亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

使用JavaScript實(shí)現(xiàn)一個(gè)拖拽縮放效果

 更新時(shí)間:2022年05月24日 15:47:11   作者:mayoha  
這篇文章主要介紹了如何使用JS實(shí)現(xiàn)一個(gè)這樣的拖拽縮放效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

前言

在寫一個(gè)簡單的H5頁面時(shí),需要實(shí)現(xiàn)如下的一個(gè)拖拽效果,找了半天未能找到符合要求的,含淚手寫
先來看一下我們要是實(shí)現(xiàn)一個(gè)怎樣的效果

基本思路

  • 鼠標(biāo)摁下,記錄元素的初始位置以及寬高
  • 監(jiān)聽鼠標(biāo)的移動(dòng),根據(jù)鼠標(biāo)的移動(dòng)不斷改變自己的位置/寬高
  • 是否存在邊界限制

拖拽實(shí)現(xiàn)

我們常見的改變元素位置的方式有

  • 定位
  • 使用translate進(jìn)行偏移

那我們現(xiàn)在用那種方式那實(shí)現(xiàn)拖拽呢?
從功能實(shí)現(xiàn)上來看,這兩個(gè)方式都能很好的實(shí)現(xiàn)我們的需求
從性能上來看,translate天生就是用來制作動(dòng)畫效果的,所以translate的性能以及流暢度都是要優(yōu)于定位的。
開始操作!!

<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() {
    // 為目標(biāo)元素設(shè)置初始的偏移,避免在第一次獲取偏移時(shí)為空的問題
    dragEl.style.transform = "translate(0px,0px)"
    // 獲取父元素寬高
    maxWidth = container.clientWidth
    maxHeight = container.clientHeight
  }
  function getInfo(e) {
      // 獲取元素當(dāng)前的寬高
      width = dragEl.clientWidth
      height = dragEl.clientHeight
      // 獲取元素當(dāng)前的偏移量
      let translateStr = dragEl.style.transform
      const reg = /\d+/g
      let translateArr = translateStr.match(reg)
      tx = Number(translateArr[0])
      ty = Number(translateArr[1])
      // 記錄鼠標(biāo)的起始位置
      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>

通過上述代碼,我們已經(jīng)完成了元素的拖動(dòng),接下來需要考慮的就是,如果有邊界限制,我們又該如何實(shí)現(xiàn)
從上訴例子中,我們可以觀察出,元素偏移的最小值為0,最大值為父元素的寬高 - 目標(biāo)元素的寬高
所以在有邊界限制的情形下偏移量的計(jì)算方式為

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

縮放實(shí)現(xiàn)

這里我們以向左縮放為例

  • 首先我們需要為目標(biāo)元素添加一個(gè)邊框,用來進(jìn)行縮放的操作
<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.為左側(cè)的邊框添加縮放功能,因?yàn)槭亲髠?cè)的縮放,所以在寬度變化的同時(shí),需要不斷調(diào)整元素的位置,令其符合視覺效果

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))
  • 現(xiàn)在我們已經(jīng)完成了縮放,但是當(dāng)元素向右縮小到最小值時(shí),元素會(huì)向右移動(dòng),顯然這是不符合邏輯的,所以我們需要對偏移進(jìn)行限制
// 最大偏移為已經(jīng)偏移的距離 + 目標(biāo)元素的寬度 - 最小寬度
let distanceX = Math.min(tx + width - minWidth, tx + (e.clientX - startX))

4.如果縮放的尺寸需要限制在父元素內(nèi),我們需要繼續(xù)完善代碼

// 最大寬度為元素當(dāng)前偏移量 + 最初的寬度,最小寬度為minWidth
newWidth = Math.min(tx + width, Math.max(minWidth, width - (e.clientX - startX)))
// 最大偏移為已經(jīng)偏移的距離 + 目標(biāo)元素的寬度 - 最小寬度,最小偏移為0
let distanceX = Math.max(0,Math.min(tx + width - minWidth, tx + (e.clientX - startX)))

其他是三邊以及四個(gè)角的實(shí)現(xiàn)方式基本相同,就不在這里一一贅述了

最后

雖然我們完成了元素的拖拽與縮放,但是我們在使用時(shí),還是存在許多的限制,比如

  • 目標(biāo)元素不能被定位,如果使用定位對元素進(jìn)行了偏移,我們所做的限制就會(huì)不生效
  • 同理目標(biāo)元素也不能存在邊距

雖然存在限制,但是我們可以根據(jù)自己的實(shí)際需求進(jìn)行調(diào)整

到此這篇關(guān)于如何使用JS實(shí)現(xiàn)一個(gè)這樣的拖拽縮放效果的文章就介紹到這了,更多相關(guān)js拖拽縮放內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論