Fabric JS: мне нужно удалить инструмент с квадратной изогнутой стрелкой после его создания на холсте

#javascript #jquery #canvas #fabricjs

#javascript #jquery #холст #fabricjs

Вопрос:

Я пытаюсь создать инструмент с квадратной изогнутой стрелкой.

Я использовал демонстрацию по следующей ссылке для создания инструмента. http://kpomservices.com/oldweb/HTML5_Canvas_Curved_Lines.php

мне удалось создать инструмент, который мне нужен. но у меня возникают некоторые проблемы с этим. Надеюсь, что кто-нибудь здесь сможет мне помочь в этом вопросе… вот код, который я использую для создания инструмента..

         line_number  ;
        var line;
        var reinit_stroke = "";

        fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
        function _getQBezierValue(t, p1, p2, p3) {
            var iT = 1 - t;
            return iT * iT * p1   2 * iT * t * p2   t * t * p3;
        }

        function getQuadraticCurvePoint(startX, startY, cpX, cpY, endX, endY, position) {
            return {
                x: _getQBezierValue(position, startX, cpX, endX),
                y: _getQBezierValue(position, startY, cpY, endY)
            };
        }
        canvas.on({
            'object:selected': onObjectSelected,
            'object:moving': onObjectMoving,
            'before:selection:cleared': onBeforeSelectionCleared
        });

        (function drawQuadratic() {

            line = new fabric.Path('M 65 0 Q 100, 100, 200, 0', { fill: '', selectable: false,hasBorders: false,hasControls: false,stroke: #000});

            line.path[0][1] = posx;
            line.path[0][2] = posy;

            line.path[1][1] = posx 50;
            line.path[1][2] = posy 50;

            line.path[1][3] = posx 100;
            line.path[1][4] = posy 100;


            line.id = line_number;

            //line.selectable = false;
            canvas.add(line);

            canvas.sendBackwards(line);

            var pt = getQuadraticCurvePoint(line.path[0][1], line.path[0][2], line.path[1][1], line.path[1][2], line.path[1][3], line.path[1][4], 0.5);
            var p1 = makeCurvePoint(pt.x, pt.y, null, line, null)
            p1.name = "p1";
            p1.id = line_number;
            canvas.add(p1);

            var p0 = makeCurveCircle(posx, posy, line, p1, null);
            p0.name = "p0";
            p0.id = line_number;
            canvas.add(p0);

            var p2 = makeArrow(posx 100, posy 100, null, p1, line);
            p2.name = "p2";
            p2.id = line_number;
            canvas.add(p2);

            var dx = line.path[1][3] - posx;
            var dy = line.path[1][4] - posy;

            var angle = Math.atan2(dy, dx) * 180 / Math.PI;
            p2.setAngle(angle   90);

            p2.setCoords();

            canvas.bringToFront(p2);
            canvas.bringToFront(p0);
            canvas.bringToFront(p1);

            line.p2 = p2;
        })();


        function makeArrow(left, top, line1, line2, line3) {
            var c = new fabric.Triangle({
                width: 5,
                height: 5,
                left: left 5,
                top: top 5,
                strokeWidth: 10,
                fill: #000,
                opacity: 1,
                stroke: #000
            });

            c.hasBorders = c.hasControls = false;

            c.angle = 90;

            c.line1 = line1;
            c.line2 = line2;
            c.line3 = line3;

            return c;
        }

        function makeCurveCircle(left, top, line1, line2, line3) {
            var c = new fabric.Circle({
                radius: 5,
                left: left,
                top: top,
                strokeWidth: 10,
                fill: #000,
                stroke: #000
            });

            c.hasBorders = c.hasControls = false;

            c.line1 = line1;
            c.line2 = line2;
            c.line3 = line3;

            return c;
        }

        function makeCurvePoint(left, top, line1, line2, line3) {
            var c = new fabric.Circle({
                radius: 5,
                left: left,
                top: top,
                strokeWidth: 10,
                fill: #000,
                opacity: 0,
                stroke: #000
            });

            c.hasBorders = c.hasControls = false;

            c.angle = 90;

            c.line1 = line1;
            c.line2 = line2;
            c.line3 = line3;

            return c;
        }
        var prevselobj;

        function onObjectSelected(e) {

            var activeObject = e.target;

            reinit_stroke = activeObject.stroke;

            if (activeObject.name == "p0" || activeObject.name == "p2") {

                if (prevselobj) {
                    prevselobj.line2.animate('opacity', '0', {
                        duration: 200,
                        onChange: canvas.renderAll.bind(canvas),
                    });
                    prevselobj.line2.selectable = false;
                }

                activeObject.line2.animate('opacity', '1', {
                    duration: 200,
                    onChange: canvas.renderAll.bind(canvas),
                });
                activeObject.line2.selectable = true;

                prevselobj = activeObject;

            }

        }

        function onBeforeSelectionCleared(e) {
            var activeObject = e.target;
            if (activeObject.name == "p0" || activeObject.name == "p2") {
              activeObject.line2.animate('opacity', '0', {
                duration: 200,
                onChange: canvas.renderAll.bind(canvas),
              });
              activeObject.line2.selectable = false;
            }
            else if (activeObject.name == "p1") {
              activeObject.animate('opacity', '0', {
                duration: 200,
                onChange: canvas.renderAll.bind(canvas),
              });
              activeObject.selectable = true;
            }
        }

        function onObjectMoving(e) {
            if (e.target.name == "p0" || e.target.name == "p2") {
                var p = e.target;

                var curvedline;

                if (p.line1) {
                    p.line1.path[0][1] = p.left;
                    p.line1.path[0][2] = p.top   p.height/2;
                    curvedline = p.line1;
                } else if (p.line3) {
                    p.line3.path[1][3] = p.left;

                    if(p.line3.path[0][2] <= p.line3.path[1][4])
                      p.line3.path[1][4] = p.top - p.height/2;

                    if(p.line3.path[0][2] > p.line3.path[1][4])
                      p.line3.path[1][4] = p.top   p.height/2;

                    p.line3.setCoords();

                    curvedline = p.line3;
                }

                if (curvedline) {
                    curvedline.setCoords();
                    var pt = getQuadraticCurvePoint(curvedline.path[0][1], curvedline.path[0][2], curvedline.path[1][1], curvedline.path[1][2], curvedline.path[1][3], curvedline.path[1][4], 0.5);
                    p.line2.left = pt.x;
                    p.line2.top = pt.y;

                    if (curvedline.p2) {
                        var pt = getQuadraticCurvePoint(curvedline.path[0][1], curvedline.path[0][2], curvedline.path[1][1], curvedline.path[1][2], curvedline.path[1][3], curvedline.path[1][4], 0.99);

                        curvedline.p2.left = pt.x;
                        curvedline.p2.top = pt.y;

                        var dx = curvedline.path[1][3] - pt.x;
                        var dy = curvedline.path[1][4] - pt.y;

                        var angle = Math.atan2(dy, dx) * 180 / Math.PI;
                        curvedline.p2.setAngle(angle   90);

                        curvedline.p2.setCoords();
                    }
                    p.line2.setCoords();
                }

                if (e.target.text) {
                    e.target.text.left = p.left;
                    e.target.text.top = p.top;
                    e.target.text.setCoords();
                }

            } else if (e.target.name == "p1") {
                var p = e.target;

                if (p.line2) {
                    p.line2.path[1][1] = p.left;
                    p.line2.path[1][2] = p.top;
                }

                curvedline = p.line2;

                if (curvedline) {
                    var pt = getQuadraticCurvePoint(curvedline.path[0][1], curvedline.path[0][2], curvedline.path[1][1], curvedline.path[1][2], curvedline.path[1][3], curvedline.path[1][4], 0.5);
                    p.left = pt.x;
                    p.top = pt.y;
                    p.setCoords();
                }

                if (curvedline) {
                      var pt = getQuadraticCurvePoint(curvedline.path[0][1], curvedline.path[0][2], curvedline.path[1][1], curvedline.path[1][2], curvedline.path[1][3], curvedline.path[1][4], 0.99);

                      curvedline.p2.left = pt.x;
                      curvedline.p2.top = pt.y;

                      var dx = curvedline.path[1][3] - pt.x;
                      var dy = curvedline.path[1][4] - pt.y;

                      var angle = Math.atan2(dy, dx) * 180 / Math.PI;
                      curvedline.p2.setAngle(angle   90);

                      curvedline.p2.setCoords();
                }

            } else if (e.target.name == "p0" || e.target.name == "p2") {
                var p = e.target;

                p.line1 amp;amp; p.line1.set({
                    'x2': p.left,
                    'y2': p.top
                });
                p.line2 amp;amp; p.line2.set({
                    'x1': p.left,
                    'y1': p.top
                });
                p.line3 amp;amp; p.line3.set({
                    'x1': p.left,
                    'y1': p.top
                });
                p.line4 amp;amp; p.line4.set({
                    'x1': p.left,
                    'y1': p.top
                });
            }
            p amp;amp; reinit();
        }
        function reinit() {
            canvas.remove(line);
            line = new fabric.Path(line.path, { fill: '',selectable: false });
            line.id = line_number;
            line.stroke = reinit_stroke;
            canvas.add(line);
            canvas.sendBackwards(line);
        }


        canvas.on('mouse:over', function(e) {
            if(e.target.type == "path")
            {
                canvas.sendBackwards(e.target);
            }

          });
  

Я использую следующий код для удаления инструмента.

(Примечание: этот код запускается, когда я нажимаю на кнопку удаления. Кнопка удаления удаляет выбранный объект. )

вот код…

     var objs = canvas.getObjects();

    if (activeObject) {
        active_id = activeObject.get('id');

        canvas.forEachObject(function (obj) {
            if(obj.get('id') == active_id)
            {
                if(obj.type == 'path')
                {
                    obj.selectable = true;
                    canvas.remove(obj);
                }
                canvas.remove(obj); 
            }
        });

        canvas.remove(activeObject);    
    }
  

проблема, с которой я сталкиваюсь, заключается в том, что после удаления этого, если я создам еще одну изогнутую стрелку в конструкторе (т. Е. Без перезагрузки страницы) и перемещаю узлы, тогда он все еще показывает старый объект path, который мы уже удалили.

и если я удалю вновь созданную изогнутую стрелку, то она удалит весь путь с холста, короче говоря, все объекты Path ведут себя как один (надеюсь, это понятно).).

итак, объект path не удаляется должным образом, он просто скрывается, когда я его удаляю. Или, может быть, он удален, но создан снова, когда я перемещаю другой объект path.. и если мы сохраним холст как json, тогда мы сможем увидеть объекты path, которые тоже будут удалены.

Что мне нужно сделать, так это правильно удалить объект path и сохранить только объект Path, который в данный момент отображается на холсте с узлами.

Пожалуйста, скажите мне, есть ли какое-то решение для этой проблемы..

Спасибо..

Ответ №1:

Я нашел решение проблемы с удалением кривой. Нам нужно изменить код в функциях reinit() . Он перезаписал line_id для всей строки (или, скажем, пути) на холсте. Вот код для замены на функцию reinit() ..

        function reinit() {
            var objs = canvas.getObjects();
            current_line = canvas.getActiveObject();
            canvas.forEachObject(function (obj) {
                if(obj.type == 'path' amp;amp; obj.get("id") == current_line.get("id"))
                {
                    canvas.remove(obj);
                    line = new fabric.Path(obj.path, { fill: '',selectable: false });
                    line.id = current_line.get("id");
                    line.stroke = reinit_stroke;
                    canvas.add(line);
                    canvas.sendBackwards(line);
                }               
            });

        }
  

Надеюсь, это может быть полезно для тех, кому нужно такое решение..