Giter Club home page Giter Club logo

vue-draggable-resizable-gorkys's Introduction

VueDraggableResizable 2

Latest Version on NPM Software License npm

该fork版本修复的问题清单:

  • fix:增加右键菜单事件contextmenu 2021-08-10
  • fix:开启自动对齐后,元素依据中线对齐可能会超出父容器边界的问题 2021-07-02
  • fix:取消选中的行为优先绑定在父节点上 2021-06-22
  • fix:冲突检测回退后没有再次触发resizing事件的bug 2021-06-08

新增特征✨

  • 辅助线(新)
  • 元素对齐(新)
  • 冲突检测
  • 吸附对齐
  • 默认样式优化

Q交流群:138146781

说明

说明:组件基于vue-draggable-resizable进行二次开发

距离上1.7版本版本的修改已经过去快一年的时间了,原版组件在之前已经更新到了2.0版本。

虽然之前适配过旧版组件,但是因为2.0版本原作者对代码进行了重构,原来修改的代码照搬是不可能的了。

所以也就一直没有将冲突检测以及吸附对齐功能适配到2.0版本,最近正好有时间就适配一下。

功能预览

英文版演示地址 | 中文版演示地址

注意:英文版为官方原版,没有新增功能的演示。中文版为google翻译版本,新增功能在高级目录下可查看

新增Props

handleInfo
类型: Object
必需: false
默认: { size: 8, offset: -5, switch: true }

当使用transform:scale()进行缩放操作时,其中switch为是否让handle始终保持视觉效果不变,size为handle的大小(宽高相同), offset为handle的位置偏移,通常在自定义handle样式时需要设置。

<vue-draggable-resizable :handle-info="{size: 14,offset: -5,switch: true}" />

scaleRatio
类型: Number
必需: false
默认: 1

当使用transform:scale()进行缩放操作时,用来修复操作组件时鼠标指针与移动缩放位置有所偏移的情况

详见:Issues

<vue-draggable-resizable :scale-ratio="0.6" />

isConflictCheck
类型: Boolean
必需: false
默认: false

定义组件是否开启冲突检测。

<vue-draggable-resizable :is-conflict-check="true" />

snap
类型: Boolean
必需: false
默认: false

定义组件是否开启元素对齐。

<vue-draggable-resizable :snap="true" />

snapTolerance
类型: Number
必需: false
默认: 5

当调用snap时,定义组件与元素之间的对齐距离,以像素(px)为单位。

<vue-draggable-resizable :snap="true" :snap-tolerance="20" />

新增Events

refLineParams
参数: params

返回参数是一个Object,里面包含vLinehLine,具体使用参考下面代码。

<div>
  <vue-draggable-resizable :snap="true" :snap-tolerance="20" @refLineParams="getRefLineParams" />
  <vue-draggable-resizable :snap="true" :snap-tolerance="20" @refLineParams="getRefLineParams" />
  <span class="ref-line v-line"
      v-for="item in vLine"
      v-show="item.display"
      :style="{ left: item.position, top: item.origin, height: item.lineLength}"
  />
  <span class="ref-line h-line"
      v-for="item in hLine"
      v-show="item.display"
      :style="{ top: item.position, left: item.origin, width: item.lineLength}"
  />
</div>

<script>
import VueDraggableResizable from 'vue-draggable-resizable'
import 'vue-draggable-resizable-gorkys/dist/VueDraggableResizable.css'

export default {
  name: 'app',
  components: {
    VueDraggableResizable
  },
  data () {
    return {
      vLine: [],
      hLine: []
    }
  },
  methods: {
    getRefLineParams (params) {
      const { vLine, hLine } = params
      this.vLine = vLine
      this.hLine = hLine
    }
  }
}
</script>

其它属性

英文版 | 中文版

注意:英文版为官方原版,中文版为google翻译版本

安装使用

$ npm install --save vue-draggable-resizable-gorkys

全局注册组件

//main.js
import Vue from 'vue'
import vdr from 'vue-draggable-resizable-gorkys'

// 导入默认样式
import 'vue-draggable-resizable-gorkys/dist/VueDraggableResizable.css'
Vue.component('vdr', vdr)

局部注册组件

<template>
  <div style="height: 500px; width: 500px; border: 1px solid red; position: relative;">
    <vdr :w="100" :h="100" v-on:dragging="onDrag" v-on:resizing="onResize" :parent="true">
      <p>Hello! I'm a flexible component. You can drag me around and you can resize me.<br>
      X: {{ x }} / Y: {{ y }} - Width: {{ width }} / Height: {{ height }}</p>
    </vdr>
    <vdr
      :w="200"
      :h="200"
      :parent="true"
      :debug="false"
      :min-width="200"
      :min-height="200"
      :isConflictCheck="true"
      :snap="true"
      :snapTolerance="20"
    >
    </vdr>
  </div>
</template>

<script>
import vdr from 'vue-draggable-resizable-gorkys'
import 'vue-draggable-resizable-gorkys/dist/VueDraggableResizable.css'
export default {
  components: {vdr},
  data: function () {
    return {
      width: 0,
      height: 0,
      x: 0,
      y: 0
    }
  },
  methods: {
    onResize: function (x, y, width, height) {
      this.x = x
      this.y = y
      this.width = width
      this.height = height
    },
    onDrag: function (x, y) {
      this.x = x
      this.y = y
    }
  }
}
</script>

License

The MIT License (MIT). Please see License File for more information.

vue-draggable-resizable-gorkys's People

Contributors

gorkys avatar wuzhibo0902 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-draggable-resizable-gorkys's Issues

IE compliant

when you run server in IE, you will find ['object not support forEach'].
While you're traversing nodeLlist, the forEach method won't work in IE, you can replace it with [for of]

缩放时 中心点 选取会不同

当lock-aspect-ratio 为false时, 4个对角点进行缩放时,是会以 相反的对角点作为固定点进行缩放,而 lock-aspect-ratio为true时,固定点要么是左上,要么是右下了

点击组件,组件会刷新

你好,我的组件里面是一个echarts饼图。当我点击组件的时候,饼图会重绘,请问怎样可以阻止饼图重绘

请问我在组件内部添加了内容元素,在元素上添加了点击事件, 触发点击事件的时候总是触发组件的dragstop事件,如何避免冒泡或默认事件呢, stop, .pevent .native 写在子组件的事件上都不管用

<vdr
          v-for="(item2, index) in fastMenuList"
          :key="index"
          :w="80"
          :h="80"
          :min-width="80"
          :min-height="80"
          :y="Number(item2.position.split(',')[1])"
          :x="Number(item2.position.split(',')[0])"
          :z="index + 1041"
          :outline='false'
          :resizable="false"
          :snap='true'
          :isConflictCheck='true'
          :snap-tolerance="20"
          class-name="vdr"
          class-name-dragging="draggingClass"
          parent=".nav-conts"
          :preventActiveBehavior='true'
          :maximize="true"
          @dragstop="(left,top)=>onDragStop(item2.id, left, top)"
        >
          <div
            class='menu-item'
            :index="item2.menuId + ''"
            v-on:dblclick.prevent="gotoRouteHandle($event,item2)"
            >
            <icon-svg :name="item2.icon || ''" class="site-sidebar__menu-icon"></icon-svg>
            <span>{{item2.name}}</span>
          </div>
        </vdr>

关于辅助线精确性问题建议方案

image

问题一

关于辅助线不在控制点中间的问题2.4.0版本已修复

是因为基础导入的控制点样式不在正中位置导致的,只要将
handle-tm,handle-ml,handle-mr,handle-bm四个中心控制点的样式进行覆盖。
例:

.handle-tm {
  top: -5px;
  left: calc(50% - 4px);
  /*margin-left: -5px;*/
  cursor: n-resize;
}

问题二

关于未对齐时却出现辅助线的情况

因为元素大小的差值与snapTolerance所设值相近时导致的误差判断。
为了保证精确性,建议吸附功能与辅助线功能二选一。
snapTolerance值为1时,不会出现图中所见问题,所以当需求上snapTolerance值大于1时可选择关闭辅助线功能。

另,如果有相关的修复方案可直接联系我或提交PR。

关于父元素的大小发生变化,组件移动区域未改变的问题

问题参考原作者的issues,很多人问,并且一直纠结于提问者给出的方案,其实原作者已在下面给出更好的解决方案。
主动触发windowresize事件就可以解决。
在业务中动态调整父元素的大小后,使用:

this.$nextTick(() => {
     window.dispatchEvent(new Event('resize'))
})

即可...

关于使用transform: scale()属性导致html2canvas截图缺失的解决办法

按理说关于html2canvas的问题不应该写在这里,但是呢,目前此组件提供了对scale的修复功能。

我自己在项目中使用此组件的时候有场景遇到了此问题,就在这里记录一下。

<div  id="editArea" :style="templateStyle" class="editArea">
            <vdr
              v-for="(item,index) in elements"
              :key="item.id"
              :parent="true"
              :x="item.x"
              :y="item.y"
              :w="item.width"
              :h="item.height"
              :z="item.zIndex"
            ></vdr>
</div>
/*--------------*/
  computed: {
    templateStyle: function() {
      return {
        width: `${this.templateWidth}px`,
        height: `${this.templateHeight}px`,
        transform: `scale(${this.proportion})`
      }
    }
/*--------------*/
 .editArea{
    background-color: white;
    flex-shrink: 0;
  }

最开始的代码大致如上(缩写了很多属性),在页面上显示正常,但是就是截图的时候,lefttop会缺失一部分。当时使用了html2canvasx,y属性进行偏移矫正,也是没办法完全恢复。

因为以前用过html2canvas,这次除了增加了transform:scale()其它都基本一样。所以把出现问题的重点放在它的身上。百度完又googel,google完又在github里翻issuse。各种五花八门的答案都有,不过百度上的基本是copy来copy去。

最终是调出devTools,把transform注释掉后发现里面的内容超出了#editArea的有效范围。
恍然大悟。

 .editArea{
    background-color: white;
    flex-shrink: 0;
    position: relative;
  }

加上relative后完全正常。本来布局上就出现了问题,只是缩放后问题就此被遮盖住了。

同时拖动多个组件时以一个整体为基准显示辅助线

实现同时拖动多个元素的原理是通过拖动一个元素,另外一个元素的通过计算跟随移动。所以位置可能会出现一些误差。如果有更好的解决方案可以留言。

成为一个整体的前提条件是需要将跟随元素都设为激活状态

注意: 拖动多个组件时,不支持吸附与元素对齐功能。

image

冲突检测,组件往左移动失效,组件左右拉伸和向下拉伸失效

代码如下,代码来源链接:https://tingtas.com/vue-draggable-resizable-gorkys/?path=/story/%E9%AB%98%E7%BA%A7--%E5%85%83%E7%B4%A0%E5%AF%B9%E9%BD%90%E4%B8%8E%E8%BE%85%E5%8A%A9%E7%BA%BF

<template>
  <div id="app">
    <div style="height: 800px; width: 1200px; border: 1px solid red; position: relative;margin: 0 auto">
      <vdr
        :w="200"
        :h="200"
        :parent="true"
        :debug="false"
        :min-width="200"
        :min-height="200"
        :is-conflict-check="true"
        :snap="true"
        :snap-tolerance="10"
        class="test1"
        @refLineParams="getRefLineParams"
      />
      <vdr
        :w="200"
        :h="200"
        :parent="true"
        :x="210"
        :debug="false"
        :min-width="200"
        :min-height="200"
        :is-conflict-check="true"
        :snap="true"
        :snap-tolerance="10"
        class="test2"
        @refLineParams="getRefLineParams"
      />
      <vdr
        :w="200"
        :h="200"
        :parent="true"
        :x="420"
        :debug="false"
        :min-width="200"
        :min-height="200"
        :is-conflict-check="true"
        :snap="true"
        :snap-tolerance="10"
        class="test3"
        @refLineParams="getRefLineParams"
      />
      <!--辅助线-->
      <span
        v-for="item in vLine"
        v-show="item.display"
        class="ref-line v-line"
        :style="{ left: item.position, top: item.origin, height: item.lineLength}"
      />
      <span
        v-for="item in hLine"
        v-show="item.display"
        class="ref-line h-line"
        :style="{ top: item.position, left: item.origin, width: item.lineLength}"
      />
      <!--辅助线END-->
    </div>
  </div>
</template>

<script>

export default {
  name: 'DemoDrag',

  data() {
    return {
      vLine: [],
      hLine: []
    }
  },
  methods: {
    // 辅助线回调事件
    getRefLineParams(params) {
      const { vLine, hLine } = params
      this.vLine = vLine
      this.hLine = hLine
    }
  }
}
</script>

<style>
  .test1 {
    background-color: rgb(239, 154, 154);
  }
  .test2{
    background-color: rgb(129, 212, 250);
  }
  .test3{
    background-color: rgb(174, 213, 129);
  }
</style>

冲突检测后resizestop与dragstop返回参数问题

当组件与组件进行冲突检测时,组件移动结束(dragstop)并判定冲突回到起始位置后,resizestopdragstop返回的参数值应当是起始位置。

而目前返回的参数值是移动结束时的位置,并非组件实际所在的位置

默认class建议改个名字

VueDraggableResizable.css中直接设置了.vdr、.handle的样式。
vdr还好,handle这个名字实在太容易冲突了,建议修改一下吧。

请教一下如何进行从外界拖拽生成组件。

image
类似鼠标在输入框文本处按下,自动生成组件并可以拖拽。 我试过按下时进行数组push,组件生成但是没有被默认选中无法进行拖拽。使用js主动触发mousedown发现会产生极大偏移。
image

parent allowed .class identifier, now its boolean only.

Love the additional features you have added :)

Previously, I could use parent to identify a class to restrict the draggable to. Now, it only allows boolean. Any plans on restoring the previous capability to also allow css class?

源码中计算属性style存在不受props传入的minWidth、minHeight、maxWidth、maxHeight、x、y控制的现象

vue-draggable-resizable.vue文件的第1087~1094行,直接使用了data中的数据,在实际使用过程中如果组件自己响应了浏览器的resize事件重新计算了minWidth、minHeight、maxWidth、maxHeight、x、y等,通过props传入后,style计算出来的内容不受传入的值控制,导致组件显示异常。
style () {
return {
transform: translate(${this.left}px, ${this.top}px),
width: this.computedWidth,
height: this.computedHeight,
zIndex: this.zIndex,
...(this.dragging && this.disableUserSelect ? userSelectNone : userSelectAuto)
}
}

需要在return中进行校验控制,防止出现自己计算出来的数据和props传入的数据有出入。

关于现拖拽元素中对元素进行拖拽的问题

QQ截图20191204112107
QQ截图20191204112116

如图展示,只要拖拽元素中的子元素,就会出现错位的问题,如果修改样式 position: absolute,会连着把父类元素一起拖动(正常状态应该是父类元素不会拖动,之后改动子元素的位置),请问有什么思路可以解决这个问题?谢谢!

您好请教一下有遇到图中出现的问题吗

vue.runtime.esm.js?0261:619 [Vue warn]: Error in mounted hook: "TypeError: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'."

found in

--->

TypeError: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.
at VueComponent.getParentSize (VueDraggableResizable.umd.min.js?52a7:1)
at VueComponent.mounted (VueDraggableResizable.umd.min.js?52a7:1)
at invokeWithErrorHandling (vue.runtime.esm.js?0261:1854)
at callHook (vue.runtime.esm.js?0261:4219)
at Object.insert (vue.runtime.esm.js?0261:3139)
at invokeInsertHook (vue.runtime.esm.js?0261:6346)
at VueComponent.patch [as patch] (vue.runtime.esm.js?0261:6565)
at VueComponent.Vue._update (vue.runtime.esm.js?0261:3948)
at VueComponent.updateComponent (vue.runtime.esm.js?0261:4066)
at Watcher.get (vue.runtime.esm.js?0261:4479)
您好,请问一下出现这个问题是什么原因

通过列表数据渲染多个可拖动box,给每一个增加一个删除按钮,点击删除出现错误

版本2.4.4
删除使用的最常规的 splice
删除前的样子
image
删除后
image
下方de的块自动上移了
通过修改代码消除当前问题

moveHorizontally(val) {
      const [deltaX, deltaY] = snapToGrid(this.grid, val, this.top, this.scale)
      console.log(deltaX, deltaY)
      const left = restrictToBounds(deltaX, this.bounds.minLeft, this.bounds.maxLeft)
      this.left = val  // 插件中原来取得是left  改成val就不再有问题了
      this.right = this.parentWidth - this.width - left
    },
    moveVertically(val) {
      const [deltaX, deltaY] = snapToGrid(this.grid, this.left, val, this.scale)
      console.log(deltaX, deltaY)
      const top = restrictToBounds(deltaY, this.bounds.minTop, this.bounds.maxTop)
      this.top = val   // 插件中原来取得是top  改成val就不再有问题了
      this.bottom = this.parentHeight - this.height - top
    },

忘楼主帮忙解答一下,原来为什么取计算出来的top和left,改成取val就不再有当前问题了

缺少计算属性

屏幕宽度动态变宽后,每一个拖动的元素w,h,x,y不会重新计算

希望可以加一个单位参数

当前的width height 支持 数字 或者 auto? 单位是px

在H5项目里 单位rem的无法进行正常的工作. 希望可以增加一个参数为单位 默认px

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.