Я хочу создать круг и форму стрелки с помощью Fabric.js, так что, например, если вы нажмете кнопку со стрелкой, можно будет нарисовать стрелку (с текущими выбранными шириной и высотой), то же самое для круга. В отношении html выглядит так:
<div class = "btn-group-toggle toolbar-left-btns" data-toggle = "buttons">
<h4 class = "h4-color-white" id = "current-shape-name" style = "display:none;"></h4>
<label class = "btn btn-secondary btn-md btn-md btn-tool-margin-left" title = "Create an arrow object" id = "drawing-arrow-shape">
<input type = "radio" name = "drawing-shape">
<i class = "fas fa-arrow-right"></i>
</label>
<label class = "btn btn-secondary btn-md btn-tool-margin-left" title = "Create a circle object" id = "drawing-circle-shape">
<input type = "radio" name = "drawing-shape">
<i class = "far fa-circle"></i>
</label>
</div>
В основном выбор, если используется форма стрелки или круга. Я не буду публиковать полный сценарий, так как он действительно длинный, в настоящее время я могу выбрать цвет и ширину кисти и рисовать на своем холсте. Это работает, так что имейте это в виду. Я просто не умею рисовать круг и стрелку. В следующей части моего скрипта я выбираю, если это стрелка или круг (выбор работает), и если выбран «рисовать» эту стрелку или круг на моем холсте, он рисует сразу после выбора комбинации между стрелкой и куб, любая идея, что мне не хватает. Я также не получаю сообщения об ошибке.
const canvasRenderer = {
render() {
this.initCanvas();
},
elements: {
...
canvas: '',
isDown: null,
circle: null,
circleOrigX: null,
circleOrigY: null,
startX: null,
startY: null,
id: {
...
drawingArrowShape: $('#drawing-arrow-shape'),
drawingCircleShape: $('#drawing-circle-shape'),
imgInput: $('#img-input'),
},
tags: {
html: $('html')
}
},
propToolRadio() {
this.elements.id.drawingArrowShape.prop('checked', false);
this.elements.id.drawingCircleShape.prop('checked', false);
this.elements.id.drawingArrowShape.parent().removeClass('active');
this.elements.id.drawingCircleShape.parent().removeClass('active');
},
recOnArrow(canvas) {
this.elements.id.drawingArrowShape.change((e) => {
canvas.isDrawingMode = false;
this.elements.id.currentShapeName.innerHTML = 'Arrow';
canvas.off('mouse:down', this.onCircleMouseDown(e));
canvas.off('mouse:move', this.onCircleMouseMove(e));
canvas.off('mouse:up', this.onCircleMouseUp(e));
canvas.on('mouse:down', this.onArrowMouseDown(e));
canvas.on('mouse:move', this.onArrowMouseMove(e));
canvas.on('mouse:up', this.onArrowMouseUp(e));
this.recCanvas(canvas);
});
},
recOnCircle(canvas) {
this.elements.id.drawingCircleShape.change((e) => {
canvas.isDrawingMode = false;
this.elements.id.currentShapeName.innerHTML = 'Circle';
canvas.on('mouse:down', this.onCircleMouseDown(e));
canvas.on('mouse:move', this.onCircleMouseMove(e));
canvas.on('mouse:up', this.onCircleMouseUp(e));
canvas.off('mouse:down', this.onArrowMouseDown(e));
canvas.off('mouse:move', this.onArrowMouseMove(e));
canvas.off('mouse:up', this.onArrowMouseUp(e));
this.recCanvas(canvas);
});
},
onArrowMouseDown(o) {
let pointer = this.elements.canvas.getPointer(o.e);
this.elements.startX = pointer.x;
this.elements.startY = pointer.y;
this.recCanvas(this.elements.canvas);
},
onArrowMouseUp(o) {
let pointer = this.elements.canvas.getPointer(o.e);
let endX = pointer.x;
let endY = pointer.y;
this.showArrow(
this.elements.startX,
this.elements.startY,
endX,
endY,
this.elements.canvas
);
this.recCanvas(this.elements.canvas);
},
onArrowMouseMove(e) {
},
onCircleMouseDown(o) {
this.elements.isDown = true;
let pointer = this.elements.canvas.getPointer(o.e);
this.elements.circleOrigX = pointer.x;
this.elements.circleOrigY = pointer.y;
if (!this.elements.circle) {
this.elements.circle = new fabric.Circle({
left: this.elements.circleOrigX,
top: this.elements.circleOrigY,
originX: 'center',
originY: 'center',
radius: 0,
fill: '',
stroke: this.elements.id.drawingColorEl.value,
strokeWidth: parseInt(this.elements.id.drawingLineWidthEl.value, 10) || 1,
selectable: true
});
this.elements.canvas.add(this.elements.circle);
}
this.recCanvas(this.elements.canvas);
},
onCircleMouseMove(o) {
console.info("onCircleMouseMove");
if (!this.elements.isDown) return;
let pointer = this.elements.canvas.getPointer(o.e);
this.elements.circle.set({
radius: Math.sqrt(
Math.pow(
(this.elements.circleOrigX - pointer.x), 2
) + Math.pow((this.elements.circleOrigY - pointer.y), 2)
)
});
this.elements.canvas.renderAll();
},
onCircleMouseUp(o) {
console.info("onCircleMouseUp");
this.elements.isDown = false;
this.elements.circle = null;
},
showArrow(fromx, fromy, tox, toy, canvas) {
console.info("showArrow");
let angle = Math.atan2(toy - fromy, tox - fromx);
let headlen = 15; // arrow head size
// bring the line end back some to account for arrow head.
tox = tox - (headlen) * Math.cos(angle);
toy = toy - (headlen) * Math.sin(angle);
// calculate the points.
let points = [{
x: fromx, // start point
y: fromy
}, {
x: fromx - (headlen / 4) * Math.cos(angle - Math.PI / 2),
y: fromy - (headlen / 4) * Math.sin(angle - Math.PI / 2)
}, {
x: tox - (headlen / 4) * Math.cos(angle - Math.PI / 2),
y: toy - (headlen / 4) * Math.sin(angle - Math.PI / 2)
}, {
x: tox - (headlen) * Math.cos(angle - Math.PI / 2),
y: toy - (headlen) * Math.sin(angle - Math.PI / 2)
}, {
x: tox + (headlen) * Math.cos(angle), // tip
y: toy + (headlen) * Math.sin(angle)
}, {
x: tox - (headlen) * Math.cos(angle + Math.PI / 2),
y: toy - (headlen) * Math.sin(angle + Math.PI / 2)
}, {
x: tox - (headlen / 4) * Math.cos(angle + Math.PI / 2),
y: toy - (headlen / 4) * Math.sin(angle + Math.PI / 2)
}, {
x: fromx - (headlen / 4) * Math.cos(angle + Math.PI / 2),
y: fromy - (headlen / 4) * Math.sin(angle + Math.PI / 2)
}, {
x: fromx,
y: fromy
}];
let pline = new fabric.Polyline(points, {
fill: 'black',
stroke: this.elements.id.drawingColorEl.value,
opacity: 1,
// strokeWidth: 2,
strokeWidth: parseInt(this.elements.id.drawingLineWidthEl.value, 10) || 1,
originX: 'left',
originY: 'top',
selectable: true
});
canvas.add(pline);
canvas.renderAll();
},
/**
* TODO on mdified, moving, rotating, scaling method to call only once
*/
recOnEvent(canvas) {
let isObjectMoving = false;
canvas.on('path:created', () => {
this.recCanvas(canvas)
});
canvas.on('object.added', () => {
this.recCanvas(canvas)
});
canvas.on('object:modified', () => {
isObjectMoving = true;
});
canvas.on('object:moving', () => {
isObjectMoving = true;
});
canvas.on('object:removed', () => {
this.recCanvas(canvas)
});
canvas.on('object:rotating', () => {
isObjectMoving = true;
});
canvas.on('object:scaling', () => {
isObjectMoving = true;
});
this.elements.id.canvasContainer.click(() => {
this.recCanvas(canvas);
});
canvas.on('mouse:up', () => {
if (isObjectMoving) {
isObjectMoving = false;
this.recCanvas(canvas); // fire this if finished
}
});
},
};
$(document).ready(() => {
canvasRenderer.render();
});
Путь к большому количеству кода! пожалуйста, уменьшите объем до одной проблемы
попробуйте canvas.off('mouse:down', this.onCircleMouseDown);
для всего. не передавайте e в качестве аргумента, вы вызываете функцию там.
@Durga привет, я пытался удалить параметр e, но получаю эту ошибку cannt read property canvas of undefined
onArrowMouseDown: function onArrowMouseDown(o) { var pointer = this.elements.canvas.getPointer(o);
canvas.off('mouse:down', this.onCircleMouseDown.bind(this))
@Durga ok Ошибки исчезли, но я не получаю ни кружка, ни стрелки, если пытаюсь перетащить
попробуйте отладить, вызываются ли функции или нет.
@Durge, если я выбираю инструмент и нажимаю на холст, он запускается через эту функцию onArrowMouseDown
, если я отпускаю мышь, он запускает функцию showArrow
, я каким-то образом не получаю никаких журналов перемещения мыши, если я нажимаю на холст и пытаюсь нарисовать круг или Стрелка
Трудно помочь вам с множеством пропавших без вести в вашем коде. Можете ли вы нормализовать свой код и создать скрипку?