Jump to content

"Clearing a canvas at the back" problem in multilayer HTML5 canvas application


eaglehopes
 Share

Go to solution Solved by eaglehopes,

Recommended Posts

I am preparing a multilayer canvas program by using HTML5. It consists of three layer of canvas elements at top of each others.

z-index 3 : axesLayer

z-index 2 : nodesLayer

z-index 1 :  edgesLayer 

When I am using mouse wheel to change the point's position(i.e. scale the graph) using event listener for top layer(axes layer), zoom function triggered. In zoom function I call clearCanvas(g). Where g is the 2D context of the canvas. However, second layer canvas could not be cleared properly. Somehow, it stores all the drawings although I cleared it. Same thing happens when I try to delete a node too. To delete a node, click the checkbox nead the node number, and press either big red - sign at the bottom, or at the X button at the same row of node under Remove title.

I noticed that, I can only trigger a mouse wheel event for the top canvas, so zoom function only triggered by axesCanvas, so zoom event is triggered by axesCanvas object.

When I used only one layer, the same code(i.e. I changed only names of the contexts, other than that code was the same) did not give any error, but when I used three layers this problem starts.

Can anybody help me about it?

You can replicate the situation : 

1. enter 100 in x and 0 in y coordinates input boxes,

2. press green colored +(plus) sign to add it to nodesLayer element's context 

3. while on the canvas at the right, use mouse wheel to scale the point's position  and you will see that, it draws continuously the track.  

My code is live at : http://www.online-mech.epizy.com/js/mtw_v3.js file and application is at :  http://www.online-mech.epizy.com

 

also related part is

var backcol = `rgba(0,0,0,0.0)`;

function clearCanvas(g) {
    g.save(); // save current state flipped about x axis
    g.fillStyle = backcol;
    g.scale(1,1);
    g.clearRect(-w/2,-h/2,w,h);
    g.fillRect(-w/2,-h/2,w,h);		
    g.restore() ; // get back to old flipped state
}

function drawActiveNodes() {  // make it more smart , if 
	// draw all nodes in nodesArray
	nodesArray.forEach((value) => {
	   value.draw();
	});
}

function zoom(event) {
	event.preventDefault();  // prevent scrolling of mouse wheel
    // make zoom in given increments 
    var increment = 60; 
    zoomFactor = 1 + Math.sign(event.deltaY)*increment * -0.0001;
    modZoomRef *= zoomFactor;
    totalZoom  = modZoomRef/zoomReference; // += Math.sign(event.deltaY)*increment * -0.0001;
  	if(nodesGraphics) { 
		// this is just for show - not real node values will be changed
		nodesArray.forEach((value) => {
			value.gx *= zoomFactor; 
			value.gy *= zoomFactor;
		});
		clearCanvas(nodesGraphics);
        drawActiveNodes();
	}
}

Thanks.

 

Edited by eaglehopes
correct mispelling , added some related functions of the code.
Link to comment
Share on other sites

I used directly the canvas' context (not sending it as a function argument) :

function clearCanvas() {
    
    
        nodesGraphics.save(); // save current state flipped about x axis
        nodesGraphics.fillStyle = backcol;
    
        nodesGraphics.scale(1,1);
        nodesGraphics.clearRect(-w/2,-h/2,w,h);  
        nodesGraphics.fillRect(-w/2,-h/2,w,h);		
        nodesGraphics.restore() ; // get back to old flipped state
      
    
}

did not work. Also when I used :

function clearCanvas(g) {
    if(g) {
        g.save(); // save current state flipped about x axis
        g.fillStyle = backcol;
        g.scale(1,1);
        g.clearRect(-w/2,-h/2,w,h);  
        g.fillRect(-w/2,-h/2,w,h);		
        g.restore() ; // get back to old flipped state
        g = null ; // nullified g, still working.... strange !
    } else { wc("clearing canvas is not possible since graphics is not ready"); }
}

Althouth I nullified the sended graphics context g, I can again use it, so javascript uses pass by copy method for function arguments.  However, in https://www.geeksforgeeks.org/pass-by-value-and-pass-by-reference-in-javascript/  it says that objects are passed by references. So why context of canvas did not pass by its reference? Any help is appreciated. Thanks.

Link to comment
Share on other sites

  • 4 months later...
  • Solution
Posted (edited)

Since, no one answers to my question, I am back with my code sample to who want to use multiple canvas layers!   My sample code :

 

<html>

<script src="code.js"></script>

<body>
<canvas id="canvas1" height="300" width="400" style="position:absolute;top:0px;left:0px;z-index:1;">
</canvas>

<canvas id="canvas2" height="300" width="400" style="position:absolute;top:0px;left:0px;z-index:2;">
</canvas>

</html>

 


window.onload=function() {
 var canvas1 = document.getElementById('canvas1'); 
 var canvas2 = document.getElementById('canvas2'); 
 var g1 = canvas1.getContext('2d');
 var g2 = canvas2.getContext('2d');
 g1.save(); // save current state
 g2.save();
    // fill 1
 g1.fillStyle='rgba(0,10,200,0.5)';
 g1.fillRect(0,0,100,100);
    // fill 2
 g2.fillStyle='rgba(0,255,0,0.5)';
 g2.fillRect(20,20,60,60);
 // restore all states
 g1.restore(); 
 g2.restore();
}

Simply I used "z-index" in style and force two canvas to be in the same position by using "position:absolute". Everything else remains to you... Edited: I attached my code's output...

multipleCanv1.jpg

Edited by eaglehopes
Add an output of my code
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.