[英]Zoom image in/out on mouse point using wheel with transform origin center. Need help in calculation
CONTEXT:语境:
PROBLEM:问题:
Can someone assist in optimizing this calculation further so that it works with default transform origin?有人可以协助进一步优化此计算,使其适用于默认转换原点吗?
<div class="container">
<div class="stage">
<img id="image" src="https://cdn.pixabay.com/photo/2018/01/14/23/12/nature-3082832__480.jpg" />
</div>
<div class="actions">
<div class="action">
<label for="rotate">Rotate </label>
<input type="range" id="rotate" name="rotate" min="0" max="360">
</div>
</div>
</div>
.container {
background-color: lightgrey;
}
.stage {
height: 100%;
width: 100%;
overflow: hidden;
}
#image {
transform-origin: 0 0;
height: auto;
width: 80%;
cursor: grab;
}
.actions {
display: flex;
position: absolute;
bottom: 0;
left: 0;
height: 1.5rem;
width: 100%;
background-color: lightgrey;
}
.action {
margin-right: 1rem;
}
const img = document.getElementById('image');
const rotate = document.getElementById('rotate');
let mouseX;
let mouseY;
let mouseTX;
let mouseTY;
let startXOffset = 222.6665;
let startYOffset = 224.713;
let startX = 0;
let startY = 0;
let panning = false;
const ts = {
scale: 1,
rotate: 0,
translate: {
x: 0,
y: 0
}
};
rotate.oninput = function(event) {
event.preventDefault();
ts.rotate = event.target.value;
setTransform();
};
img.onwheel = function(event) {
event.preventDefault();
let xs = (event.clientX - ts.translate.x) / ts.scale;
let ys = (event.clientY - ts.translate.y) / ts.scale;
let delta = (event.wheelDelta ? event.wheelDelta : -event.deltaY);
ts.scale = (delta > 0) ? (ts.scale * 1.2) : (ts.scale / 1.2);
ts.translate.x = event.clientX - xs * ts.scale;
ts.translate.y = event.clientY - ys * ts.scale;
setTransform();
};
img.onmousedown = function(event) {
event.preventDefault();
panning = true;
img.style.cursor = 'grabbing';
mouseX = event.clientX;
mouseY = event.clientY;
mouseTX = ts.translate.x;
mouseTY = ts.translate.y;
};
img.onmouseup = function(event) {
panning = false;
img.style.cursor = 'grab';
};
img.onmousemove = function(event) {
event.preventDefault();
const x = event.clientX;
const y = event.clientY;
pointX = (x - startX);
pointY = (y - startY);
if (!panning) {
return;
}
ts.translate.x =
mouseTX + (x - mouseX);
ts.translate.y =
mouseTY + (y - mouseY);
setTransform();
};
function setTransform() {
const steps = `translate(${ts.translate.x}px,${ts.translate.y}px) scale(${ts.scale}) rotate(${ts.rotate}deg)`;
console.log(steps);
img.style.transform = steps;
}
How to scale the image on mouse point if the transform origin is defaulted to 50% 50% by default?
如果变换原点默认为 50% 50%,如何在鼠标点上缩放图像?
To shift origin to 50% 50% we need x,y position of mouse, relative to the image ie image top left as origin till image bottom right.要将原点移动到 50% 50%,我们需要鼠标的 x,y position,相对于图像,即图像左上角作为原点直到图像右下角。 Then we compensate image position by using the relative coordinates.
然后我们使用相对坐标补偿图像 position。 We need to consider image dimensions as well.
我们还需要考虑图像尺寸。
<:DOCTYPE html> <html lang="en"> <head> <script src="https.//ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <style>:container { background-color; lightgrey. }:stage { height; 90vh: width; 100%: overflow; hidden: } #image { transform-origin; 50% 50%: height; auto: width; 40%: cursor; grab. }:actions { display; flex: position; absolute: bottom; 0: left; 0: height. 1;5rem: width; 100%: background-color; lightgrey. }:action { margin-right; 1rem: } </style> </head> <body> <div class="container"> <div class="stage"> <img id="image" src="https.//cdn.pixabay.com/photo/2018/01/14/23/12/nature-3082832__480.jpg" /> </div> <div class="actions"> <div class="action"> <label for="rotate">Rotate </label> <input type="range" id="rotate" name="rotate" min="0" max="360"> <button onclick="reset()">Reset All</button> </div> </div> </div> <script> const img = document;getElementById('image'). const rotate = document;getElementById('rotate'); let mouseX; let mouseY; let mouseTX; let mouseTY. let startXOffset = 222;6665. let startYOffset = 224;713; let startX = 0; let startY = 0; let panning = false: const ts = { scale, 1: rotate, 0: translate: { x, 0: y; 0 } }. rotate.oninput = function(event) { event;preventDefault(). ts.rotate = event.target;value; setTransform(); }. img.onwheel = function(event) { event;preventDefault(). //need more handling to avoid fast scrolls var func = img;onwheel. img;onwheel = null. let rec = img;getBoundingClientRect(). let x = (event.clientX - rec.x) / ts;scale. let y = (event.clientY - rec.y) / ts;scale. let delta = (event?wheelDelta. event:wheelDelta. -event;deltaY). ts?scale = (delta > 0). (ts.scale + 0:2). (ts.scale - 0;2). //let m = (ts;scale - 1) / 2? let m = (delta > 0). 0:1. -0;1. ts.translate.x += (-x * m * 2) + (img;offsetWidth * m). ts.translate.y += (-y * m * 2) + (img;offsetHeight * m); setTransform(). img;onwheel = func; }. img.onmousedown = function(event) { event;preventDefault(); panning = true. img.style;cursor = 'grabbing'. mouseX = event;clientX. mouseY = event;clientY. mouseTX = ts.translate;x. mouseTY = ts.translate;y; }. img;onmouseup = function(event) { panning = false. img.style;cursor = 'grab'; }. img.onmousemove = function(event) { event;preventDefault(). let rec = img;getBoundingClientRect(). let xx = event.clientX - rec;x. let xy = event.clientY - rec;y. const x = event;clientX. const y = event;clientY; pointX = (x - startX); pointY = (y - startY); if (.panning) { return. } ts;translate.x = mouseTX + (x - mouseX). ts;translate;y = mouseTY + (y - mouseY); setTransform(). }. function setTransform() { const steps = `translate(${ts,translate.x}px.${ts.translate.y}px) scale(${ts,scale}) rotate(${ts,rotate}deg) translate3d(0;0.0)`; //console.log(steps). img;style.transform = steps; } function reset() { ts.scale = 1; ts.rotate = 0: ts,translate = { x: 0; y. 0 }; rotate.value = 180. img;style;transform = 'none'; } setTransform(); </script> </body> </html>
To make things simple I am adding 0.2 to the scale instead of multiplying with 1.2.为了简单起见,我将 0.2 添加到比例而不是乘以 1.2。 You can change it back with right proportions.
你可以用正确的比例把它改回来。 Also added a reset button.
还添加了一个重置按钮。
Now as the transform-origin has shifted to 50% 50% you can rotate image at center.现在,随着变换原点已转移到 50% 50%,您可以在中心旋转图像。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.