SVG animations artifacts on Safari - javascript

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.

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.

Zooming SVG is blury or pixelated, not sharp

vI know to some extent this is a known issue that has been asked here but never answered, but I'm hoping for some additional insight.
I have a simple SVG image in a div on a web page. I want to be able to zoom the image using pinch gestures and have the SVG render sharply. It doesn't need to be sharp during the zoom, but should be sharp after the gesture is complete.
I'm doing my testing on a Windows 8.1 computer with a touch monitor, on an iPad, and on an old Android Galaxy Tab. On the main computer, I'm using IE11 and Chrome. For handling touch gestures, I'm using Hammer.js. I'm doing the zooming by modifying the transform CSS using the jQuery css() function (I'm setting scale3d and translate3d).
IE11 on my computer works exactly like I would like it to. It keeps the SVG image sharp throughout the pinch zoom and the image is always sharp regardless of when I set the CSS.
Chrome on my computer always renders the SVG blocky when I am zoomed in using pinch zoom. It is blocky during the zoom and does not get sharp afterwards. If I add a call to zoom the image after the page (x13) is loaded, the image is sharp. If I use a setTimeout() call to reset the zoom and then rezoom the image after the pinch zoom ends, the image is sharp.
On the iPad and Android tablet, the SVG never renders sharply, regardless of when I zoom it in code.
Does anyone have any ideas of how to reliably end up with a sharp rendering of SVG after a pinch-zoom is completed? Does anyone have a better solution? Using the SVG viewBox to zoom and pan during the gesture does not provide good enough performance for our more complex SVG images. I'm thinking of attempting to use the hardware accelerated scale3d/translate3d during the gesture and then attempt to convert this to new SVG viewBox settings afterwards, but this is a challenge and I'm not sure panning will work correctly after this is done. Any pointers or ideas are greatly appreciated.
Having just tried to answer your other SVG Question I will have a try at this one.
Michael Mullany is spot on that GPU translations will never give you a sharp image. This is because the GPU just maps one array of pixels to a new one. Because it has no concept of lines or rectangles the resolution is set by the time the GPU gets the image. The CPU will always struggle to re-render in time for a smooth drag.
What happens to allow some browsers to produce a sharp image is they do clever manipulations like rendering more pixels than they need so some zooming can happen without loss of resolution. These however are completely inconsistent and just not possible to rely on.
The as I see it 'correct' solution is to translate and zoom with hardware accelerated transformations during a pinch or zoom and then to refresh the viewbox with no css transformation when the translation has finished.
Challenges to overcome are
The css transformation will use screen coordinates but the viewBox manipulation will use the SVG coordinate system.
There are browser inconsistencies in both screenCTM and device pixel ratio
limits so that people don't drag or zoom too far need to be calculated in both systems
Pinch centerpoints also need to be calculated in both
To improve performance further the css transforms will be wrapped into updating on the requestAnimationFrame loop.
My working solution is hammerhead2. I am concentrating on desktops and android mobiles first and it seams to be working for them. To simplify the problem zoom is always centered to the screen center. I do however thing this is currently one of the only solutions. Here is an example of it working.

How to work around Firefox canvas text rendering bug?

I have written a small JavaScript library to calculate text height-related metrics.
It scans canvas image data to find top and bottom points of the text.
Unfortunately due to Firefox Bug 737852 it is currently broken in Firefox -- top position is higher than it should be, which breaks fitHeight logic.
Any suggestions on how I can work around that?

Excanvas vml positioning issue

I've slogged my way through implementing excanvas on ie8. I've got the dynamic element bit sorted, the initially-hidden elements are now happily rendering throughout most of the app, and just when all seemed to be well I've hit another roadblock.
The vml items rendered inside the div that excanvas generates are all offset by a large amount.
I only discovered what was happening by setting overflow:visible on all children of canvas, which caused the offset vml to become visible.
I've got a screenshot of the offending articles; the area in blue is the generated div in the correct position, and the items bordered in red should be within the blue area.
Has anyone encountered this before, and even better, been able to solve it?
Cheers!
In case anyone ever encounters this error, it seems the issue was with a translate() call. Although I was using save and restore, and every standard implementation of canvas interpreted the translate call as I intended, in excanvas the translate was persistently additive.
I solved the issue by restoring the identity matrix before performing the other save, translate & restore calls.
context.setTransform(1,0,0,1,0,0);

Categories

Resources