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);
}
var canvas= Array();
var guias= Array();
var color=Array();
var graficos= Array();
var polyline= Array();
var points= Array();
var Ocanvas;
var isDragging=false;
var dragPoints={x:0,y:0};
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+")";
}
var total=3;
var iPath=0;
</script>
<script type="text/javascript">
jQuery(document).ready(function(){
Ocanvas=jQuery("canvas.canvas-basic");
var OriginalWidth=parseInt(Ocanvas.innerWidth());
var OriginalHeight=parseInt(Ocanvas.innerHeight());
var actual_zoom=0;
var Vstroke=2.5;
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,
});
guias[i] = new fabric.Line([0,-1, OriginalWidth+2, -1],{
top:OriginalHeight,
left:-1,
strokeWidth:0.5,
stroke: "#f00",
lockMovementY: true,
lockRotation: true,
selectable: false,
});
canvas[i].add(guias[i]);
canvas[i].labelGuia=new labelGuia({
backgroundColor: color[getRandomInt(0,500)],
});
canvas[i].add(canvas[i].labelGuia);
});
canvas.renderAll();
jQuery("body").delegate(".upper-canvas.canvas-basic", "mousemove", event, function(obj){
if(isDragging){
jQuery(this).addClass("cursor-move");
}
var strokeColor=color[getRandomInt(0,500)];
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){
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;
});
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;
actual_zoom= Math.round( canvas.getZoom() * 100) /100;
if(delta < 0 && (actual_zoom + delta) > 1){
canvas.zoomToPoint(movePoints, actual_zoom+delta);
graficos.setScaleY(actual_zoom+delta);
strokeWidthWheel= guias.get("strokeWidth")+delta;
}else if(delta > 0){
canvas.zoomToPoint(movePoints, actual_zoom+delta);
graficos.setScaleY(actual_zoom+delta);
strokeWidthWheel= guias.get("strokeWidth")-delta;
}
if(strokeWidthWheel<0.5){
strokeWidthWheel=0.5;
}
guias.set({
opacity:1,
top:valY,
strokeWidth: strokeWidthWheel,
});
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;
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',
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]);
polyline[xCount] = new fabric.Polyline( [ {x: posX, y: posY } ]
, {
strokeWidth: Vstroke,
stroke: color[getRandomInt(0,500)],
originX: 'left',
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;
polyline[j].points[iPath]={x:graficos[j].posicionX, y:graficos[j].posicionY};
if( parseInt(graficos[j].posicionY) > parseInt(canvas.getHeight()) ){
graficos[j].setTop(graficos[j].get("top") - CONST_escale);
if(iPath>=10){
polyline[j].points[iPath-10]=null;
}
}
if(iPath==100*itemToRemove){
itemToRemove++;
}
if(canvas[j] != undefined ){
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 , "" .
, / - , , .
, .
.