有没有人曾尝试为Fabric.js创建一个自定义形状类,它是形状的组合?我想创建一个类似尺子的东西,左右两端是垂直线,并连接到中间,| --- | 。 我还想在这个统治者的中心跟随一个文本框。两端还应具有重新定位的能力。 我没有上课就完成了这个,但它不会保存或加载,因为我从多个形状制作了我的版本。 任何人都有任何想法,如果可以创建这样的自定义形状?
以下是我从前一段时间发现的另一个例子中提取的一些代码示例。创建3条线来组成我的标尺。如果我导出画布数据,我将获得数据重新创建为3行,所以如果我清除画布并重新加载这些数据,我将得到我的3行,但它们将是独立的3行。我想我需要弄清楚如何保存他们的关系,这样他们可以在重新加载时保留他们的标尺行为。我认为最好的方法是创建一个带有“标尺”类型的自定义形状。
window.onload = function() {
var canvas;
var started = false;
var mode = 0;
var lastX = 0;
var lastY = 0;
canvas = new fabric.Canvas('c');
canvas.isDrawingMode = false;
canvas.isTouchSupported = true;
canvas.selection = false;
canvas.on("mouse:down", function(option) {
if (mode === 1) {
var mouse = canvas.getPointer(option.e);
lastX = mouse.x;
lastY = mouse.y;
started = true;
var ln = new fabric.Line([lastX, lastY, lastX, lastY], {
fill: 'red',
stroke: 'red',
strokeWidth: 4,
originX: 'center',
originY: 'center',
lockScalingX: true,
lockScalingY: true,
lockRotation: true,
hasBorders: false,
hasControls: false,
perPixelTargetFind: true
});
var rAnchor = new fabric.Line([lastX - 20, lastY, lastX + 20, lastY], {
fill: 'red',
stroke: 'red',
strokeWidth: 4,
originX: 'center',
originY: 'center',
lockScalingX: true,
lockScalingY: true,
lockRotation: true,
hasBorders: false,
hasControls: false,
perPixelTargetFind: true
});
var tip = new fabric.Line([lastX - 20, lastY, lastX + 20, lastY], {
fill: 'red',
stroke: 'red',
strokeWidth: 4,
originX: 'center',
originY: 'center',
lockScalingX: true,
lockScalingY: true,
lockRotation: true,
hasBorders: false,
hasControls: false,
perPixelTargetFind: true
});
tip.line = ln;
rAnchor.line = ln;
ln.tip = tip;
ln.rAnchor = rAnchor;
canvas.add(ln);
canvas.add(rAnchor);
canvas.add(tip);
canvas.setActiveObject(ln);
canvas.renderAll();
}
});
canvas.on("mouse:move", function(e) {
if (!started) {
return false;
}
var mouse = canvas.getPointer(e.e);
var line = canvas.getActiveObject();
line.set('x2', mouse.x).set('y2', mouse.y);
var tip = line.get('tip');
tip.set('left', mouse.x).set('top', mouse.y);
var rAnchor = line.get('rAnchor');
// Get the angle for pointing the tip at the mouse location.
var rad = Math.atan2((line.y1 - line.y2), (line.x1 - line.x2));
var ang = rad * (180 / Math.PI);
tip.set('angle', (ang - 90));
rAnchor.set('angle', (ang - 90));
line.setCoords();
tip.setCoords();
rAnchor.setCoords();
canvas.renderAll();
});
canvas.on("mouse:up", function() {
if (started) {
started = false;
}
canvas.discardActiveObject();
canvas.renderAll();
});
// Event Handler for Drawn Object move
canvas.on('object:moving', function(e) {
var p = e.target;
// move line
if (p.tip) {
var oldCenterX = (p.x1 + p.x2) / 2;
var oldCenterY = (p.y1 + p.y2) / 2;
var deltaX = p.left - oldCenterX;
var deltaY = p.top - oldCenterY;
p.tip.set({
'left': p.x2 + deltaX,
'top': p.y2 + deltaY
}).setCoords();
p.rAnchor.set({
'left': p.x1 + deltaX,
'top': p.y1 + deltaY
});
p.set({
'x1': p.x1 + deltaX,
'y1': p.y1 + deltaY
});
p.set({
'x2': p.x2 + deltaX,
'y2': p.y2 + deltaY
});
p.set({
'left': (p.x1 + p.x2) / 2,
'top': (p.y1 + p.y2) / 2
});
}
// move tip
if (p.line) {
var tip = p.line.tip;
var rAnchor = p.line.rAnchor;
p.line.set({
'x2': tip.left,
'y2': tip.top,
'x1': rAnchor.left,
'y1': rAnchor.top
});
// Get the angle for pointing the tip at the mouse location.
var rad = Math.atan2((p.line.y1 - p.line.y2), (p.line.x1 - p.line.x2));
var ang = rad * (180 / Math.PI);
tip.set('angle', (ang - 90));
rAnchor.set('angle', (ang - 90));
tip.setCoords();
rAnchor.setCoords();
p.line.setCoords();
}
canvas.renderAll();
});
// Button Event Handlers
document.getElementById("btnEdit").addEventListener("click", function(e) {
mode = 0;
});
document.getElementById("btnArrow").addEventListener("click", function(e) {
mode = 1;
});
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.17/fabric.min.js"></script>
<canvas style="border: 2px solid; " height="500" width="600" id="c"></canvas>
<button id="btnEdit">Edit</button>
<button id="btnArrow">Ruler</button>