关于前端:假如今天让你写一个可自由拖拽的组件

38次阅读

共计 1833 个字符,预计需要花费 5 分钟才能阅读完成。

最近的我的项目中遇到一个需要,在页面上增加一个能够自在拖拽、缩放、编辑色彩的 svg 图片,我的项目中援用了两个现有的插件,对插件进行解读之后略有心得,与大家分享一下。
自在拖拽缩放的节点 —— react-rnd

说到拖拽,咱们的第一反馈当然是监听鼠标事件来批改 dom 元素的地位,而缩放的话,则是在对元素边界进行操作时从新修改元素的 position 和 width、height 属性。这部分就不予过多的赘述,有趣味的敌人能够参考下 react-rnd 这个插件,它援用了 react-draggable 和 react-resizeable 两个插件来实现元素的拖拽和缩放。
此时咱们实践上曾经实现了 dom 元素的拖拽和缩放,然而在增加了 svg 图片之后咱们很快发现,因为外层的拖拽是由 document.addEventListener 来实现的,然而咱们在 mouseDown 的时候,鼠标点击的地位实际上是 svg 内的 document。

那么这个时候应该怎么解决呢?最简略的思路:把 svg 的 document 取出来,放到父级的 document 外面。

自在的 svg —— react-svg

有了把 svg 的 document 取出来的思路,咱们很容易能找到一个插件:react-svg,它的实现思路与咱们下面提到的完全一致,此处贴上它的外围代码供各位查看:

avatar
此时咱们发现,咱们增加的 svg 图片曾经能够自在的拖拽和缩放了。另外因为 react-svg 还凋谢了一个属性 beforeInjection,咱们能够通过这个属性来在 svg 挂载之前批改它的属性,如 stroke、stroke-width、fill 等,因而咱们能够更加灵便得解决咱们的 svg 图片。

svg 的缩放 —— preserveAspectRatio、vector-effect

咱们很快又发现一个问题,svg 的缩放默认是等比的,也就是说当咱们横向拉长图片的时候,它并不会变大,只会横向偏移居中。

这个时候咱们就要用到 svg 自带的一个属性:preserveAspectRatio,用来示意是否强制进行对立缩放,当设置为 none 的时候,svg 图片不会进行强制对立缩放,如果须要,会缩放指定元素的图形内容,使元素的边界齐全匹配视图矩形。如下图。其余类型强制缩放可参考 MDN。

当初咱们的 svg 终于能够自在缩放了,然而很快咱们又发现,把一个 svg 放大之后,它的线条宽度也跟着变宽了,那么有没有什么属性来放弃线条宽度不变呢?答案是有的,vector-effect,然而这个属性只对局部 svg 元素(<circle>, <ellipse>, <foreignObject>, <image>, <line>, <path>, <polygon>, <polyline>, <rect>, <text>, <textPath> <tspan>, <use>)失效,而它的属性有以下几个:
none 该值指定不利用矢量成果,即,应用默认的渲染行为,即首先用指定的绘画填充形态的几何形态,而后应用指定的绘画描边轮廓。
non-scaling-stroke 该值批改了笔触的形式。通常,笔触波及在以后用户坐标系中计算形态门路的笔触轮廓,并用笔触颜料(色彩或突变)填充轮廓。该值的最终视觉效果是笔触宽度不依赖于元素的变换(包含非平均缩放和剪切变换)和缩放级别。
non-scaling-size 该值指定元素及其后辈应用的非凡用户坐标系。只管从宿主坐标空间进行任何转换更改,该用户坐标系的比例也不会更改。然而,它没有指定克制旋转和偏斜。同样,它也不指定用户坐标系的原点。因为此值克制了用户坐标系的缩放,因而它还具备 non-scaling-stroke 的个性。
non-rotation 该值指定元素及其后辈应用的非凡用户坐标系。只管从宿主坐标空间产生任何变换更改,该用户坐标系的旋转和歪斜仍被克制。然而,它没有指定克制缩放。同样,它也没有指定用户坐标系的原点。
fixed-position 该值指定元素及其后辈应用的非凡用户坐标系。只管从宿主坐标空间进行任何转换更改,用户坐标系的地位都是固定的。然而,它没有指定克制旋转,偏斜和缩放。当同时指定了该矢量成果和 transform 属性,transform 属性将因该矢量成果而被耗费。
当咱们设置 vector-effect=”non-scaling-stroke” 后,咱们的 svg 终于看起来失常了~

序幕

以上就是咱们在做给页面上增加一个能够自在拖拽、缩放、编辑色彩的 svg 图片时总结的一些货色

正文完
 0