I want the map of Disneyland to pan/zoom to the yellow square when you click on it. I'm new to web dev so any pointers on how to implement this with CSS/JavaScript/jQuery would be hugely appreciated.
Edit: I replaced my example with something closer to the actual app to avoid confusion.
Codepen: https://codepen.io/dan-freeman/pen/mdVWYox
HTML
<img src="https://i.redd.it/64xwakxpbae21.jpg">
<div class="pin">Click me!</div>-
CSS
img {
width: 800px;
height: auto;
}
.pin {
position: absolute;
height: 75px;
width: 75px;
top: 300px; /*Solution should use these coordinates*/
left: 550px;
background-color: yellow;
}
I created an example for your case. This literally solves your problem. You can give the scale size what you want in .zoom
class. I gave it 1.5.
const pins = document.querySelectorAll(".pin");
const figure = document.querySelector(".figure");
const mapImage = document.querySelector("#mapImage");
pins.forEach(p => {
p.addEventListener("click", e => {
figure.style.transformOrigin = `${e.target.getBoundingClientRect().left - e.target.getBoundingClientRect().width / 2}px ${e.target.getBoundingClientRect().top - e.target.getBoundingClientRect().height / 2}px`;
if (figure.classList.contains("zoom")) {
figure.style.transition = "transform-origin 0.3s, transform 0.3s";
} else {
figure.style.transition = "transform 0.3s";
}
figure.classList.add("zoom");
});
});
document.addEventListener("click", (e) => {
pins.forEach((p) => {
let isClickInside = p.contains(event.target);
if (!isClickInside &&
!event.target.classList.contains("pin")
) {
figure.style.transition = "transform-origin 0.3s, transform 0.3s";
figure.style.transformOrigin = '50% 50%';
figure.classList.remove("zoom");
}
});
});
.container {
width: 800px;
overflow: hidden;
}
figure {
width: 100%;
position: relative;
transform-origin: 50% 50%;
}
figure img {
width: 100%;
}
.pin {
position: absolute;
height: 75px;
width: 75px;
background-color: yellow;
transition: 0.3s;
transform-origin: 50% 50%;
}
.pin1 {
top: 300px;
left: 550px;
}
.pin2 {
top: 100px;
left: 250px;
}
.zoom {
transform: scale(1.5);
}
<div class="container">
<figure class="figure">
<img id="mapImage" src="https://i.redd.it/64xwakxpbae21.jpg">
<div class="pin pin1">Click me!</div>
<div class="pin pin2">Another Pin</div>
</figure>
</div>
Another one:
const pins = document.querySelectorAll(".pin");
const mapImage = document.querySelector("#mapImage");
pins.forEach(p => {
p.addEventListener("click", e => {
pins.forEach(pin => {
pin.classList.remove("pinZoom");
});
mapImage.style.transformOrigin = `${e.target.getBoundingClientRect().left - e.target.getBoundingClientRect().width / 2}px ${e.target.getBoundingClientRect().top - e.target.getBoundingClientRect().height / 2}px`;
if (mapImage.classList.contains("zoom")) {
mapImage.style.transition = "transform-origin 0.3s, transform 0.3s";
} else {
mapImage.style.transition = "transform 0.3s";
}
mapImage.classList.add("zoom");
p.classList.add("pinZoom");
});
});
document.addEventListener("click", (e) => {
pins.forEach((p) => {
let isClickInside = p.contains(event.target);
if (!isClickInside &&
!event.target.classList.contains("pin")
) {
mapImage.style.transformOrigin = '50% 50%';
mapImage.classList.remove("zoom");
p.classList.remove("pinZoom");
}
});
});
figure{
position: relative;
width: 800px;
height: auto;
overflow: hidden;
}
figure img {
width: 100%;
transform-origin: 50% 50%;
}
.pin {
position: absolute;
height: 75px;
width: 75px;
background-color: yellow;
transition: 0.3s;
transform-origin: 50% 50%;
}
.pin1 {
top: 300px;
left: 550px;
}
.pin2 {
top: 100px;
left: 250px;
}
.zoom {
transform: scale(1.5);
}
.pinZoom {
transform: scale(1.3);
}
<figure>
<img id="mapImage" src="https://i.redd.it/64xwakxpbae21.jpg">
</figure>
<div class="pin pin1">Click me!</div>
<div class="pin pin2">Another Pin</div>
I created another example also with js-image-zoom library and no click needed. You can set scale, zoom position, offset, zoom width and zoom style. See documentation.
var options = {
width: 800,
zoomWidth: 800,
/*
offset: {
vertical: 0,
horizontal: 10
},
scale: 2.0,
*/
zoomPosition: 'original', /* right, top, bottom, left */
};
new ImageZoom(document.getElementById("img-container"), options);
.pin {
position: absolute;
height: 75px;
width: 75px;
top: 300px;
left: 550px;
background-color: yellow;
}
#img-container {
position: relative;
}
<div id="img-container" style="width: 400px">
<img src="https://i.redd.it/64xwakxpbae21.jpg" />
<div>
<script src="https://unpkg.com/js-image-zoom@0.7.0/js-image-zoom.js"></script>