戴尬猴,我是德育处主任
这次要介绍的一个demo是"拖拽多边形定点修改多边形形状"。
其实 Fabric.js
官网也有这个demo:Fabric.js demos · Custom controls, polygon 。但这个demo可能对于刚接触 Fabric.js
的工友来说有点过于复杂,所以本文就把该demo进一步简化,简化到老奶奶也能看得懂的!
先看看效果(录制gif的工具有点小瑕疵,导致多边形红色填充色“被弄脏了”):
完整代码在文末。
要实现“拖拽多边形定点修改多边形形状”这个功能有很多方案,比如 Fabric.js demos · Custom controls, polygon 中,通过自定义控件来实现。
使用 Fabric.js
官网给出的demo会更优雅,推荐在工作中使用。
本文使用对学习阶段来说更容易理解的方案去实现上述功能。
先列出所有步骤:
new fabric.Canvas()
new fabric.Polygon()
new fabric.Circle()
canvas.on('object:moving', callback)
canvas.renderAll()
以上就是需要做的所有操作了。
我们创建出来的多边形是禁止用户直接操作的,想要修改多边形形状只能通过辅助的小圆来修改。
要禁止多边形的操作可以设置多边形以下两个属性为 false
:
selectable: false, // 禁止选中 evented: false, // 当设置为“false”时,对象不能成为事件的目标。所有事件都会通过它传播。
还要将多边形的 objectCaching
设置为 false
,只有这样做了,多边形才不会有缓存。
创建圆形时,需要将其 originX
和 originY
设置为 center
,这样圆形的圆心就是它的 top
和 left
了。
除此之外还需要将 hasControls
和 hasBorders
设置为 false
,这样做完圆形就不会显示控制角和控制边了,看上去会更像是多边形的控件。
最后还需要给每个圆形添加一个自定义属性,当圆形被移动时就可以用这个自定义属性判断当前移动的是哪个圆。
如果理解了上面的讲解就看看下面的代码吧(都有备注了,应该比较好理解)
<canvas id="c" width="500" height="400" style="border:1px solid #ccc"></canvas> <script src="https://unpkg.com/fabric@5.3.0/dist/fabric.min.js"></script> <script> // 绑定画布 const canvas = new fabric.Canvas('c') // 多边形的顶点 let points = [ {x: 80, y: 80}, {x: 150, y: 40}, {x: 220, y: 80}, {x: 200, y: 190}, {x: 100, y: 160} ] // 多边形 const polygon = new fabric.Polygon( points, // 顶点坐标集 { fill: 'red', // 填充红色 stroke: 'black', // 边框黑色 strokeWidth: 2, // 边框粗细 objectCaching: false, // 当“true”时,对象缓存在另一个画布上。当“false”时,除非必要(clipPath)默认为 true,否则不缓存对象。默认是true selectable: false, // 禁止选中 evented: false, // 当设置为“false”时,对象不能成为事件的目标。所有事件都会通过它传播。 } ) // 圆形列表 let circleList = [] // 循环所有定点并创建圆形 points.forEach((item, index) => { circleList.push( new fabric.Circle({ left: item.x, top: item.y, strokeWidth: 5, radius: 12, fill: '#fff', stroke: '#666', originX: 'center', // x轴方向以中心点为原点 originY: 'center', // y轴方向以中心点为原点 hasControls: false, // 不显示控制器 hasBorders: false, // 不显示控制器的边 cid: `circle-${index}` // 自定义属性 }) ) }) // 将多边形和圆形对象添加到画布中 canvas.add(polygon, ...circleList) // 监听画布上的元素移动事件 canvas.on('object:moving', function(e) { // 当前移动的元素 let target = e.target // 如果存在自定义属性和指定值就执行以下代码(本例主要筛选出刚刚创建的几个圆形) if ('cid' in target && target.cid.match(RegExp(/circle-/))) { // 通过cid可以判断出当前操作的是哪个圆形,并且圆形的cid最后一位对应多边形指定的顶点 let index = target.cid.split('-')[1] // 获取多边形定点 let points = polygon.points // 修改指定点顶点的x坐标 points[index].x = target.left // 修改指定定点的y坐标 points[index].y = target.top // 刷新画布 canvas.renderAll() } }) </script>
⭐ 修改多边形形状
代码仓库