I am trying to build an application where you can zoom a bit with the mouse wheel into one point, and then later zoom further in at another point.
In other words, the point of "origin" for the zooming can change along the way.
Take a look at this example: https://codesandbox.io/s/4w4m1k5zlx
var phase = 1;
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
box1.style.transformOrigin = "0 0";
box2.style.transformOrigin = "0 0";
var width = 100;
var height = 100;
function transform(originX, originY, translateX, translateY, scale) {
transformElement(1, box1, originX, originY, translateX, translateY, scale);
transformElement(2, box2, originX, originY, translateX, translateY, scale);
}
function transformElement(
method,
element,
originX,
originY,
translateX,
translateY,
scale
) {
element.style.transition = "transform 1s linear";
if (method === 1) {
element.style.transform = `translate(${originX}px, ${originY}px) translate(${translateX}px, ${translateY}px) scale(${scale}) translate(-${originX}px, -${originY}px)`;
} else if (method === 2) {
element.style.transformOrigin = `${originX}px ${originY}px`;
element.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scale})`;
}
var pointElement = document.createElement("div");
pointElement.classList.add("point");
pointElement.style.transform = `translate(${originX}px, ${originY -
2 * scale}px)`;
element.appendChild(pointElement);
}
function reset() {
resetElement(box1);
resetElement(box2);
}
function resetElement(element) {
while (element.children.length > 0) {
element.removeChild(element.children[0]);
}
element.style.transform = "";
element.style.transition = "";
void element.clientWidth;
}
function phase1() {
transform(width * 0.75, height / 2, 0, 0, 1.5);
}
function phase2() {
transform(width * 0.25, height / 2, 0, 0, 2);
}
function phase3() {
transform(width / 2, height, 0, 0, 2.5);
}
function phase4() {
transform(width / 2, 0, 0, 0, 3);
}
const phases = [reset, phase1, phase2, phase3, phase4];
setInterval(() => phases[phase++ % phases.length](), 1500);
* {
box-sizing: border-box;
}
body {
background-color: black;
}
.container {
position: relative;
margin: 60px;
background-color: lightgray;
width: 200px;
height: 200px;
}
.point {
width: 2px;
height: 2px;
background-color: white;
}
.box {
position: absolute;
top: 25%;
left: 25%;
transform-origin: 0 0;
background-color: teal;
opacity: 0.8;
width: 100px;
height: 100px;
}
.outline {
background-color: transparent;
border: 1px solid black;
}
<div class="container">
<div class="box outline">
</div>
<div id="box1" class="box"></div>
</div>
<div class="container">
<div class="box outline">
</div>
<div id="box2" class="box"></div>
</div>
Top box in the example: Here I tried simulating transform-origin
with transform
in order to be able to transition one property. However, the animation is not "even" - especially during the first scale (where it will zoom a bit in and out again - hard to explain but I hope you can see it).
Bottom box in the example: Changing both the transform-origin
and transform
at the same time, it becomes quite jumpy, because transform
has a transition and transform-origin
doesn't.
The top example is most ideal, but it still doesn't look good because of the unsmooth zooming. How can I zoom on points at different phases without making the translation either jump or zoom in and out again?
from CSS scaling from a specific point when that point may change along the way?
No comments:
Post a Comment