前端的拖拽和缩放(缩放以鼠标为中心)
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>
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。