views:

1608

answers:

6

Javascript CANVAS is amazing: it allows us to draw something like lines, polygons on the browser screen.

I wonder how does Javascript CANVAS works. For example to draw a line, does it use a series aligned tiny images to simulate the line or some other approach?

Thanks in advance.

+1  A: 

Surely that's implementation-specific to the JavaScript engine browser in question?

Rob
I think it's actually native to the browser, no the JS engine. For example, I don't think V8 supports Canvas, it's Chrome that does the rendering work.
slacy
Duh, I meant browser. Something went badly wrong between brain and keyboard there...
Rob
+6  A: 

Any reasonable implementer would just use a bitmap (stored internally in the browser), and draw to that using OS native drawing commands.

Why does it matter? It's not at all related to HTML+CSS, if that's what you're wondering.

More detail, for detail's sake:

When the browser's HTML parser sees a canvas element (of a given width & height) it needs to allocate an onscreen pixmap to cover that area. It either does this manually (i.e. malloc()) or it calls into some OS native drawing API to create a surface to draw on. The OS native API could be Windows, Gtk, Kde, Qt, or any other drawing library that the implementer of the browser chose. Also, it's highly dependent on the operating system. Internet Explorer probably calls into some Windows native library (i.e. DirectX or WinFooBarMethod()).

Once the drawing surface is created, it's made accessible to the internal guts of the JavaScript interpreter, likely via a pointer or handle to the constructed drawing surface. Then, when the JS interpreter sees an invocation of one of the canvas methods, it turns this into a call to the appropriate OS native command.

So, using the Windows 3.1 style metaphor:

"new canvas(width, height)" = "WinCreatePixmap(width, height)" 
"canvas.setPixel(x,y,color)" = "WinSetPixel(x,y,color)"

And using a manually managed pixmap:

"new canvas(width, height)" = "malloc(width * height * sizeof(Pixel))"
"canvas.setPixel(x,y,color)" = "canvas[x][y] = color;"

Again, it shouldn't matter to the JavaScript developer how these methods are implemented. The only people who need to care are the ones who are writing HTML5 compliant web browsers with canvas support.

slacy
On a second thought, it seems impossible for javascript to call browser's OS native drawing methods.
JavaScript can't call OS drawing commands. The *browser* interprets the JavaScript/CSS/HTML and *it* calls the operating system's native drawing commands to draw what is necessary.
Steve Harrison
This makes more sense. But which method is actually called when I call Canvas drawline()? In other words, how a single black pixel is actually rendered on the browser by Javascript call?
Again, why does it matter? The actual method name could be internal to the browser (i.e. manually setting pixels in a pixmap to do the rendering) or it could end up calling the OS commands, WinDrawLine() or whatever the implementer of the browser chose. (i.e. Windows, DirectX, Qt, GTK, etc.)
slacy
-1 for answering "Why does it matter?" to a question that includes the words "I wonder".
Jason Orendorff
Please remember, IE doesn't support Canvas. If you're using Canvas in an IE browser, you're most likely using the exCanvas bootstrap. IE uses VML.
jeremyosborne
A: 

If you're interested in how line drawing works, check out Bresenham's Line Drawing Algorithm.

Paul
Thank you, but I don't care the algorithm to draw a line or something. Just wonder how a single pixel is actually rendered on the browser.
@sc85: The browser is doing the work. It has the context of a bitmap. It can either draw the line or it can call an OS call to draw the line. It doesn't matter. Drawing an antialiased line is trivial.
Nosredna
+1  A: 

You're thinking too much, it's simple:

A canvas is like an image that can be drawn on to the browser.

Georg
I think you're thinking of SVG.
tj111
I think gs has the right idea. If we can make sure we recognize that "image" in this case is not an img element, but rather a (pardon the recursive definition) blank "canvas" that can be manually plotted to from a set of JavaScript methods.
jeremyosborne
A: 

I think implementation is important. Why does it matter? Look at flash. When you use the drawing API to create complex fractal artwork it is actually creating vector artwork and making every line and curve a child of the object being drawn on, thus it rerenders the vector artwork every frame.. CRASH! or chug... chug........ chug.............. So for complex fractals or art that records equations, I have to use a Bitmap or the render engine CACKS. It DOES make a difference, since now I am trying to transfer some of my flash multimedia to Javascript and encountering differences among browsers.

Robert Woodbury
+2  A: 

If you know C++, you can go to the source.

For example, in Firefox, the "graphics context" object is implemented by the class nsCanvasRenderingContext2D. But that class doesn't actually modify the pixels directly. Instead, it asks a separate object, called Thebes, to do that. Thebes in turn delegates this work to a graphics library called Cairo, which typically asks a library provided by your operating system to do the actual pixel work. I imagine it's a similar story everywhere.

At the very bottom, the canvas has a two-dimensional array of pixels. Each pixel is a 32-bit integer. A pixel is set by assigning a value to an element of the array. Somewhere there's a bit of code that determines which pixels to paint and assigns the appropriate values to the appropriate array elements.

In theory, the pixels might be drawn by your video card, but I have heard that graphics cards generally can't be trusted to do 2D graphics, because the hardware is aggressively tuned for 3D gaming and trades away too much accuracy for speed.

Jason Orendorff