当前位置:主页 > 网页前端 > JavaScript代码 >

使用JavaScript实现一个拖拽缩放效果

时间:2023-03-21 09:47:41 | 栏目:JavaScript代码 | 点击:

前言

在写一个简单的H5页面时,需要实现如下的一个拖拽效果,找了半天未能找到符合要求的,含泪手写
先来看一下我们要是实现一个怎样的效果

基本思路

拖拽实现

我们常见的改变元素位置的方式有

那我们现在用那种方式那实现拖拽呢?
从功能实现上来看,这两个方式都能很好的实现我们的需求
从性能上来看,translate天生就是用来制作动画效果的,所以translate的性能以及流畅度都是要优于定位的。
开始操作!!

<style>
  .box{
    margin: 50px;
    width: 500px;
    height: 300px;
    border: 1px solid black;
    position: relative;
  }
  .drag{
    height: 100px;
    width: 100px;
    background-color: #cbd;
  }
</style>

<div class="box">
  <div class="drag"></div>
</div>

<script>
  let dragEl = document.querySelector(".drag")
  let container = document.querySelector(".box")
  let width, height, maxWidth, maxHeight, tx, ty, startX, startY
  // 初始化
  function init() {
    // 为目标元素设置初始的偏移,避免在第一次获取偏移时为空的问题
    dragEl.style.transform = "translate(0px,0px)"
    // 获取父元素宽高
    maxWidth = container.clientWidth
    maxHeight = container.clientHeight
  }
  function getInfo(e) {
      // 获取元素当前的宽高
      width = dragEl.clientWidth
      height = dragEl.clientHeight
      // 获取元素当前的偏移量
      let translateStr = dragEl.style.transform
      const reg = /\d+/g
      let translateArr = translateStr.match(reg)
      tx = Number(translateArr[0])
      ty = Number(translateArr[1])
      // 记录鼠标的起始位置
      startX = e.clientX
      startY = e.clientY
    }
  function  drag() {
    dragEl.addEventListener("mousedown", (e) => {
      getInfo(e)
      document.onmousemove = (e) => {
        let distanceX = tx + e.clientX - startX
        let distanceY = ty + e.clientY - startY
        dragEl.style.transform = `translate(${distanceX}px, ${distanceY}px)`
      }
      document.onmouseup = () => {
        document.onmousemove = null
      }
    })
  }
  init()
  drag()
</script>

通过上述代码,我们已经完成了元素的拖动,接下来需要考虑的就是,如果有边界限制,我们又该如何实现
从上诉例子中,我们可以观察出,元素偏移的最小值为0,最大值为父元素的宽高 - 目标元素的宽高
所以在有边界限制的情形下偏移量的计算方式为

let distanceX = Math.max(0, Math.min(tx + e.clientX - startX, maxWidth - width))
let distanceY = Math.max(0, Math.min(ty + e.clientY - startY, maxHeight - height))

缩放实现

这里我们以向左缩放为例

<style>
  .box{
    margin: 50px;
    width: 500px;
    height: 300px;
    border: 1px solid black;
    position: relative;
  }
  .drag{
    height: 100px;
    width: 100px;
    background-color: #cbd;
  }
  .left{
    width: 10px;
    height: calc(100% - 14px);
    margin: 7px 0px;
    position: absolute;
    background-color: #000;
    cursor: col-resize;
    top: 0;
    left: -5px;
  }
</style>
<script>
function addLeft() {
  left = document.createElement("div")
  left.className = "left"
  dragEl.append(left)
}
init()
drag()
addLeft()
</script>

2.为左侧的边框添加缩放功能,因为是左侧的缩放,所以在宽度变化的同时,需要不断调整元素的位置,令其符合视觉效果

function leftZoom() {
  left.addEventListener("mousedown", (e) => {
    e.stopPropagation()
    getInfo(e)
    document.onmousemove = (e) => {
      // 注意这里是?
      newWidth = width - (e.clientX - startX)
      let distanceX = tx + (e.clientX - startX)
      dragEl.style.width = `${newWidth}px`
      dragEl.style.transform = `translate(${distanceX}px, ${ty}px)`
    }
    document.onmouseup = () => {
      document.onmousemove = null
    }
  })
}
init()
drag()
addLeft()
leftZoom()
let minWidth = 30
newWidth = Math.max(minWidth, width - (e.clientX - startX))
// 最大偏移为已经偏移的距离 + 目标元素的宽度 - 最小宽度
let distanceX = Math.min(tx + width - minWidth, tx + (e.clientX - startX))

4.如果缩放的尺寸需要限制在父元素内,我们需要继续完善代码

// 最大宽度为元素当前偏移量 + 最初的宽度,最小宽度为minWidth
newWidth = Math.min(tx + width, Math.max(minWidth, width - (e.clientX - startX)))
// 最大偏移为已经偏移的距离 + 目标元素的宽度 - 最小宽度,最小偏移为0
let distanceX = Math.max(0,Math.min(tx + width - minWidth, tx + (e.clientX - startX)))

其他是三边以及四个角的实现方式基本相同,就不在这里一一赘述了

最后

虽然我们完成了元素的拖拽与缩放,但是我们在使用时,还是存在许多的限制,比如

虽然存在限制,但是我们可以根据自己的实际需求进行调整

您可能感兴趣的文章:

相关文章