效果:
拖拽和缩放(缩放以鼠标为中心)
代码具体实现如下:
但是有几个注意点
(1)为什么需要设置
transform-origin: 0 0;
缩放时以鼠标为中心进行缩放。这意味着需要手动计算缩放过程中元素的位移,以确保缩放是以鼠标为中心的。如果不设置
transform-origin
,缩放和位移的计算将变得更加复杂。
设置
transform-origin: 0 0;
后,所有的位移和缩放都是基于左上角进行的,这使得计算变换的位移量更加直观和简单。只需要考虑从左上角开始的平移和缩放,而不需要考虑元素的中心点。
如果不设置
transform-origin: 0 0;
,在缩放和位移时需要考虑变换原点的位置,这会增加计算的复杂性。
(2)关于代码中的
(scale / prevScale - 1)
在缩放过程中需要计算新的平移值,使得缩放以鼠标为中心。
(scale / prevScale - 1)
计算出相对于原始缩放比例的变化量。
例如,如果 scale 增加了10%,那么 scale / prevScale 会是1.1,减去1后得到0.1,表示增加的10%。
offsetX * (scale / prevScale - 1)
计算出由于缩放而导致的水平偏移量。类似地,
offsetY * (scale / prevScale - 1)
计算出由于缩放而导致的垂直偏移量。
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metaname="viewport"content="width=device-width, initial-scale=1.0"/><title>移动和缩放容器</title><style>body{margin: 0;height: 100vh;display: flex;justify-content: center;align-items: center;background-color: #f0f0f0;overflow: hidden;}#container{width: 200px;height: 200px;background-color: #4caf50;cursor: grab;user-select: none;transform-origin: 0 0;/* 设置原点为左上角 */}</style></head><body><divid="container">ABC</div><script>const container = document.getElementById("container");let isDragging =false;let startX, startY, initialX, initialY;let scale =1;let translateX =0,
translateY =0;
container.addEventListener("mousedown",(e)=>{
isDragging =true;
startX = e.clientX;
startY = e.clientY;
initialX = translateX;
initialY = translateY;
container.style.cursor ="grabbing";});
document.addEventListener("mousemove",(e)=>{if(isDragging){const dx = e.clientX - startX;const dy = e.clientY - startY;
translateX = initialX + dx;
translateY = initialY + dy;
container.style.transform =`translate(${translateX}px, ${translateY}px) scale(${scale})`;}});
document.addEventListener("mouseup",()=>{
isDragging =false;
container.style.cursor ="grab";});
container.addEventListener("wheel",(e)=>{
e.preventDefault();const minScale =0.5;const maxScale =3;const rect = container.getBoundingClientRect();const offsetX = e.clientX - rect.left;const offsetY = e.clientY - rect.top;const prevScale = scale;const delta = e.deltaY || e.detail || e.wheelDelta;// console.log(delta, "delta");
scale += delta *-0.01;
scale = Math.min(Math.max(minScale, scale), maxScale);const newX = offsetX *(scale / prevScale -1);const newY = offsetY *(scale / prevScale -1);
console.log(newX);
translateX -= newX;
translateY -= newY;
container.style.transform =`translate(${translateX}px, ${translateY}px) scale(${scale})`;});</script></body></html>
版权归原作者 Lsx~ 所有, 如有侵权,请联系我们删除。