前端的拖拽和缩放(缩放以鼠标为中心)

Lsx~ 2024-08-02 15:03:02 阅读 56

效果:

拖拽和缩放(缩放以鼠标为中心)

代码具体实现如下:

但是有几个注意点

(1)为什么需要设置 <code>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) 计算出由于缩放而导致的垂直偏移量。

<!DOCTYPE html>

<html lang="en">code>

<head>

<meta charset="UTF-8" />code>

<meta name="viewport" content="width=device-width, initial-scale=1.0" />code>

<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>

<div id="container">ABC</div>code>

<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>



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。