articles icon indicating copy to clipboard operation
articles copied to clipboard

vue实现dom元素拖动布局

Open zhengguorong opened this issue 6 years ago • 0 comments

项目演示

完整代码请访问github

源码地址 在线demo账号admin 密码admin

核心对象

下面的操作都基于Element对象,element由父组件传递给子组件,子组件负责监听鼠标实现,修改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
  }
}

元素实现拖动

监听鼠标移动事件,计算移动的距离并修改对象属性 参考代码:src/components/Element/PicElement.vue

// 这里监听的是editor这个类的鼠标移动,就是最外层容器,防止元素超出画布没反应
document.querySelector('.editor').onmousemove = (event) => {
            var e = event || window.event
            // 锁判断,当释放鼠标的时候,鼠标移动不执行操作
            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、监听鼠标点击元素和移动的方向,实现元素放大 参考代码: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
              }
            }
          }

zhengguorong avatar Sep 19 '18 06:09 zhengguorong