Fabric.js dynamically adds / removes items

I started working with the Fabric.js library, browsing through several libraries to find out what works best for what I need to do, and finally select Fabric.js (also tried with Paper.js or Chars.js or Raphael.js )

I'm still struggling with the problem of trying to dynamically add / remove segments in Path (I selected Path elements because I found that this is the best option for it to work, but also works fine with the Polyline element), but this cannot be done.

This is part of the code:

function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min);
}

//Seteo un array para todos los canvas que va a tener el grafico
var canvas= Array();

//Seteo un array para lineas guias que va a tener el grafico
var guias= Array();

//Seteo un array con todos los colores posibles
var color=Array();

//Seteo un array para todas las variables / lineas que va a tener el grafico
var graficos= Array();

var polyline= Array();

//Seteo un array para todas las variables / puntos que va a tener el grafico
var points= Array();

//Capturo todos los elementos canvas de la clase especifica
var Ocanvas;

//Capturo el evento de Drag&Drop
var isDragging=false;
var dragPoints={x:0,y:0};

//Se generan random un cantidad X de colores (cantidad= variable total)
for(var c=0;c <= 500; c++){
    var rojo=getRandomInt(0,155);
    var azul=getRandomInt(0,155);
    var verde=getRandomInt(0,155);
    transparencia=getRandomInt(5,10)/10;
    color[c]="rgba("+rojo+","+verde+","+azul+","+transparencia+")";
}

//Seteo el total de elementos que deseo mostrar en cada canvas (siempre tomar en cuenta que comienza desde 0 a contar)
var total=3;

//Seteo el nro de elemento inicial de cada Path
var iPath=0;

</script>
<script type="text/javascript">
jQuery(document).ready(function(){
    //Capturo todos los elementos canvas de la clase especifica
    Ocanvas=jQuery("canvas.canvas-basic");

    //Obtengo el ancho de las columnas de canvas
    var OriginalWidth=parseInt(Ocanvas.innerWidth());

    //Obtengo el alto de las columnas de canvas
    var OriginalHeight=parseInt(Ocanvas.innerHeight());

    var actual_zoom=0;

    //Defino el valor del ancho de las lineas de los graficos
    var Vstroke=2.5;

    //var canvas_color = color[getRandomInt(0,500)];
    var canvas_color="#E6E6E6";

    jQuery.each(Ocanvas, function(i, v){

        var aux_id = jQuery(this).attr("id");

        canvas[i] = new fabric.Canvas(aux_id, {
            containerClass:"canvas-conteiner",
            backgroundColor: canvas_color,
            renderOnAddRemove:false,
            width: OriginalWidth,
            height: OriginalHeight,
            selection:false,
            stateful: false,
        });

        //Creo una linea con 2 pixeles mas de largo para que 
        guias[i] = new fabric.Line([0,-1, OriginalWidth+2, -1],{
            top:OriginalHeight,
            left:-1, //muevo la linea a la posicion -1 para evitar que queden espacios entre los canvas
            strokeWidth:0.5,
            stroke: "#f00",
            lockMovementY: true,
            lockRotation: true,
            selectable: false,
            //stroke: color[getRandomInt(0,500)],
        });

        canvas[i].add(guias[i]);

        canvas[i].labelGuia=new labelGuia({
            backgroundColor: color[getRandomInt(0,500)],
        });

        canvas[i].add(canvas[i].labelGuia);
    });

    canvas.renderAll();

    //Agrego funcionamiento al evento de movimiento del mouse
    jQuery("body").delegate(".upper-canvas.canvas-basic", "mousemove", event, function(obj){

        if(isDragging){
            jQuery(this).addClass("cursor-move");
        }

        var strokeColor=color[getRandomInt(0,500)];

        //alert(strokeColor);

        //var index= jQuery(this).parents(".col-canvas").attr("data-index");

        if(canvas.getZoom()>1){
            obj.offsetY= (obj.offsetY / canvas.getZoom());
        }

        lastmove=0;

        lastpositionY=obj.offsetY+lastmove;
        var valY=lastpositionY;

        guias.set({
            opacity:1,
            top:valY,
            stroke:"#000",
        }); 

        guias.bringToFront();

        canvas.renderAll();
    });

    jQuery("body").delegate(".upper-canvas.canvas-basic", "mousedown", event, function(e){
        isDragging=true;
        dragPoints.x = e.offsetX;
        dragPoints.y = e.offsetY;
        jQuery(this).css("cursor","move");
    });

    jQuery("body").delegate(".upper-canvas.canvas-basic", "mouseup", event, function(e){
        if( dragPoints.x != e.offsetX && dragPoints.y != e.offsetY){
            //console.log("isDragging x0:"+ dragPoints.x+" y0:"+ dragPoints.y + " / x1:"+e.offsetX+" y1:"+e.offsetY);
            var posX=graficos.get("top");
            var moveX=posX + (e.offsetY-dragPoints.y);
            graficos.set({
                top: moveX,
            });

            canvas.renderAll();
        }
        jQuery(this).removeClass("cursor-move");
        isDragging=false;
    });

    //Agrego funcionamiento al evento de la "rueda" del mouse
    jQuery(".upper-canvas.canvas-basic").on("mousewheel", function (e) {
        var strokeWidthWheel=1;

        var delta = (e.originalEvent.wheelDelta / 1200);
        var pointer=e;

        var actual_points={
            x:e.offsetX, 
            y:e.offsetY,
        };

        var movePoints={ 
            x:e.offsetX,
            y:e.offsetY+50
        }

        lastpositionY=pointer.offsetY / canvas.getZoom();

        var valY=lastpositionY;

        delta=Math.round(delta * 100) /100; //Esto esta hecho asi para que el valor quede con 2 decimales nada mas.

        actual_zoom= Math.round( canvas.getZoom() * 100) /100;

        if(delta < 0 && (actual_zoom + delta) > 1){
            //canvas.zoomToPoint(actual_points, actual_zoom+delta);
            //canvas.setZoom(actual_zoom+delta);
            canvas.zoomToPoint(movePoints, actual_zoom+delta);
            graficos.setScaleY(actual_zoom+delta);
            //graficos.setOriginX(actual_points.x);
            strokeWidthWheel= guias.get("strokeWidth")+delta;
        }else if(delta > 0){
            //canvas.setZoom(actual_zoom+delta);
            canvas.zoomToPoint(movePoints, actual_zoom+delta);
            graficos.setScaleY(actual_zoom+delta);
            //graficos.setOriginX(actual_points.x);
            strokeWidthWheel= guias.get("strokeWidth")-delta;
        }           

        if(strokeWidthWheel<0.5){
            strokeWidthWheel=0.5;
        }

        guias.set({
            opacity:1,
            top:valY,
            strokeWidth: strokeWidthWheel,
        });

        //console.log(canvas[0]);

        if((actual_zoom + delta) == 1){
            canvas.zoomToPoint({x:0,y:0}, 1);
            graficos.set({top:-1});
            guias.set({
                left:-1
            });
            canvas.setCoords();
            canvas.fxCenterObjectV();
        }

        canvas.renderAll();
    });

    var xCount=0;

    //Genero graficos de forma aleatoria 
    jQuery.each(canvas, function(i, v){
        for(var j=0; j< total; j++){
            var pos_j=j%total;
            var posX=getRandomInt(50,65)*(pos_j+1);
            var posY=0;             

            graficos[xCount] = new fabric.Path("M "+posX+",-1 L "+posX+","+posY
                , {
                    strokeWidth: Vstroke,
                    stroke: color[getRandomInt(0,500)],
                    originX: 'left',
                    //originY: 'top',
                    left:posX,
                    top:0,
                    opacity:1,
                    hasBorders:false,
                    backgroundColor: "transparent",
                    fill: "transparent",
                    lockScalingX:true,
                }
            );

            graficos[xCount].posicionY=posY;

            graficos[xCount].posicionX=posX;

            points[xCount]=Array();

            canvas[i].add(graficos[xCount]);

            //Beta Test use Polyline instead of Path
            polyline[xCount] = new fabric.Polyline( [ {x: posX, y: posY } ]
                , {
                    strokeWidth: Vstroke,
                    stroke: color[getRandomInt(0,500)],
                    originX: 'left',
                    //originY: 'top',
                    left:posX,
                    top:0,
                    opacity:1,
                    hasBorders:false,
                    backgroundColor: "transparent",
                    fill: "transparent",
                    lockScalingX:true,
                }
            );

            canvas[i].add(polyline[xCount]);

            xCount++;
        }
    });

});
var itemToRemove=0;

var oldPath=Array();

function cachePath(init, max, ar){
    if(ar instanceof Array){
        var len=ar.length;
        if(len>0){
            if(init < max){

            }else{
                return false;   
            }
        }else{
            return false;
        }
    }else{
        return false;
    }
}

var CONST_escale=25;

window.setInterval(function(){

    for(var j=0; j < graficos.length; j++){
        graficos[j].posicionY=graficos[j].get("minY")+iPath*CONST_escale;
        //graficos[j].path[iPath]=Array("L", graficos[j].posicionX, graficos[j].posicionY);
        polyline[j].points[iPath]={x:graficos[j].posicionX, y:graficos[j].posicionY};
        //graficos[j].posicionY = graficos[j].posicionY + 1;
        //points[j][iPath]={ x: graficos[j].posicionX, y: graficos[j].get("minY")+iPath};

        //console.log("posY:"+parseInt(graficos[j].posicionY) +" - Height: "+ parseInt(canvas.getHeight()));

        if( parseInt(graficos[j].posicionY) > parseInt(canvas.getHeight()) ){
            //graficos[j].setTop(graficos[j].get("top") - 1);
            graficos[j].setTop(graficos[j].get("top") - CONST_escale);
            if(iPath>=10){
                //graficos[j].set({stroke:color[getRandomInt(0,500) ] } );
                //polyline[j].points.splice(iPath-10,1);
                polyline[j].points[iPath-10]=null;
                //polyline[j].points[iPath].set({stroke:color[getRandomInt(0,500) ] } );
                //points[j].splice(itemToRemove,1);
                //itemToRemove++;
                //console.log("points["+j+"]:"+points[j].length);
                //graficos[j].path.shift();
                //graficos[j].path[0][0]="M";
                //console.log(graficos[j].path[0][0]);
            }
        }

        if(iPath==100*itemToRemove){
            //var oldPath[j][itemToRemove]=graficos[j].path.splice(100, graficos[j].path.length-100);
            //graficos[j].path=graficos[j].path.splice(itemToRemove,100);
            //itemToRemove++;
            //console.log("points["+j+"]:"+points[j].length);
            //graficos[j].path.shift();
            //graficos[j].path[0][0]="M";
            //console.log(graficos[j].path[0][0]);
            itemToRemove++;
        }

        if(canvas[j] != undefined ){
            //console.log(canvas[j].labelGuia);
            canvas[j].labelGuia.updateText("label: "+ iPath * CONST_escale * j);
        }
    }

    if( (iPath % 1) == 0 ){
        for(var j=0; j < graficos.length; j++){
            var rand=getRandomInt(-65,65);
            var pos_j=j%total;
            var pos_X=65*(pos_j+1) + rand;
            graficos[j].posicionX = pos_X;
            var pos_Y=graficos[j].get("minY")+iPath;

            graficos[j].path[iPath]=Array("L", pos_X, pos_Y*CONST_escale);

            points[j][iPath]=Array();
            points[j][iPath][0]=graficos[j].posicionX;
            points[j][iPath][1]=graficos[j].get("minY")+iPath;
        }
    } 

    iPath++;

    canvas.renderAll();
},500);

http://jsfiddle.net/17ueLva2/17/

4 Canvas ( , / Canvas), 1 4 ( , , x ). , , 3 .

, , , ( 4 6 , 1/2 1 ), , (, 300 , - 500 , reamins 500px).

Javascript shift splice. .

, , , - .

, , , 2 10 , "" .

, / - , , .

, .

.

+4
1

. , , , , . , , . .

Javascript , . , , 6 .

, , . , , , , ( , , , ), , ( 20000 200 ). 100 200 , , max, .)

, , , , , - , . (10 ) . () , , , .

, , . .

+1

Source: https://habr.com/ru/post/1613483/


All Articles