我正在使用FabricJS创建用于绘制特定线条和形状的画布。其中一条线是带箭头的波浪线,类似于这样:
。我已成功创建了一个带箭头末端的直线版本,但找不到如何创建波浪线的示例。用户可以画出任意长度的线条,因此线条中“峰值”和“谷值”的数量需要相应调整(像上面的图像一样短的线可能有4个峰值,而长度加倍的线将有8个峰值,不仅仅是较短线的拉伸版本)。
下面是我用来绘制带箭头末端的直线的代码。请注意,线的起点在鼠标按下时绘制,终点在鼠标松开时绘制。
![enter image description here](https://istack.dev59.com/tFw6Y.webp)
下面是我用来绘制带箭头末端的直线的代码。请注意,线的起点在鼠标按下时绘制,终点在鼠标松开时绘制。
import LineWithArrow from './LineWithArrow';
drawLineWithArrow = (item, points, color) => (
new LineWithArrow(points, {
customProps: item,
strokeWidth: 2,
stroke: color,
})
)
selectLine = (item, points) => {
switch (item.type) {
case 'line_with_arrow':
return this.drawLineWithArrow(item, points, colors.BLACK);
case 'wavy_line_with_arrow':
return this.drawWavyLineWithArrow(item, points);
// no default
}
return null;
}
let line;
let isDown;
fabricCanvas.on('mouse:down', (options) => {
isDown = true;
const pointer = fabricCanvas.getPointer(options.e);
const points = [pointer.x, pointer.y, pointer.x, pointer.y];
line = this.selectLine(item, points);
fabricCanvas
.add(line)
.setActiveObject(line)
.renderAll();
});
fabricCanvas.on('mouse:move', (options) => {
if (!isDown) return;
const pointer = fabricCanvas.getPointer(options.e);
line.set({ x2: pointer.x, y2: pointer.y });
fabricCanvas.renderAll();
});
fabricCanvas.on('mouse:up', () => {
isDown = false;
line.setCoords();
fabricCanvas.setActiveObject(line).renderAll();
});
还有LineWithArrow文件:
import { fabric } from 'fabric';
const LineWithArrow = fabric.util.createClass(fabric.Line, {
type: 'line_with_arrow',
initialize(element, options) {
options || (options = {});
this.callSuper('initialize', element, options);
// Set default options
this.set({
hasBorders: false,
hasControls: false,
});
},
_render(ctx) {
this.callSuper('_render', ctx);
ctx.save();
const xDiff = this.x2 - this.x1;
const yDiff = this.y2 - this.y1;
const angle = Math.atan2(yDiff, xDiff);
ctx.translate((this.x2 - this.x1) / 2, (this.y2 - this.y1) / 2);
ctx.rotate(angle);
ctx.beginPath();
// Move 5px in front of line to start the arrow so it does not have the square line end showing in front (0,0)
ctx.moveTo(5, 0);
ctx.lineTo(-5, 5);
ctx.lineTo(-5, -5);
ctx.closePath();
ctx.fillStyle = this.stroke;
ctx.fill();
ctx.restore();
},
toObject() {
return fabric.util.object.extend(this.callSuper('toObject'), {
customProps: this.customProps,
});
},
});
export default LineWithArrow;