JavaScript FabricJ помещает изображение в представление холста

Я хочу создать круг и форму стрелки с помощью 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();
});

Трудно помочь вам с множеством пропавших без вести в вашем коде. Можете ли вы нормализовать свой код и создать скрипку?

Observer 08.08.2018 18:06

Путь к большому количеству кода! пожалуйста, уменьшите объем до одной проблемы

Helder Sepulveda 08.08.2018 18:32

попробуйте canvas.off('mouse:down', this.onCircleMouseDown); для всего. не передавайте e в качестве аргумента, вы вызываете функцию там.

Durga 10.08.2018 11:11

@Durga привет, я пытался удалить параметр e, но получаю эту ошибку cannt read property canvas of undefinedonArrowMouseDown: function onArrowMouseDown(o) { var pointer = this.elements.canvas.getPointer(o);

Jon not doe xx 10.08.2018 16:16
canvas.off('mouse:down', this.onCircleMouseDown.bind(this))
Durga 10.08.2018 16:19

@Durga ok Ошибки исчезли, но я не получаю ни кружка, ни стрелки, если пытаюсь перетащить

Jon not doe xx 10.08.2018 16:23

попробуйте отладить, вызываются ли функции или нет.

Durga 10.08.2018 16:27

@Durge, если я выбираю инструмент и нажимаю на холст, он запускается через эту функцию onArrowMouseDown, если я отпускаю мышь, он запускает функцию showArrow, я каким-то образом не получаю никаких журналов перемещения мыши, если я нажимаю на холст и пытаюсь нарисовать круг или Стрелка

Jon not doe xx 10.08.2018 16:41
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
8
66
0

Другие вопросы по теме