Jagged canvas rendering in Chrome - javascript

I'm writing a drawing application using HTML canvas. To smooth drawn lines, I'm filling a series of quadratic curves after each mousemove event:
ctx.beginPath()
ctx.moveTo(mx1-halfLastWidth*sin(angle), my1-halfLastWidth*cos(angle))
ctx.quadraticCurveTo(mx1-lastWidth*cos(angle), my1+lastWidth*sin(angle),
mx1+halfLastWidth*sin(angle), my1+halfLastWidth*cos(angle))
ctx.quadraticCurveTo(xl+halfMidWidth*sin(angle), yl+halfMidWidth*cos(angle),
mx2+halfCurrentWidth*sin(angle), my2+halfCurrentWidth*cos(angle))
ctx.quadraticCurveTo(mx2+currentWidth*cos(angle), my2-currentWidth*sin(angle),
mx2-halfCurrentWidth*sin(angle), my2-halfCurrentWidth*cos(angle))
ctx.quadraticCurveTo(xl-halfMidWidth*sin(angle), yl-halfMidWidth*cos(angle),
mx1-halfLastWidth*sin(angle), my1-halfLastWidth*cos(angle))
ctx.fill()
Full demo: http://jsfiddle.net/PfzM2/2/ (there's a lot of irrelevant code due to this being extracted from a much larger project)
The lines render very smoothly in Firefox, but seem "jagged" in places in Chrome:
The series of commands and arguments issued to the browsers was identical.
How can I get Chrome to render the lines like Firefox?

Similar questions have been asked all over the place with respect to font rendering. It's almost certainly possibly the same root problem: anti-aliasing differences that arise from the rendering engine. Chrome, as you know, uses Webkit; FF, Gecko. Gecko seems to like anti-aliasing more than Webkit.
Chalk it up to a browser issue (the way you would typically would for IE, I reckon).
EDIT: Seems the converse is known to be true, too. Nick Heer discusses this in his blog: "due to Gecko’s more precise (and blockier) anti-aliasing, most serif faces don’t look great." Could be a platform issue.

Related

How to fix poor anti-aliasing in Firefox when using Pixi.js?

I use Pixi.js for my work project to draw simple shapes — circles and segments, and make some interaction between them. I work on Mac running El Capitan and test my prototype in Google Chrome. I use PIXI.autoDetectRenderer() method to set renderer and usually it is set to WebGL in latest browsers. I don't have any experience in WebGL, so might not know some important details.
When testing my application in Firefox I've noticed thin black border around shapes.
Turned out that antialias property set to true caused this effect:
renderer = new PIXI.autoDetectRenderer(width, height, {backgroundColor: 0xffffff, antialias: true})
I've done some investigation. On Pixi.js forums and on some other resources it's said that PIXI.Graphics() objects do not support anti-aliasing because of using the stencil buffer. On practice they do support anti-aliasing. Guess, something has changed since discussions took place.
I don't like the result I get with switched off anti-aliasing, here it is on images below.
I and my colleague had a talk about that, and we discovered that when any other graphic object lays behind, there is no black border around original one. So we added white rectangle behind other elements in case Firefox browser is used.
That solved problem of black border. Still I get far neater image in Google Chrome. There are lots of artifacts around segments and circles in Firefox.
They become more visible once elements get smaller.
In console I get following warning:
FXAA antialiasing being used instead of native antialiasing.
Is there a way to improve anti-aliasing quality in this case?

CreateJS: poor/strange framerate in Firefox

I'm at the early stage of building my own game framework, based on CreateJS (especially on the feature of exporting everything from Flash IDE). And found out that framerate of CreateJS (EaselJS) is much worse in Firefox than in Chrome/IE.
Also, it seems that the framerate of app (which might be changed using Ticker.setFPS) doens't matter. It looks like Firefox has some problems with rendering (I've tried to use 60fps and 30fps, and in both cases there were problems, it looks like FF doesn't have any stable time/logic of rendering).
I've tried to play with Ticker.timingMode (set it to Ticker.RAF_SYNCHED), but it didn't help either.
And also, I've found a lot of similar topics/questions in the Internet, and no any clear answer.
So, I was wondering, if there is any way to improve framerate/rendering in FF or we should work with it as it is now?
P.S.: It looks like the problem, probably, partially might be on the CreateJS side, because I've found few nice HTML5 games (as I know they don't use CreateJS) with smooth and nice animations in FF. Here an example: https://www.netent.com/games/slots/dazzle-me/
EaselJS just facilitates Canvas drawing operations and updates. I have built a number of applications and games without FireFox-specific performance issues using the CreateJS framework, so while there might be something that is happening through CreateJS causing the issue, it is more likely related to the content and how CreateJS is used.
Different browsers have different issues and performance differences, including how they handle vectors, large images on the GPU, etc. Without seeing code or an example, it is hard to pinpoint where the performance is going.
What have you tried so far to isolate the performance?
Do you have a lot of large images, text, or vector content?
Are you using filters or Shadows?
How are you determining that the framerate is not working? RAF_SYNCHED attempts to normalize the computer's RAF framerate (usually about 60 fps, but dependent on lots of things).
Do you have a lot of children (like particles) going on?
Are you checking mouse position or hitTesting often?
If you can provide more info, code samples, working demos, etc you can likely get a better diagnosis of what is happpening.

SVG zoom with svg-pan-zoom.js performance issues in Mozilla Firefox

I am using javascript svg-pan-zoom.js (https://github.com/ariutta/svg-pan-zoom) libary to zoom and pan svg in web application. Zooming in Firefox is very slow and laggy, while zooming in Chrome and IE11 works very well (tested with 5MB .svg file that presents floor plan - if file is smaller, this issue is not that noticeable). Panning is working fine. I've read many topics on this issue on forum but I haven't find any solution yet. Does anybody know what is causing this problem and how to fix it?
Example: http://jsfiddle.net/coz3fd0L/3/
Check your refreshRate option. Maybe you set a high number.
If not then you may set a low number (ex. 10 which means max 10 frames per second) and if may improve your problem.
Other than that I don't know of any other problems in svg-pan-zoom. At least if pan is smooth then zoom should be the same.
Maybe your SVG has a lot of edges/curves/nodes and Firefox is simply bad at resizing such things. Or it is bad at resizing large SVGs when matrix transform is used (matrix transform is used for zoom/pan in svg-pan-zoom).
Update: From what I see this is purely a Firefox problem (or the way it is). Just opening the SVG from your example http://imgh.us/test_51.svg takes 100% of CPU (for page scroll).
Also I did try to change matrix transform values manually (to test if it is svg-pan-zoom issue) and it is anyway very slow.
The only solution I see is to try to optimize your SVGs (maybe it is possible to make them simpler: less edges, nodes, do not render white elements...).

Rendering and jaggering

I have a html 5 canvas using the 2d context. I am able to get up to 120 frames per second, but the rendering can be jagged, where the animation just jumps. I would like to know any ideas what may be causing it, especially with such a high (but pointless) frame rate? What are known ways or smoothing out animation as well?
The only thing that does come to mind, is the actual drawing is not being accounted for. So while the updating and drawing functions can be run quickly, the painting onto the canvas is stacked later. Which would then imply that I am not geting a true frames per second.
Although, I can get 120 frames per seconds that really means nothing. Because I am using setTimeout, I have not guarantees that the time will be constant, thus, when it does jagger, that is because the frame rate, for a moment, has dropped significantly.
However, there is an alternative in the works, that I managed to found. I'm a bit surprised how hard this was to find.
http://paulirish.com/2011/requestanimationframe-for-smart-animating/
https://developer.mozilla.org/en/DOM/window.mozRequestAnimationFrame
http://dev.chromium.org/developers/design-documents/requestanimationframe-implementation
From what I can understand, the function allows the browser to optimise for animations. In theory, this should give a more consistent frame rate, which should give smoother animations.
It is also quite interesting to compare how Chrome, Safari, Opera and Firefox draw. I mainly test on Chrome 14 dev and Mozilla Aurora 6.0a, and they way draw look very different. Chrome seems to be able to draw directly. Firefox seems to be piping the pixels, as if it's sending them one by one to be drawn.
Which leads me to Opera
http://www.scribd.com/doc/58835981/122/Double-Buffering-with-Canvas
http://www.felinesoft.com/blog/index.php/2010/09/accelerated-game-programming-with-html5-and-canvas/
turns out Webkit-based browsers and Gecko-based browsers use double buffers internally, that is, it collects all the drawing functions together and then draws them on the return of the function thread. If you have a main loop function, like update, it won't draw until that has returned. Opera, just draws them as the drawing functions are called, but it's not hard to implement double buffering. This is, supposably, another method of smoothing out the animation.
There is also another experimental feature that may help as well
http://badassjs.com/post/4064873160/webgl-2d-an-implementation-of-the-2d-canvas-context-in

How to generate simple 3D images in JavaScript

I like to generate a simplified version of the following static image in pure JavaScript. It should work with 2010 vintage browsers, so I can't wait for Firefox 4 and WebGL.
I do not need any fancy textures - the task is just to visualise how to stack some boxes.
BTW: the current image is generated with POV-Ray which is overkill for the job - and does not run in the browser ;-)
As you say you don't need fancy textures I'd recommend for vintage support that you stack images like mentioned earlier. I made an example for you: http://jsfiddle.net/andersand/5RsEx/
The simple function is just to illustrate, and does the drawing of a segmented box. Of course you may need to figure out box placement, orientation, and so on if that is your business goal.
That approach could help you with boxes of various height (z axis). If your boxes also vary in width (x and/or y) you'd need to create more images to suit your needs.
If you can do without IE support, or require a plug-in for IE users, or provide server-side rasterization for IE users, you could use computed svg files.
You could do a very basic projection of the vertices of the boxes, maybe start with a simple isometric projection and then go to a perspective projection. Use simple 4x4 matrix math as used in OpenGL for this and represent the 3D coordinates as [x, y, z, w] vectors. Since the images are small and simple enough you can get away with simply using a smart rendering order, i.e. bottom to top, back to front, which will make sure you don't have to worry about mucking about with a depth buffer or other such things. Should be fairly simple to implement, you don't need third party libs and it will be natively supported in most of the contemporary browsers.
Okay, I thought this to be an interesting experiment, so I made a working version of what I described above. It works in all major browsers with the notable exception of IE. SVG support should come to IE with the introduction of IE9. I've tested in Opera, Firefox and Safari under OS X and Opera and Firefox under Linux. It might be possible to add IE support by making VML output possible, though I must say that I do not know whether IE permits inlining of VML in XHTML using namespaces like I used here.
Computed SVG rendering of 3D stacked boxes
Right now it only does isometric projection. I might just spend a bit more time on this to add a perspective projection option as well. That would seem fun and should not be much more than adding another matrix multiplication.
Searching for Collada (XML based 3d file) support may be your best bet. Now that canvas has landed, lots of 3d routines are being ported from Flash Actionscript to Javascript.
You can export Collada files from all of the major 3D applications, as well as blender ;)
Try the following as an example;
http://www.rozengain.com/blog/2007/11/21/parsing-collada-3d-assets-with-javascript-in-the-html-5-canvas-element/
If you want to rotate a 3D scene using javascript, you may have a few months wait until the engines get released. They will most likely be HTML5 dependent.
There are a few WebGL implementations doing the rounds but they are for the bleeding edge browsers and are very unstable.

Categories