vueドラッグ拡大縮小コンテナコンポーネント

7700 ワード

コードは直接実行できます
効果:4つの方向と4つのコーナーにストレッチ、ドラッグ
GitHubにパッケージされています.https://github.com/GuLinLing/vue-resize-box





  export default {
    name: 'ResizeBox',
    props: {
      max: {
        type: Object,
        default: function () {
          return {
            width: 0,
            height: 0
          }
        },
        validator: function (obj) {
          if (typeof obj.width === 'number' || typeof obj.height === 'number') {
            if (obj.width >= 0 && obj.height >= 0) {
              return true
            } else {
              return false
            }
          } else {
            return false
          }
        }
      },
      min: {
        type: Object,
        default: () => {
          return {
            width: 0,
            height: 0
          }
        },
        validator: function (obj) {
          if (typeof obj.width === 'number' || typeof obj.height === 'number') {
            if (obj.width >= 0 && obj.height >= 0) {
              return true
            } else {
              return false
            }
          } else {
            return false
          }
        }
      },
      move: {
        type: Object,
        default: () => {
          return {
            t: true,
            l: true,
            r: true,
            b: true,
            tl: true,
            tr: true,
            bl: true,
            br: true
          }
        },
        validator: function (obj) {
          if (
            typeof obj.t === 'boolean'
            || typeof obj.l === 'boolean'
            || typeof obj.r === 'boolean'
            || typeof obj.b === 'boolean'
            || typeof obj.tl === 'boolean'
            || typeof obj.tr === 'boolean'
            || typeof obj.bl === 'boolean'
            || typeof obj.br === 'boolean'
          ) {
            return true
          } else {
            return false
          }
        }
      },
      speed: {
        type: Number,
        default: 2,
        validator: function (num) {
          return num >= 1
        }
      },
      disabled: {
        type: Boolean,
        default: false
      }
    },
    created () {
      document.body.addEventListener('mouseup', this.mouseupHanlder)
    },
    destroyed () {
      document.body.removeEventListener('mouseup', this.mouseupHanlder)
    },
    methods: {
      getStyle (element) {
        if (element.currentStyle) {
          return element.currentStyle
        } else {
          return getComputedStyle(element, false)
        }
      },
      mousedownHanlder (event) {
        let { cursor } = this.getStyle(event.target)
        this.dataType = event.target.getAttribute('data-type')
        this.event = event
        document.body.addEventListener('mousemove', this.mousemoveHandler)
        document.body.style.cursor = cursor
      },
      mouseupHanlder () {
        document.body.removeEventListener('mousemove', this.mousemoveHandler)
        document.body.style.cursor = 'default'
      },
      mousemoveHandler (event) {
        if (this.disabled) {
          return
        }
        let { width, height } = this.getStyle(this.$el)
        width = parseInt(width)
        height = parseInt(height)
        this[this.dataType]({ event, width, height })
        this.event = event
      },
      t ({ event, height }) {
        if (event.y > this.event.y) {
          this.$el.style.height = this.min.height
            ? `${ Math.max(this.min.height, height - (event.y - this.event.y) * this.speed) }px`
            : `${ height - (event.y - this.event.y) * this.speed }px`
        } else {
          this.$el.style.height = this.max.height
            ? `${ Math.min(this.max.height, height + (this.event.y - event.y) * this.speed) }px`
            : `${ height + (this.event.y - event.y) * this.speed }px`
        }
      },
      l ({ event, width }) {
        if (event.x > this.event.x) {
          this.$el.style.width = this.min.width
            ? `${ Math.max(this.min.width, width - (event.x - this.event.x) * this.speed)}px`
            : `${ width - (event.x - this.event.x) * this.speed }px`
        } else {
          this.$el.style.width = this.max.width
            ? `${ Math.min(this.max.width, width + (this.event.x - event.x) * this.speed) }px`
            : `${ width + (this.event.x - event.x) * this.speed }px`
        }
      },
      r ({ event, width }) {
        if (event.x > this.event.x) {
          this.$el.style.width = this.max.width
            ? `${ Math.min(this.max.width, width + (event.x - this.event.x) * this.speed) }px`
            : `${ width + (event.x - this.event.x) * this.speed }px`
        } else {
          this.$el.style.width = this.min.width
            ? `${ Math.max(this.min.width, width - (this.event.x - event.x) * this.speed) }px`
            : `${ width - (this.event.x - event.x) * this.speed }px`
        }
      },
      b ({ event, height }) {
        if (event.y > this.event.y) {
          this.$el.style.height = this.max.height
            ? `${ Math.min(this.max.height, height + (event.y - this.event.y) * this.speed) }px`
            : `${ height + (event.y - this.event.y) * this.speed }px`
        } else {
          this.$el.style.height = this.min.height
            ? `${ Math.max(this.min.height, height - (this.event.y - event.y) * this.speed) }px`
            : `${ height - (this.event.y - event.y) * this.speed }px`
        }
      },
      tl ({ event, width, height }) {
        this.t({ event, height })
        this.l({ event, width})
      },
      tr ({ event, width, height }) {
        this.t({ event, height })
        this.r({ event, width })
      },
      bl ({ event, width, height }) {
        this.b({ event, height })
        this.l({ event, width })
      },
      br ({ event, width, height }) {
        this.b({ event, height })
        this.r({ event, width })
      }
    }
  }