先看效果圖,有興趣再看實(shí)現(xiàn)細(xì)節(jié)
項(xiàng)目演示
完整代碼請?jiān)L問github
核心對象
下面的操作都基于Element對象,element由父組件傳遞給子組件,子組件負(fù)責(zé)監(jiān)聽鼠標(biāo)實(shí)現(xiàn),修改element對象。
elememt對象屬性
export default class Element {
constructor (ele = {}) {
this.type = ele.type || 'pic'
this.imgSrc = ele.imgSrc || ''
this.left = ele.left || 0
this.top = ele.top || 0
this.width = ele.width || 0
this.height = ele.height || 0
this.lineHeight = ele.lineHeight || 0
this.animatedName = ele.animatedName || ''
this.duration = ele.duration || 1
this.delay = ele.delay || 0
this.playing = false
this.loop = false
this.opacity = ele.opacity || 100
this.transform = ele.transform || 0
this.text = ele.text || ''
this.textAlign = ele.textAlign || 'left'
this.iconKey = ele.iconKey || ''
this.bg = ele.bg || ''
this.fontSize = ele.fontSize || 18
this.fontFamily = ele.fontFamily || '微軟雅黑'
this.fontWeight = ele.fontWeight || 'normal'
this.color = ele.color || '#000000'
this.zindex = ele.zindex || 1
}
}
元素實(shí)現(xiàn)拖動
監(jiān)聽鼠標(biāo)移動事件,計(jì)算移動的距離并修改對象屬性
參考代碼:src/components/Element/PicElement.vue
// 這里監(jiān)聽的是editor這個類的鼠標(biāo)移動,就是最外層容器,防止元素超出畫布沒反應(yīng)
document.querySelector('.editor').onmousemove = (event) => {
var e = event || window.event
// 鎖判斷,當(dāng)釋放鼠標(biāo)的時(shí)候,鼠標(biāo)移動不執(zhí)行操作
if (this.flag) {
let nowX = e.clientX
let nowY = e.clientY
let disX = nowX - this.currentX
let disY = nowY - this.currentY
this.element.top = parseInt(this.top) + disY
this.element.left = parseInt(this.left) + disX
}
}
元素拖動邊角放大縮少
1、給元素加入編輯邊框,通過絕對定位,綁定到需要編輯器的元素。
參考代碼:src/components/Operate.vue
<div class="operate">
<div class="operate-hor-line"></div>
<div class="operate-ver-line"></div>
<div class="scale scale-nw" data-direction="nw"></div>
<div class="scale scale-ne" data-direction="ne"></div>
<div class="scale scale-sw" data-direction="sw"></div>
<div class="scale scale-se" data-direction="se"></div>
<div class="scale scale-n" data-direction="n"></div>
<div class="scale scale-e" data-direction="e"></div>
<div class="scale scale-s" data-direction="s"></div>
<div class="scale scale-w" data-direction="w"></div>
</div>
2、監(jiān)聽鼠標(biāo)點(diǎn)擊元素和移動的方向,實(shí)現(xiàn)元素放大
參考代碼:src/components/Element/PicElement.vue
document.querySelector('.editor').onmousemove = (event) => {
var e = event || window.event
if (this.scaleFlag) {
let nowX = e.clientX
let nowY = e.clientY
let disX = nowX - this.currentX
let disY = nowY - this.currentY
switch (this.direction) {
// 左邊
case 'w':
this.element.width = parseInt(this.width) - disX
this.element.left = parseInt(this.left) + disX
break
// 右邊
case 'e':
this.element.width = parseInt(this.width) + disX
break
// 上邊
case 'n':
this.element.height = parseInt(this.height) - disY
this.element.top = parseInt(this.top) + disY
break
// 下邊
case 's':
this.element.height = parseInt(this.height) + disY
break
// 左上
case 'nw':
this.element.width = parseInt(this.width) - disX
this.element.left = parseInt(this.left) + disX
this.element.height = parseInt(this.height) - disY
this.element.top = parseInt(this.top) + disY
break
// 左下
case 'sw':
this.element.width = parseInt(this.width) - disX
this.element.left = parseInt(this.left) + disX
this.element.height = parseInt(this.height) + disY
break
// 右上
case 'ne':
this.element.height = parseInt(this.height) - disY
this.element.top = parseInt(this.top) + disY
this.element.width = parseInt(this.width) + disX
break
// 右下
case 'se':
this.element.height = parseInt(this.height) + disY
this.element.width = parseInt(this.width) + disX
break
}
}
}