拖动和缩放的效果怎么做?

作者站长头像
站长
· 阅读数 6

有两个div

<div class="one" style="width:300px;height:300px;">
  <div class="two" style="width:1000px;height:500px;"></div>
</div>

想要实现.two在.one这个div里面通过滚轮缩放和鼠标拖动效果,并且拖动过程中不能完全拖离.one这个的区域,至少保留20px还在区域内(不管上下左右拖动都一样)意思大概跟下面这张图一样拖动和缩放的效果怎么做?而且.two初始的宽高大于.one,在打开这个页面的时候要把.two缩放到.one可显示全的大小,不知道这个效果该怎么做,搞了好久搞不出来,现在做了一部分,代码如下:

<template>
  <div class='layoutView' ref="canvasRef">
    <div ref="divRef" class="draggable"></div>
  </div>
</template>
<script>
export default {
  props:[],
  data() {
    return {
      screenNum:1,//缩放倍数
    }
  },
  created(){
    
  },
  mounted(){
    // 获取canvas和div元素的引用
    const canvas = this.$refs.canvasRef;
    const div = this.$refs.divRef;
    // 调用拖动函数,传入div元素和canvas元素的引用
    this.draggable(div, canvas);

    // 调用缩放函数,传入div元素和canvas元素的引用
    this.zoomable(div, canvas);
  },
  methods:{
    //拖动
    draggable(element, canvas) {
      // 鼠标按下时的初始位置
      let initialX = 0;
      let initialY = 0;

      // 鼠标按下时,计算初始位置和设置鼠标移动事件
      element.addEventListener('mousedown', (e) => {
        initialX = e.clientX - element.offsetLeft;
        initialY = e.clientY - element.offsetTop;
        document.addEventListener('mousemove', moveElement);
      });

      // 鼠标松开时,移除鼠标移动事件
      document.addEventListener('mouseup', () => {
        document.removeEventListener('mousemove', moveElement);
      });

      // 鼠标移动时,计算元素的新位置并设置
      function moveElement(e) {
        const newX = e.clientX - initialX;
        const newY = e.clientY - initialY;

        element.style.left = newX + 'px';
        element.style.top = newY + 'px';
      }
    },
    //滚轮缩放
    zoomable(element, canvas) {
      let that = this
      element.addEventListener('wheel', function(event) {
        // 阻止默认的滚轮事件,以防止整个页面滚动
        event.preventDefault();
        
        // 获取鼠标滚轮的变化值
        var delta = event.deltaY || event.detail || event.wheelDelta;

        // 获取鼠标相对于div元素的位置
        var mouseX = event.clientX - element.offsetLeft;
        var mouseY = event.clientY - element.offsetTop;

        // 根据鼠标位置以及滚轮变化值进行放大缩小操作
        if (delta < 0) {
          that.screenNum+=0.1
          // 放大div元素
          element.style.transform = `scale(${that.screenNum})`;
        } else {
          //不能无限缩小
          if(that.screenNum <=0.4) return
          that.screenNum-=0.1
          // 缩小div元素
          element.style.transform = `scale(${that.screenNum})`;
        }
        // 获取canvas的宽度和高度
        // const canvasWidth = canvas.width;
        // const canvasHeight = canvas.height;
        // // 获取div元素的宽度和高度
        // const divWidth = element.offsetWidth;
        // const divHeight = element.offsetHeight;
        // // 计算div元素放大后的宽度和高度
        // const scaledDivWidth = divWidth * that.screenNum;
        // const scaledDivHeight = divHeight * that.screenNum;
        // // 计算div元素在canvas中心的位置
        // const x = (canvasWidth - scaledDivWidth) / 2;
        // const y = (canvasHeight - scaledDivHeight) / 2;
        // // 设置div元素在canvas中心的位置
        // element.style.left = `${x}px`;
        // element.style.top = `${y}px`;
      });
    },
  }
}
</script>
<style lang='scss'>
.layoutView{
  position:relative;
  overflow: hidden;
  width:500px;
  height: 500px;
  border: 1px solid #000;
  .draggable {
    cursor: move;
    z-index: 1;
    position: absolute;
    background-color: red;
    width: 1024px;
    height: 768px;
  }
}
</style>
回复
1个回答
avatar
test
2024-06-28

这种吗?answer image

<!DOCTYPE html>
<html>

<head>
  <style>
    .one {
      width: 300px;
      height: 300px;
      overflow: hidden;
      position: relative;
      background-color: aquamarine;
    }

    .two {
      width: 1000px;
      height: 500px;
      position: absolute;
      cursor: grab;
      background: #000;
    }
  </style>
</head>

<body>

  <div class="one" id="container">
    <div class="two" id="content"></div>
  </div>

  <script>
    var container = document.getElementById('container');
    var content = document.getElementById('content');

    var initialWidth = 1000;
    var initialHeight = 500;

    var minLeft = 20;
    var minTop = 20;

    content.style.width = initialWidth + 'px';
    content.style.height = initialHeight + 'px';

    var isDragging = false;
    var lastX = 0;
    var lastY = 0;

    content.addEventListener('mousedown', function (e) {
      isDragging = true;
      lastX = e.clientX;
      lastY = e.clientY;
      content.style.cursor = 'grabbing';
      e.preventDefault();
    });

    document.addEventListener('mousemove', function (e) {
      if (!isDragging) return;

      var deltaX = e.clientX - lastX;
      var deltaY = e.clientY - lastY;

      var newLeft = content.offsetLeft + deltaX;
      var newTop = content.offsetTop + deltaY;

      newLeft = Math.max(minLeft, newLeft);
      newLeft = Math.min(container.clientWidth - minLeft, newLeft);

      newTop = Math.max(minTop, newTop);
      newTop = Math.min(container.clientHeight - minTop, newTop);

      content.style.left = newLeft + 'px';
      content.style.top = newTop + 'px';

      lastX = e.clientX;
      lastY = e.clientY;
    });

    document.addEventListener('mouseup', function () {
      isDragging = false;
      content.style.cursor = 'grab';
    });

    container.addEventListener('wheel', function (e) {
      var scaleFactor = 1.2;
      var newWidth = content.clientWidth * (e.deltaY > 0 ? 1 / scaleFactor : scaleFactor);
      var newHeight = content.clientHeight * (e.deltaY > 0 ? 1 / scaleFactor : scaleFactor);

      newWidth = Math.min(container.clientWidth, newWidth);
      newHeight = Math.min(container.clientHeight, newHeight);

      content.style.width = newWidth + 'px';
      content.style.height = newHeight + 'px';

      e.preventDefault();
    });
  </script>

</body>

</html>
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容