clearRect does not clear the canvas when drawing vertical lines - javascript

I hit a weird edge case building something with canvas at work. clearRect does not clear the canvas when drawing vertical lines that go from the top to the bottom of the canvas. When rendering other stuff, clearRect works fine.
I'm not sure if I am missing something obvious, if this is intentional behavior, or a browser bug (unlikely since the behavior is identical in chrome, safari, firefox and opera on mac).
If it is intentional behavior, does anybody know the rationale behind it and/or can perhaps point to some documentation?
I made a small test case that shows the behavior clearly, only the combination clearRect/vertical lines does not clear the canvas:
http://jsfiddle.net/kZj6F/
Thanks!

Your issue is with a missing beginPath causing subsequent lines to be added to the same path that was stroke drawing all lines.
If you switch to dots and back to lines with the clearRect option choose you can see the last arc added to the path being drawn too. Just add a call ctx.beginPath(); prior ctx.moveTo(randomX + 0.5, 0); ctx.lineTo(randomX + 0.5, canvas.height); and the problem is solved.
You can check http://jsfiddle.net/kZj6F/1/ to see it working.
Bwt it will with other shapes too if they got added to the path and the path was not cleared.

Related

Ag-charts canvas zoom bug

I would like to comment on my problem in case someone has an idea of what it is due to or proposes an alternative solution.
Currently I have a large ag-charts graph that does not fit and it is always necessary to scroll to be able to see it in its entirety but when scrolling the axes are not maintained, so I resorted to the alternative of cloning the graph canvas twice to generate 2 new canvas clipped with "position:fixed" so that they always stay at the ends.
So far there is no problem except that if the browser zoom and/or the windows scale differs from 100%, it affects the cropping of said canvas in an inconsistent way. I was not able to get a rule of 3 to apply the correct zoom multiplier ( with ctx.drawImage() ) due to its inconsistency.
The error stops happening when you test it with a normal canvas that has not been generated by ag-charts
Here I have a very simple Live Demo to test it.
(To reproduce the bug you need to have the zoom applied before the generation of the graph).
I also tried to get the zoom level using:
(Math.round(window.devicePixelRatio*100)/100, -1);
and applying the correspondent ratio using:
.drawImage(canvas,0, 0, canvas.width*ratio, canvas.height*ratio);
but it only works in specific percentages of zoom

anti aliasing issue with the width of SVG element path

I am using the D3 to draw a line chart. However I found the lines with lower slope(flat) is thinner than the lines with higher slope(steep), I guess this is because of anti aliasing is working?
The width is a fixed number, and the zooming are controlled by transform and scale.
When the line is horizontal (almost parallel to x axis), then it become impossible to see in chrome and firefox, and in safari, it is still discoverable.
I tried using every combination of different option in shape-rendering and vector-effect. Doesn't seem to change the situation.
The constant width of that path no matter how steep it is.
Here is the overview:
Zoom a little bit in chrome:
Zoom in further more, then you can see some line are missing.
However safari can still show the line, although the width is still changing as slope changes
The same drawing codes for a different datasets which shows the exact problem, inconsistent width.
Any suggestion or link would be great, thanks!
Thanks for viewing this question and answer. I just found the solution for my own problem.
What I am trying to do here is building a zoomable line chart.
The problem is the scale transform also squash the width of horizontal (or nearly horizontal) lines.
So the solution is, vector-effect set to non-scaling-stroke. And don't change the width of the path while zooming.
And that's it.

How to avoid unwanted fill opacity changes of circle markers in canvas element when zooming in and out?

I am experiencing some strange behaviour of fill opacity settings. This happens on Circle and semi-Circle markers. FillOpacity is not set explicitly and is using default values.
My scenario is described below (simplified version can be tested in following JS Bin
I am having more than 100k semiCircles, which are defined in a canvas element for faster rendering.
For each zoom level bigger than 10 different radii are defined, so that to have a readable map. The higher the zoom, the smaller the radius. After "zoomend" event is fired, the current zoom is defined and the corresponding radius is set to the circle with:
layerSites1.eachLayer(function(layer) {
return layer.setRadius(rad1);
});
After zooming in (usually to the maximum) and when I start zooming out the density of fillOpacity changes - it becomes darker. This can be fixed even with the smallest move of the map. Sometimes the complete circle is with darker fillOpacity, sometimes just a part of it. Below you can find examples for both cases:
The above mentioned JS Bin example can be tested - the change of fillOpacity is more visible on the red circles. You need to fully zoom in and then zoom out, so that to observer the effect. If this does not happen the first time, try again to zoom in and then zoom out.
I will be grateful for any suggestion whether I am doing something wrong or it is an issue of browser rendering, or something else. I tested it with Chrome, Chromium, IE and Firefox.
Thank you!
It seems there's a timing issue between zoomend events and the actual redrawing of the canvas. Maybe an issue worth raising on GitHub, but in the meantime, letting the call stack clear and only then setting the radius seems to do the trick:
setTimeout(function() {
layerSites1.eachLayer(function(layer) {
return layer.setRadius(rad1);
});
}, 0);
Here's an updated JsBin

SVG animations artifacts on Safari

I'm using d3.js to do some svg layout/animations and am running into the problem described by the first example here (only on Safari / Safari mobile):
http://www.mysparebrain.com/svgbug.html
(e.g., when the rect+text moves, it leaves rendering artifacts in its path)
Does anyone know of a workaround for this?
The only similar question on SO I could find is this unanswered one:
Canvas draws artifacts in Safari for animated, filled bezier curves
You should definitely file a WebKit bug report on this. You've already reduced it to a very clear test case, so that should make it easier for someone to fix it.
Anything that forces a redraw based on horizontal positioning seems to fix it. I noticed just by switching to another tab and back caused it to redraw. What about doing a reposition of the content area, e.g., move right 1px then left 1px, to force a redraw? It's not pretty, but it's better than artifacts.

Google Chrome - context.canvas.width/context.canvas.width causes "Blue layer"

I upgraded from Chrome version 17 to Chrome: 18.0.1025.142 today.
I've noticed one of the web apps I am working on has a strange blue layer that appears on load and then vanishes when you start scrolling.
I've tracked this down to the following lines in my JS:
context.canvas.width = canWidth;
context.canvas.height = canHeight;
canWidth and canHeight are generated dynamically.
Commenting these lines out stops the blue layer from rendering, however this isn't a fix as I need to use the dynamically generated values to control the canvas width/height.
I also attempted hard coding the context.canvas.width and context.canvas.height to 600 and this also generated the blue layer issue.
This wasn't a problem on previous versions of Chrome, and I don't have any problems in FireFox.
Any suggestions on what the issue might be?
Edit:
Here is the block of code where the above resides (nodeLeft and nodeTop are generated else where):
context.clearRect ( 0 , 0 ,canWidth, canHeight );
context.canvas.width = canWidth;
context.canvas.height = canHeight;
context.beginPath();
context.moveTo(x, y);
context.lineTo(nodeLeft, nodeTop);
context.strokeStyle = "#000000";
context.lineCap = "round";
context.stroke();
Can you post more code than the two lines you've provided? I believe it's something more than where you've set the width/height.
I have a drawing application that I've been tinkering with on and off for a while in which I do very much the same thing. The only difference is that I call context.scale(0,0); before setting the width and height. I have no issues in any version of Google Chrome with a blue overlay. Are you possibly modifying the context's scale value before setting the width and height?
e.g. here's what I have, setting the canvas to document width/height for a full-document drawing area:
context.scale(0,0);
context.canvas.width = $(document).width();
context.canvas.height = $(document).height();
edit: my tinkering site mentioned is at http://drawcomix.com if you want to test the blue overlay to see if it's your browser or your code.
edit: based on your additional comment...
I've seen tutorials on the web that suggest the best way to clear the canvas is to set the height/width. That's not entirely true. On document load, it may be the quickest/easiest way to do so, but on mouse movements, you're probably better off doing something like this:
context.save();
context.setTransform(1,0,0,1,0,0);
context.clearRect(0,0,width,height); // width/height of canvas
context.restore();
You may not need setTransform if you're not performing any transformations on the canvas.
I believe I found this solution in Pro HTML5 Programming (Apress), but I'm not sure.
EDIT:
Ok, I got it for me. It seems to be a problem with some AMD graphic cards. I could turn off the high performance mode for chrome in the catalyst control center. That fixed most of the annoying things for me...hope that it'll be fixed in the next versions.
For mor information see: http://code.google.com/p/chromium/issues/detail?id=121658
This is not a solution, but I'm facing the same problem and it's driving me nuts. I'm trying to nail it down. I've tested differnt browser on different machines:
Problems:
Blue layers (I only see them if Chrome is NOT maximized)
Misplaced y scrollbar (sometimes only shows up if I switch through the tabs)
Distorted shapes. The size of the canvas and the drawed images / shapes vary from chrome to other browser. Means, the canvas / shapes is smaller on Chrome, it mostly shrinks the width.
Conclusion 1:
It seems that it does not happen on every machine with Chrome 18.x.x. Seems to be a hardware issue, but couldn't constrain it futher actually.
Conclusion 2:
If i set the size of the canvas to 200 height/width, the problems don't appear. If I set it higher than 200, it will deform the canvas / rectangle and other problems appear.
Conclusion 3:
The problems show only up if something is drawed to the canvas or something is set, i.e. fillStyle.
Here the test snippets I used:
<canvas id="canvas" width="300" height="300" style="background-color:orange"></canvas>
...
ctx.fillRect (10, 10, 55, 50);

Categories

Resources