這篇文章將為大家詳細講解有關(guān)javascript中怎么封裝一個拖拽類,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。
成都創(chuàng)新互聯(lián)長期為近1000家客戶提供的網(wǎng)站建設(shè)服務(wù),團隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為港南企業(yè)提供專業(yè)的網(wǎng)站設(shè)計制作、成都做網(wǎng)站,港南網(wǎng)站改版等技術(shù)服務(wù)。擁有十余年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
引入js和對應(yīng)的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é)整理:
旋轉(zhuǎn)
縮放
平移
技術(shù)難點:
旋轉(zhuǎn)時要注意盒子每一個點的位置發(fā)生了變化
針對拖拽后的盒子的left和top都有變化,計算其left和top時需將其按照中心軸旋轉(zhuǎn)擺正,再進行計算
當(dāng)且僅有一個盒子是被選中的盒子,點擊哪個選中哪個。(當(dāng)前頁面多個實例化Drag對象時,如何保證操作互不影響)
實現(xiàn)的兩種不同方式:
可以選中某元素,直接給該元素內(nèi)部加上操作的點
有一個pannel,選中某元素時,將這個pannel定位到該元素的位置上
這兩種方式都實現(xiàn)過一次,第一種比較簡單,但是第一種,不好控制選中某個元素才讓操作點展示。
如何封裝:
考慮如何讓用戶快速上手使用,可參考的點:
用戶需要傳入什么必須的參數(shù)
暴露給用戶什么可設(shè)置的參數(shù)和方法
實現(xiàn)過程:
可配置參數(shù)
字段 | 說明 | 是否必填 | 默認值 |
---|---|---|---|
id | 目標(biāo)元素id | 是 | 無 |
container | 父容器id | 否 | body |
canRotate | 是否可以旋轉(zhuǎn) | 否 | true |
canZoom | 是否可以縮放 | 否 | true |
canPull | 是否可以拉升 | 否 | true |
canMove | 是否可以平移 | 否 | true |
showAngle | 展示角度 | 否 | false |
showPosition | 展示位置 | 否 | false |
isScale | 是否等比例縮放 | 否 | true |
showBorder | 是否展示pannel的border | 否 | false |
屬性
canRotate
canZoom
canPull
canMove
showAngle
isScale
id
container
targetObj
pannelDom 操作divdom
...
具體看圖:
代碼解說
初始化參數(shù)
初始化目標(biāo)dom對象的位置:記錄其:
left平距左
top
width
height
angle
rightBottomPoint 目標(biāo)dom對象右下坐標(biāo)
rightTopPoint 目標(biāo)dom對象右上坐標(biāo)
leftTopPoint 目標(biāo)dom對象左上坐標(biāo)
leftBottomPoint 目標(biāo)dom對象左下坐標(biāo)
leftMiddlePoint 目標(biāo)dom對象左中坐標(biāo)
rightMiddlePoint 目標(biāo)dom對象右中坐標(biāo)
topMiddlePoint 目標(biāo)dom對象上中坐標(biāo)
bottomMiddlePoint 目標(biāo)dom對象下中坐標(biāo)
centerPos 目標(biāo)dom對象中心點坐標(biāo)
初始化pannel結(jié)構(gòu)
當(dāng)前的父容器中只有一個pannel結(jié)構(gòu),每次實例化對象時,會判斷一下如果當(dāng)前這個父容器里已經(jīng)存在id為pannel的結(jié)構(gòu),就將其子節(jié)點清空,按照當(dāng)前實例化對象傳進來的屬性重新渲染pannel子結(jié)構(gòu)。如果沒有id為pannel的結(jié)構(gòu),就創(chuàng)建。
初始化事件
給pannelDom和targetObj綁定mousedown事件
給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事件,是在所有實例化結(jié)束后,panneldom被展示在最后一個實例化對象上,鼠標(biāo)按下它時,觸發(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ù)新的目標(biāo)元素被重寫
this.pannelDom.onmousedown= e => {
this.moveInit(9, e, this.targetObj)
}
}
}
}
dom操作
旋轉(zhuǎn)操作
鼠標(biāo)按下時,記錄當(dāng)前鼠標(biāo)位置距離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)
鼠標(biāo)移動時,記錄再次計算鼠標(biāo)位置距離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的旋轉(zhuǎn)角度,this.getRotate(target)是js中獲取某dom元素的旋轉(zhuǎn)角度的方法(粘貼過來的,親測好使)
this.angle = this.getRotate(target) + Math.round(this.tranformRadian * 180 / Math.PI)
this.preRadian = this.curRadian //鼠標(biāo)移動的每一下都計算這個角度,所以每一下移動前的弧度值都上一次移動后的弧度值
計算旋轉(zhuǎn)后box每個點的坐標(biāo),根據(jù)余弦公式,傳入:旋轉(zhuǎn)前每點坐標(biāo),旋轉(zhuǎn)中心坐標(biāo)和旋轉(zhuǎn)角度
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))
關(guān)于javascript中怎么封裝一個拖拽類就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
網(wǎng)頁題目:javascript中怎么封裝一個拖拽類
URL地址:http://aaarwkj.com/article48/gjddhp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、網(wǎng)站設(shè)計、網(wǎng)站改版、微信公眾號、建站公司、品牌網(wǎng)站設(shè)計
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)