fabic.js Stickman应用》》元素关联设置/拓扑图
分析:最核心代码为set({ 'x2': p.left, 'y2': p.top }),通过为canvas添加元素移动判定canvas.on('object:moving',根据移动重新设定线段的绘制坐标。在canvas画布上绘制多个圆形,并添加连接线,图形移动,线自动跟随移动。查看fabic文档,Stickman火柴人demo完美适应。变形使用:(仅为逻辑,请自行编写判定逻辑)
·
需求:在canvas画布上绘制多个圆形,并添加连接线,图形移动,线自动跟随移动。类似于拓扑关系。
查看fabic文档,Stickman火柴人demo完美适应。官网具体代码如下:
(function() {
var canvas = this.__canvas = new fabric.Canvas('c', { selection: false });
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
function makeCircle(left, top, line1, line2, line3, line4) {
var c = new fabric.Circle({
left: left,
top: top,
strokeWidth: 5,
radius: 12,
fill: '#fff',
stroke: '#666'
});
c.hasControls = c.hasBorders = false;
c.line1 = line1;
c.line2 = line2;
c.line3 = line3;
c.line4 = line4;
return c;
}
function makeLine(coords) {
return new fabric.Line(coords, {
fill: 'red',
stroke: 'red',
strokeWidth: 5,
selectable: false,
evented: false,
});
}
var line = makeLine([ 250, 125, 250, 175 ]),
line2 = makeLine([ 250, 175, 250, 250 ]),
line3 = makeLine([ 250, 250, 300, 350]),
line4 = makeLine([ 250, 250, 200, 350]),
line5 = makeLine([ 250, 175, 175, 225 ]),
line6 = makeLine([ 250, 175, 325, 225 ]);
canvas.add(line, line2, line3, line4, line5, line6);
canvas.add(
makeCircle(line.get('x1'), line.get('y1'), null, line),
makeCircle(line.get('x2'), line.get('y2'), line, line2, line5, line6),
makeCircle(line2.get('x2'), line2.get('y2'), line2, line3, line4),
makeCircle(line3.get('x2'), line3.get('y2'), line3),
makeCircle(line4.get('x2'), line4.get('y2'), line4),
makeCircle(line5.get('x2'), line5.get('y2'), line5),
makeCircle(line6.get('x2'), line6.get('y2'), line6)
);
canvas.on('object:moving', function(e) {
var p = e.target;
p.line1 && p.line1.set({ 'x2': p.left, 'y2': p.top });
p.line2 && p.line2.set({ 'x1': p.left, 'y1': p.top });
p.line3 && p.line3.set({ 'x1': p.left, 'y1': p.top });
p.line4 && p.line4.set({ 'x1': p.left, 'y1': p.top });
canvas.renderAll();
});
})();
我在vue项目中使用,变形如下:
<template>
<div class="dashboard-container" @contextmenu.prevent>
<canvas id="editorCanvas" ref="canvas" style="margin-top: 10px;" />
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import { getMapList } from '@/api/table'
// import fabric from 'fabric'
let canvas = ''
export default {
name: 'Dashboard',
computed: {
...mapGetters([
'name'
])
},
data () {
return {
width: window.innerWidth,
height: window.innerHeight,
activeEl: {}// 获取当前点击元素
}
},
mounted () {
canvas = new fabric.Canvas('editorCanvas', {
width: this.width,
height: this.height,
selection: false,
backgroundColor: '#ffffff',
transparentCorners: false,
fireRightClick: true, // 启用右键,button的数字为3
stopContextMenu: true // 禁止默认右键菜单
})
var line = this.makeLine([250, 125, 250, 175])
var line2 = this.makeLine([250, 175, 250, 250])
var line3 = this.makeLine([250, 250, 300, 350])
var line4 = this.makeLine([250, 250, 200, 350])
var line5 = this.makeLine([250, 175, 175, 225])
var line6 = this.makeLine([250, 175, 325, 225])
canvas.add(line, line2, line3, line4, line5, line6)
canvas.add(
this.makeCircle(line.get('x1'), line.get('y1'), null, line),
this.makeCircle(line.get('x2'), line.get('y2'), line, line2, line5, line6),
this.makeCircle(line2.get('x2'), line2.get('y2'), line2, line3, line4),
this.makeCircle(line3.get('x2'), line3.get('y2'), line3),
this.makeCircle(line4.get('x2'), line4.get('y2'), line4),
this.makeCircle(line5.get('x2'), line5.get('y2'), line5),
this.makeCircle(line6.get('x2'), line6.get('y2'), line6)
)
canvas.on('object:moving', function (e) {
var p = e.target
p.line1 && p.line1.set({ 'x2': p.left, 'y2': p.top })
p.line2 && p.line2.set({ 'x1': p.left, 'y1': p.top })
p.line3 && p.line3.set({ 'x1': p.left, 'y1': p.top })
p.line4 && p.line4.set({ 'x1': p.left, 'y1': p.top })
canvas.renderAll()
})
},
methods: {
makeCircle (left, top, line1, line2, line3, line4) {
var c = new fabric.Circle({
left: left,
top: top,
strokeWidth: 5,
radius: 12,
fill: '#fff',
stroke: '#666',
originX: 'center',
originY: 'center'
})
c.hasControls = c.hasBorders = false
c.line1 = line1
c.line2 = line2
c.line3 = line3
c.line4 = line4
return c
},
makeLine (coords) {
return new fabric.Line(coords, {
fill: 'red',
stroke: 'red',
strokeWidth: 5,
selectable: false,
evented: false, originX: 'center',
originY: 'center'
})
}
}
}
</script>
<style lang="scss" scoped>
</style>
效果如图(随便拖动一点移动,关联线自动跟随):
分析:最核心代码为set({ 'x2': p.left, 'y2': p.top }),通过为canvas添加元素移动判定canvas.on('object:moving',根据移动重新设定线段的绘制坐标。
变形使用:(仅为逻辑,请自行编写判定逻辑)
canvas.on('object:moving', function (e) {
var p = e.target
if (....) { /* 判定我移动的元素是点 ,即是移动会改变关联的元素*/
canvas.forEachObject(function (object) {
if(....){ /* 定位到关联的线 */
object.set({ 'x1': p.left, 'y1': p.top })
}
})
}
})
更多推荐
已为社区贡献1条内容
所有评论(0)