最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于javascript的拖拽類封裝詳解

 更新時間:2019年04月19日 10:08:30   作者:我是大哥的女朋友  
這篇文章主要介紹了基于javascript的拖拽類封裝,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

效果圖如下

github地址如下: github地址

使用方法

引入js和對應的css

import Drag from '../../static/dragger.js'
import './assets/css/dragger.css'

之后,實例化

new Drag({
  id: 'box-dragger',
  showAngle: true,
  isScale: false,
  showBorder: false
})
new Drag({
  id: 'box-dragger2',
  canZoom: false,
  canRotate: false
})
new Drag({
  id: 'img-box',
  showAngle: true,
  showPosition: true
  })
new Drag({
  id: 'test'
})

具體實現(xiàn)(封裝細節(jié))

功能細節(jié)整理:

  1. 旋轉
  2. 縮放
  3. 平移

技術難點:

  1. 旋轉時要注意盒子每一個點的位置發(fā)生了變化
  2. 針對拖拽后的盒子的left和top都有變化,計算其left和top時需將其按照中心軸旋轉擺正,再進行計算
  3. 當且僅有一個盒子是被選中的盒子,點擊哪個選中哪個。(當前頁面多個實例化Drag對象時,如何保證操作互不影響)
  4. 實現(xiàn)的兩種不同方式:

可以選中某元素,直接給該元素內部加上操作的點
有一個pannel,選中某元素時,將這個pannel定位到該元素的位置上

這兩種方式都實現(xiàn)過一次,第一種比較簡單,但是第一種,不好控制選中某個元素才讓操作點展示。

如何封裝:

考慮如何讓用戶快速上手使用,可參考的點:

  1. 用戶需要傳入什么必須的參數(shù)
  2. 暴露給用戶什么可設置的參數(shù)和方法

實現(xiàn)過程:

可配置參數(shù)

字段 說明 是否必填 默認值
id 目標元素id
container 父容器id body
canRotate 是否可以旋轉 true
canZoom 是否可以縮放 true
canPull 是否可以拉升 true
canMove 是否可以平移 true
showAngle 展示角度 false
showPosition 展示位置 false
isScale 是否等比例縮放 true
showBorder 是否展示pannel的border false

屬性

  1. canRotate
  2. canZoom
  3. canPull
  4. canMove
  5. showAngle
  6. isScale
  7. id
  8. container
  9. targetObj
  10. pannelDom 操作divdom
  11. ...

具體看圖:

代碼解說

初始化參數(shù)

初始化目標dom對象的位置:記錄其:

  1. left平距左
  2. top
  3. width
  4. height
  5. angle
  6. rightBottomPoint 目標dom對象右下坐標
  7. rightTopPoint 目標dom對象右上坐標
  8. leftTopPoint 目標dom對象左上坐標
  9. leftBottomPoint 目標dom對象左下坐標
  10. leftMiddlePoint 目標dom對象左中坐標
  11. rightMiddlePoint 目標dom對象右中坐標
  12. topMiddlePoint 目標dom對象上中坐標
  13. bottomMiddlePoint 目標dom對象下中坐標
  14. centerPos 目標dom對象中心點坐標

初始化pannel結構

當前的父容器中只有一個pannel結構,每次實例化對象時,會判斷一下如果當前這個父容器里已經(jīng)存在id為pannel的結構,就將其子節(jié)點清空,按照當前實例化對象傳進來的屬性重新渲染pannel子結構。如果沒有id為pannel的結構,就創(chuàng)建。

初始化事件

  1. 給pannelDom和targetObj綁定mousedown事件
  2. 給document綁定mousemove和mouseup事件

 

initEvent () {
  document.addEventListener('mousemove', e => {
    e.preventDefault && e.preventDefault()
    this.moveChange(e, this.targetObj)
  })
  document.addEventListener('mouseup', e => {
    this.moveLeave(this.targetObj)
  })
  if (this.canMove) {
    // 外層給this.pannelDom添加mousedown事件,是在所有實例化結束后,panneldom被展示在最后一個實例化對象上,鼠標按下它時,觸發(fā)moveInit事件
    this.pannelDom.onmousedown = e => {
      e.stopPropagation()
      this.moveInit(9, e, this.targetObj)
    }
    this.targetObj.onmousedown = e => {
      e.stopPropagation()
      this.moveInit(9, e, this.targetObj)
      this.initPannel()
      // 在點擊其他未被選中元素時,pannel定位到該元素上,重寫pannelDom事件,因為此時的this.pannelDom已經(jīng)根據(jù)新的目標元素被重寫
      this.pannelDom.onmousedown= e => {
        this.moveInit(9, e, this.targetObj)
      }
    }
  }
}

dom操作

旋轉操作

鼠標按下時,記錄當前鼠標位置距離box中心位置的y/x的反正切函數(shù)A1。 

this.mouseInit = {
  x: Math.floor(e.clientX),
  y: Math.floor(e.clientY)
}
this.preRadian = Math.atan2(this.mouseInit.y - this.centerPos.y, this.mouseInit.x - this.centerPos.x) 

鼠標移動時,記錄再次計算鼠標位置距離box中心位置的y/x的反正切函數(shù)A2。

this.rotateCurrent = {
  x: Math.floor(e.clientX),
  y: Math.floor(e.clientY)
}
this.curRadian = Math.atan2(this.rotateCurrent.y - this.centerPos.y, this.rotateCurrent.x - this.centerPos.x)

求A2-A1,求出移動的弧度

this.tranformRadian = this.curRadian - this.preRadian

求出最后box的旋轉角度,this.getRotate(target)是js中獲取某dom元素的旋轉角度的方法(粘貼過來的,親測好使)

this.angle = this.getRotate(target) + Math.round(this.tranformRadian * 180 / Math.PI)
this.preRadian = this.curRadian //鼠標移動的每一下都計算這個角度,所以每一下移動前的弧度值都上一次移動后的弧度值

計算旋轉后box每個點的坐標,根據(jù)余弦公式,傳入:旋轉前每點坐標,旋轉中心坐標和旋轉角度

let disAngle = this.angle - this.initAngle
this.rightBottomPoint = this.getRotatedPoint(this.initRightBottomPoint, this.centerPos, disAngle)
this.rightTopPoint = this.getRotatedPoint(this.initRightTopPoint, this.centerPos, disAngle)
this.leftTopPoint = this.getRotatedPoint(this.initLeftTopPoint, this.centerPos, disAngle)
this.leftBottomPoint = this.getRotatedPoint(this.initLeftBottomPoint, this.centerPos, disAngle)
this.leftMiddlePoint = this.getRotatedPoint(this.initLeftMiddlePoint, this.centerPos, disAngle)
this.rightMiddlePoint = this.getRotatedPoint(this.initRightMiddlePoint, this.centerPos, disAngle)
this.topMiddlePoint = this.getRotatedPoint(this.initTopMiddlePoint, this.centerPos, disAngle)
this.bottomMiddlePoint = this.getRotatedPoint(this.initBottomMiddlePoint, this.centerPos, disAngle)

沿著一個方向拉升操作。

沿著一個角縮放操作。 這兩個操作,主要參考了一個大佬的拖拽思想實現(xiàn)的 github wiki地址

優(yōu)化,mousemove事件添加節(jié)流函數(shù)

function throttle(fn, interval) {
  let canRun = true;
  return function () {
    if (!canRun) return;
    canRun = false;
    setTimeout(() => {
      fn.apply(this, arguments);
      canRun = true;
    }, interval);
  };
}
let that = this
document.addEventListener('mousemove', throttle(function (e) {
  e.preventDefault && e.preventDefault()
  that.moveChange(e, that.targetObj)
}, 10))

以上所述是小編給大家介紹的基于javascript的拖拽類封裝詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關文章

  • VUE多層路由嵌套實現(xiàn)代碼

    VUE多層路由嵌套實現(xiàn)代碼

    這篇文章主要為大家詳細介紹了VUE多層路由嵌套的實現(xiàn)代碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Vue項目中最新用到的一些實用小技巧

    Vue項目中最新用到的一些實用小技巧

    這篇文章主要給大家介紹了關于Vue項目中最新用到的一些實用小技巧,文中通過示例代碼介紹的非常詳細,對大家學習或者使用vue具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-11-11
  • 解決vue+ element ui 表單驗證有值但驗證失敗問題

    解決vue+ element ui 表單驗證有值但驗證失敗問題

    這篇文章主要介紹了vue+ element ui 表單驗證有值但驗證失敗,本文通過實例代碼給大家分享解決方案,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-01-01
  • 基于Vue3+TypeScript實現(xiàn)圖片預覽組件

    基于Vue3+TypeScript實現(xiàn)圖片預覽組件

    在現(xiàn)代的 Web 應用中,圖片預覽是一個常見的需求,本文將介紹如何使用 Vue3 和 TypeScript 開發(fā)一個圖片預覽組件,支持展示單張或多張圖片,并提供了豐富的配置選項,需要的朋友可以參考下
    2024-04-04
  • vue3中$attrs的變化與inheritAttrs的使用詳解

    vue3中$attrs的變化與inheritAttrs的使用詳解

    $attrs現(xiàn)在包括class和style屬性。?也就是說在vue3中$listeners不存在了,vue2中$listeners是單獨存在的,在vue3?$attrs包括class和style屬性,?vue2中?$attrs?不包含class和style屬性,這篇文章主要介紹了vue3中$attrs的變化與inheritAttrs的使用?,需要的朋友可以參考下
    2022-10-10
  • vue實現(xiàn)桌面向網(wǎng)頁拖動文件的示例代碼(可顯示圖片/音頻/視頻)

    vue實現(xiàn)桌面向網(wǎng)頁拖動文件的示例代碼(可顯示圖片/音頻/視頻)

    這篇文章主要介紹了vue實現(xiàn)桌面向網(wǎng)頁拖動文件的示例代碼(可顯示圖片/音頻/視頻),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • vue?+?element-plus自定義表單驗證(修改密碼業(yè)務)的示例

    vue?+?element-plus自定義表單驗證(修改密碼業(yè)務)的示例

    這篇文章主要介紹了vue?+?element-plus自定義表單驗證(修改密碼業(yè)務),本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友一起看看吧
    2025-04-04
  • vue中實現(xiàn)多頁面應用方式

    vue中實現(xiàn)多頁面應用方式

    這篇文章主要介紹了vue中實現(xiàn)多頁面應用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Nuxt如何實現(xiàn)將服務測數(shù)據(jù)存儲到Vuex中

    Nuxt如何實現(xiàn)將服務測數(shù)據(jù)存儲到Vuex中

    這篇文章主要介紹了Nuxt如何實現(xiàn)將服務測數(shù)據(jù)存儲到Vuex中的方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • vue-resource請求實現(xiàn)http登錄攔截或者路由攔截的方法

    vue-resource請求實現(xiàn)http登錄攔截或者路由攔截的方法

    這篇文章主要介紹了vue-resource請求實現(xiàn)http登錄攔截或者路由攔截的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07

最新評論

婺源县| 共和县| 深圳市| 炎陵县| 太湖县| 彩票| 偃师市| 灵丘县| 沅陵县| 麻城市| 雷州市| 贵阳市| 晴隆县| 建始县| 枣庄市| 新昌县| 山东省| 建平县| 彰化县| 长宁区| 尚义县| 三穗县| 保靖县| 大同县| 疏勒县| 城市| 额敏县| 夏邑县| 湖南省| 深泽县| 双牌县| 青神县| 鸡泽县| 惠水县| 家居| 民权县| 临西县| 盱眙县| 鄂伦春自治旗| 岳西县| 监利县|