锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

拖拽缩放热区vue组件代码解决方案

时间:2023-12-03 21:07:02 fxd101套管式温度传感器

热区组件可移动

 /* Movable/index.js */ export { 
         default as MovableArea } from './Components/Area' export { 
         default as MovableView } from './Components/View'  

可视化区域

/* Movable/Components/View.vue */ <script> const MovableView = { 
           props: { 
             height  : { 
         type: Number, required: true },     width   : { 
         type: Number, required: true },     left    : { 
         type: Number, required: true },     top     : { 
         type: Number, required: true },     overflow: { 
         type: Boolean },     ratio   : { 
         type: Boolean },     minSize : { 
         type: Number, default: 40 },     maxSize : { 
         type: Number },     imgSrc  : { 
         type: String },     styles  : { 
         type: Object, default: () => ({ 
        ) },
    resize  : { 
         type: Boolean },
    onChange: { 
         type: Function },
    visible: { 
         type: Boolean, default: true }
  },
  methods: { 
        
    handleMoveMouseDown(e) { 
        
      this.parseMove(e, (val) => { 
        
        let top = val.y
        let left = val.x

        if (!this.$props.overflow) { 
        
          const parentWidth = parseFloat(this.$refs.viewDomRef.parentElement.style.width)
          const parentHeight = parseFloat(this.$refs.viewDomRef.parentElement.style.height)
          top = Math.max(0, top)
          top = Math.min(top, parentHeight - this.$props.height)

          left = Math.max(0, left)
          left = Math.min(left, parentWidth - this.$props.width)
        }
        this.$props.onChange && this.$props.onChange({ 
        
          width: this.$props.width,
          height: this.$props.height,
          top,
          left
        })
      })
    },
    handleResizeMouseDown(e) { 
        
      e.stopPropagation()
      this.parseMove(e, (val) => { 
        
        let width = val.x + 12
        let height = val.y + 12

        // 是否允许超出
        if (!this.$props.overflow) { 
        
          const parentWidth = parseFloat(this.$refs.viewDomRef.parentElement.style.width)
          const parentHeight = parseFloat(this.$refs.viewDomRef.parentElement.style.height)
          width = Math.min(width, parentWidth - this.$props.left)
          height = Math.min(height, parentHeight - this.$props.top)
        }

        // 等比缩放
        if (this.$props.ratio) { 
        
          height = width = Math.min(width, height)
        }

        // 最小缩放值

        width = Math.max(width, this.$props.minSize)
        height = Math.max(height, this.$props.minSize)

        // 最大缩放值
        if (this.$props.maxSize) { 
        
          width = Math.min(width, this.$props.maxSize)
          height = Math.min(height, this.$props.maxSize)
        }

        this.$props.onChange && this.$props.onChange({ 
        
          width,
          height,
          top: this.$props.top,
          left: this.$props.left
        })
      })
    },
    parseMove(e, cb) { 
        
      const x = e.clientX - e.currentTarget.offsetLeft
      const y = e.clientY - e.currentTarget.offsetTop
      this.moveEventcache = document.onmousemove
      document.onmousemove = (ee) => { 
        
        cb && cb({ 
         x: ee.clientX - x, y: ee.clientY - y })
      }
      document.onmouseup = () => { 
        
        document.onmousemove = this.moveEventcache
      }
    }

  },

  render() { 
        
    if (this.$props.visible === false) return null
    const styles = { 
        
      position: 'absolute',
      width: this.$props.width + 'px',
      height: this.$props.height + 'px',
      top: this.$props.top + 'px',
      left: this.$props.left + 'px',
      cursor: 'grab',
      userSelect: 'none',
      backgroundImage: 'url("' + this.$props.imgSrc + '")',
      backgroundSize: 'contain',
      backgroundPosition: 'center',
      backgroundRepeat: 'no-repeat',
      ...(this.$props.styles)
    }
    const resizeStyle = { 
        
      position: 'absolute',
      right: 0,
      bottom: 0,
      width: 12 + 'px',
      height: 12 + 'px',
      opacity: '0.9',
      cursor: 'nwse-resize',
      backgroundSize: '100%',
      userSelect: 'none',
      backgroundImage: 'url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAVFBMVEUAAADd3d3b29vd3d3e3t7k5OT19fXd3d3n5+eZmZnHx8e4uLioqKjv7++urq7z8/Ps7OzX19e0tLSrq6vk5OTi4uLQ0NCwsLDp6enKysq/v7++vr57c1IlAAAABnRSTlMAf4D2qROyT4+oAAABJElEQVRYw6XV3U7CUBBFYVvQOadAEQF/3/89NTayEieZKXv2/bc6aS/6UNxY9Vbzg1nVW9FfreZbs5p/IqB5AponoHkCmiegeQKaJ6B5AponIHoCoicgegKC1wJ4LYDXAngtgNcCeC2A1wJ4LYAXA3g9MOKFAF4I4LUAXgvgtQBeDHjf5s8kkPh9n+4LDKknkPtnvAus8Yc/38gQyP3x5vfdsgCe3fy5Bxfk/h1PYJX/WF7kjCewxr/+87uvMDCmvk8EUn/up+VDvjlPIPBz4H3A+1O3xb94T8B7tjz/6D0BhmeBJ5D6nfcEcg/DE/Deb3KeQOQZPggMgicgegL5/Q3vAvhoFvwXuH/tCODFAPdLu1jNH2zz669N28Vs++ML22wfvwHZ2TVJ7XC9dwAAAABJRU5ErkJggg==")'
    }
    return (
      <div style={ 
        styles} ref="viewDomRef" onmousedown={ 
        this.handleMoveMouseDown.bind(this)}>
        { 
        this.$slots?.default}
        { 
        this.$props.resize && <div style={ 
        resizeStyle} onmousedown={ 
        this.handleResizeMouseDown.bind(this)} />}
      </div>
    )
  }
}

export default MovableView
</script>

可拖拽组件

/* Movable/Components/Area.vue */
<script>
const MovableArea = { 
        
  props: { 
        
    width: { 
        
      type: Number,
      default: '100%'
    },
    height: { 
        
      type: Number,
      default: '100%'
    },
    imgSrc: { 
        
      type: String,
      default: ''
    }
  },
  render() { 
        
    const styles = { 
        
      position: 'relative',
      width: this.width ? this.width + 'px' : '100%',
      height: this.height ? this.height + 'px' : '100%',
      backgroundImage: 'url(' + this.imgSrc + ')',
      backgroundSize: '100%'
    }
    return (
      <div className="movable-area-block" style={ 
        styles}>
        { 
        this.$slots?.default}
      </div>
    )
  }
}

export default MovableArea

</script>
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章