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

效果:

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

代码具体实现如下:

但是有几个注意点

(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) 计算出由于缩放而导致的垂直偏移量。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="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>
    <div id="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>
  • 25
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在vue前端html页面中添加鼠标悬停位置按住ctrl 滚轮大并的功能,可以通过以下步骤实现: 1. 给页面需要的区域添加一个唯一的ID,例如:`<div id="zoomable">...</div>`。 2. 在Vue的mounted()方法中,使用jQuery或原生JavaScript获取该区域的DOM节点,并添加鼠标事件监听器。 3. 监听鼠标滚轮事件,在滚轮事件触发时,检查是否同时按下了Ctrl键,如果是,则执行操作。 4. 监听鼠标按下和移动事件,在按下事件触发时,检查是否同时按下了Ctrl键,如果是,则执行操作,移动事件中更新位置。 下面是一个简单的代码示例,实现在Vue前端html页面中添加鼠标悬停位置按住ctrl 滚轮大并的功能: ``` <template> <div id="zoomable" @wheel.prevent="onMouseWheel" @mousedown="onMouseDown" @mousemove="onMouseMove" @mouseup="onMouseUp"> <!-- 可的内容区域 --> </div> </template> <script> import $ from 'jquery' export default { mounted () { const zoomable = document.getElementById('zoomable') let isDragging = false let dragStartX, dragStartY, offsetX = 0, offsetY = 0 let zoomLevel = 1 $(zoomable).on('wheel', event => { if (event.ctrlKey) { event.preventDefault() zoomLevel += event.originalEvent.deltaY > 0 ? -0.1 : 0.1 zoomable.style.transform = `scale(${zoomLevel}) translate(${offsetX}px, ${offsetY}px)` } }) $(zoomable).on('mousedown', event => { if (event.ctrlKey) { isDragging = true dragStartX = event.clientX dragStartY = event.clientY } }) $(zoomable).on('mousemove', event => { if (isDragging) { offsetX += event.clientX - dragStartX offsetY += event.clientY - dragStartY dragStartX = event.clientX dragStartY = event.clientY zoomable.style.transform = `scale(${zoomLevel}) translate(${offsetX}px, ${offsetY}px)` } }) $(zoomable).on('mouseup', event => { isDragging = false }) }, methods: { onMouseWheel (event) { // do nothing, handled by jQuery }, onMouseDown (event) { // do nothing, handled by jQuery }, onMouseMove (event) { // do nothing, handled by jQuery }, onMouseUp (event) { // do nothing, handled by jQuery } } } </script> ``` 在上述代码示例中,我们使用jQuery来监听鼠标事件,实现了功能。其中,通过`event.ctrlKey`属性来检查是否同时按下了Ctrl键。在操作中,我们使用`transform`属性来设置和偏移量。在操作中,我们使用`offsetX`和`offsetY`变量来记录的偏移量,并在移动事件中更新位置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值