Activate your free membership today | Log-in

Wednesday, January 7th, 2009

Watch out for the zoom; Debugging fun with Canvas

Category: Canvas, Debugging

Ben was cursing at a bug in some canvas code that he was playing with, where the rendering was off. One piece of his UI was blurred instead of crisp.

The debugging exersize was fun, and he shares it with you on his personal blog.

The moral of the story is: watch out for that zoom feature in today's browsers!

Along the way, I got to learn that canvas supports fractional coordinates:

My first thought was that it would be due to fractional coordinates. I have years of experience with drawing APIs that force integer coordinates, so I’m used to relying whacking off the fractional part of a coordinate and making up the difference when necessary in a second pass. Canvas, on the other hand, supports fractional coordinates, which I’m told is the fancy thing to do these days. (How the fraction is converted to an actual pixel is depenendent on whatever drawing system is doing the heavy lifting somewhere down the stack.) When your coordinates are fractional, you can get this kind of fuzziness.

Because the interface I’m working with involves a few layers of rendering code, ensuring that integers ruled the roost took some time. But after quite a bit of poking around, I found no evidence of fractional coordinates. It was around this time I saw Vlad (Mozilla’s graphics guru) walking around the office and asked for some help.

We started looking for evidence of transforms that would introduce fractional coordinates–but ultimately came up empty handed. As we went through this process, he pointed out that the <canvas> context instances are reused, so it’s a really good idea to save() and restore() when obtaining a canvas to avoid polluting the context:

JAVASCRIPT:
  1.  
  2. var ctx = canvas.getContext("2d");
  3. ctx.save();
  4. // painting here
  5. ctx.restore();
  6.  

I had assumed each call produced a fresh, stateless context, so this was welcome news indeed.

But, user error was the true case:

And that’s when we noticed that I had zoomed in a click using Firefox 3’s fancy full page zoom feature. And that was causing the image the be scaled up, and the blurriness.

Posted by Dion Almaer at 8:49 am
7 Comments

++++-
4.8 rating from 4 votes

Technical Details Behind iWork.com

Category: Apple, Canvas

As soon as I heard about the new iWork.com site launched yesterday, I knew I wanted to know more about how it was made. iWork.com is a web-based way to share and collaborate over your iWork documents. I searched around the blogosphere seeing if anyone knew any technical details, but didn't find anything, so I had to crack open Firebug and see what was under the covers. I really wanted to know whether the apps were built with Flash or Ajax or something else.

I downloaded a trial version of iWork 2009 and published a Keynote presentation. The new Sharing function unfortunately requires you to configure and use the Apple Mail program, which I did before I could test out to see how the iWork.com shared documents work.

Looking at the JavaScript files, I see SproutCore and Prototype being pulled in, so everything is built with Ajax and web technologies. It's also using WebDAV to pull in the metadata about the document, which is interesting (though it's piping the WebDAV over some kind of proxy):

http://publish.iwork.com/iw/p159985190/.iWork/Share/Untitled.pages/Metadata/?webdav-method=PROPFIND

That URL returns an XML WebDAV document with the document metadata properties:

XML:
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <multistatus xmlns="DAV:">
  3. <d :response xmlns:D="DAV:">
  4.  </d><d :href>/iw/p159985190/.iWork/Share/Untitled.pages/Metadata/</d>
  5.  <d :propstat>
  6.   </d><d :prop>
  7.    </d><d :resourcetype>
  8.     <d :collection />
  9.    </d>
  10.    <d :getlastmodified>Wed, 07 Jan 2009 02:07:51 GMT</d>
  11.  
  12.    <d :modificationdate>2009-01-07T02:07:51Z</d>
  13.    <d :comment>1231293220308</d>
  14.    <x :Heckler.pages xmlns:X="urn:iwork:property">[{"guid":1,"type":"Page","w":612,"h":792}
  15. ]
  16. </x>
  17.    <x :Heckler.downloads xmlns:X="urn:iwork:property">[{"size":198284,"path":"Untitled.pages","guid":1,"downloadType":"pages09","type":"Download"},{"size":73533,"path":"Untitled.pdf","guid":2,"downloadType":"pdf","type":"Download"},{"size":30720,"path":"Untitled.doc","guid":3,"downloadType":"word","type":"Download"}]</x>
  18.    <x :Heckler.document xmlns:X="urn:iwork:property">[{"publishName":"Untitled.pages","publishDate":1231293215,"title":"Untitled","appBuildDate":"Dec 21 2008, 01:44:15","type":"Document","size":604363,"viewers":0,"marketeerPublishName":"b4d96779c707ea0d05ba5d33989ba0e45f874d3b40204a46895cdac1bd2fafac","guid":"Untitled.pages","nativeDownload":"Untitled.pages","authorEmail":"bradneuberg@gmail.com","documentType":3,"pageCount":1,"documentVersion":92008102400,"passwordProtected":false}]</x>
  19.  
  20.  
  21.   <d :status>HTTP/1.1 200 OK</d>
  22.  
  23.  
  24. </multistatus>

Notice how some of the metadata payload is JSON as well.

The web-based iWork apps are themselves built above SproutCore, using that framework to organize and do things. For example, there appears to be something named CoreHeckler that has to do with the commenting system, all built using SproutCore.

Using the Firebug Inspector, I see that the slides are a combination of an image file, the Canvas tag, and transparent DIVs that overlay; if there are hyperlinks on the page they are overlaid on a separate DIV that lies over the canvas. Comments also float on top of the Canvas using another DIV. The Canvas appears to be used for comments somehow, but I'm not sure how. I see CoreHeckler.Graphics being bound to the Canvas element; I'm not super familiar with SproutCore however.

Looking through the CSS I see they are using a few -webkit- specific CSS style rules, mostly around rounded border corners and shadows. They are also using the Webkit CSS Gradients and Clipping.

I wanted to see how things were handled in Internet Explorer. When I look at a published iWork.com document in Internet Explorer a very interesting dialog box first appears:

It was indeed slow; it took about 17 seconds to load the document in IE. Clicking on individual slides took about 4 to 5 seconds to show.

I used the Internet Explorer Developer Toolbar to get into the DOM and see how things run on IE. The first thing I see is that the Canvas tag is in the DOM:

However, notice a glitch that it has the <CANVAS> and </CANVAS> tags as separate elements, which can sometimes happen when IE is dealing with unknown tags. They are also definently using VML (Vector Markup Language) on IE, since I see them pulling in the VML behavior for IE on the main page. I wonder why they didn't just use the Google-ExCanvas library that emulates Canvas for Internet Explorer (Disclosure: I work for a team at Google that promotes open web technologies like this).

One other thing I noticed is that if you are on the iPhone you get redirected to an iPhone version of the app. This just replaces the URL /document/ section with /iphone/. When you navigate to this you get a PDF version of the page -- that must be the iPhone version, a PDF file!

I wanted to see how the Pages application does things as well, so I published a document there. The published text is selectable in the browser! The document itself appears to be an image file. To do selection, whenever I run over some text it appears that a Canvas element is created and a 'highlighted' type graphic is drawn over the correct characters. Internet Explorer also supports similar highlighting, though on there it appears to be using VML to do the highlighting.

All in all this is a very interesting web-based application built with Ajax and JavaScript!

Posted by Brad Neuberg at 6:30 am
3 Comments

++++-
4.6 rating from 14 votes

Monday, January 5th, 2009

Who needs Flash? Having fun with Canvas and SVG

Category: Canvas, SVG

Over in SproutCore land, they have been talking about Peter Bergstrom and his amazing work with Canvas and SVG:

Peter Bergstrom has been doing some amazing work with SVG and canvas tags in his SproutCore-based these project called PaperCube.  PaperCube visualizes citations their relationships between authors.  Watching the videos of his project, you’d swear he was using Flash or Silverlight, but its not.  He’s using only native web technologies powered by SproutCore and JavaScript.  It’s a great example of what’s possible using the browser’s capabilities today.

Checkout PaperCube’s Node Graph (SVG),  Per Year View (SVG), and Paper Tree (pure HTML).

Starting to get goose pimples about 2009 :)

Posted by Dion Almaer at 8:45 am
3 Comments

+++--
3.7 rating from 23 votes

2008: Awesome JavaScript

Category: Canvas

Jacob Seidelin has a really nice 2008 roundup of awesome JavaScript-yness that focuses a little on his own area of expertise (canvas whiz and all):

2008 has been just great, not least because of all the great stuff people have been doing with JavaScript, the new canvas element and the web in general. Browser vendors are now competing, trying to outdo each other in terms of JavaScript performance, leaving developers and end-users as winners as we now get to do cool stuff that wasn't really feasible before. Here's a summary of the neat things of the year 2008 as I saw it.

He starts out with fun canvas games such as Super Mario, Pac-Man, Breakout, Space Invaders, Bomberman or T&C Surf Designs.

Then we get to some fun demos... including small ones Rubber effect, Tunnex, Mars.

Then we get to 3D: Everything from basic 3D cubes, texturing experiments to regular JavaScript/Canvas 3D engines have been done.

And, emulators:

That JavaScript performance is getting better and better must be true since it's now possible to emulate other systems in the browser. Matt Westcott (who also made the Antisocial demo) pulled another rabbit out of the hat, JSSpeccy the ZX Spectrum emulator. That's just way cool.

James Urquhart also played a bit and created a proof of concept SCUMM interpreter. It won't let you play Day of the Tentacle or even Maniac Mansion, but supposedly it can at least let you see a bit of OpenQuest.

A personal favorite of mine was António Afonso's JavaScript AGI interpreter. AGI was the system used by Sierra in the golden days of adventure gaming and when António made this little gem with an (almost) working Leisure Suit Larry, it just totally tickled my fancy.

This is just the start, as we get to audio, visual, and other cool fun times from 2008. Thanks for the great roundup Jacob. I think 2009 will be even better!

Posted by Dion Almaer at 7:38 am
1 Comment

++++-
4.5 rating from 18 votes

Tuesday, December 23rd, 2008

Speed Dial Canvas Edition

Category: Canvas, Showcase

Christian Effenberger has a Christmas contribution for us, Quickchoice:

Quickchoice is a Speed Dial clone for css transform supporting browsers.
It's a simple and quick "public domain" implementation of Opera's Speed Dial.
Currently useable with Safari 3.2 and probably Firefox 3.1 -
through the http-protocol.

For personal use you need to save the html file (save as) and push to
your htdocs folder (localhost) or upload via ftp to your domain!

Posted by Dion Almaer at 7:11 am
1 Comment

++++-
4.2 rating from 18 votes

Thursday, December 18th, 2008

Pixastic: JavaScript Image Manipulation Library

Category: Canvas, JavaScript

Pixastic uses <canvas>'s ability to expose raw pixel information to perform Photoshop-style image manipulation effects all in your standards-based browser. For an example of Pixastic in action, the library's authors have built a cute little Photoshop clone in a browser:

Here's an example of using the underlying API:

JAVASCRIPT:
  1.  
  2. var img = document.getElement("myImage"); // get the image element
  3.  
  4. if (img.complete) {     // make sure the image is fully loaded
  5.         Pixastic.process(
  6.                 img,
  7.                 "brightness",   // brightness/contrast adjustment
  8.  
  9.                 {              // options object
  10.  
  11.                         "brightness" : 60,      // set brightness option value to 60
  12.                         "contrast" : 0.5,       // set contrast option value to 0.5,
  13.                         "rect" : {            // apply the effect to this region only
  14.                                 "left" : 100,
  15.                                 "right" : 100,
  16.                                 "width" : 200,
  17.                                 "height" : 150
  18.                         }
  19.                 }
  20.         )
  21. }
  22.  

There's also a jQuery plug-in wrapper, allowing you to do stuff like this:

JAVASCRIPT:
  1.  
  2. // invert the image with id="prettyface"
  3. $("#prettyface").pixastic("invert");
  4.  
  5. // convert all images with class="photo" to greyscale
  6. $(".photo").pixastic("desaturate");
  7.  
  8. // chained blur and a regional emboss, see image further down
  9. $("#myimage")
  10.         .pixastic("blurfast", {amount:0.2})
  11.         .pixastic("emboss", {direction:"topleft", rect:{left:50,top:50,width:150,height:150}});
  12.  

The architecture of the library is nice; there's a small core Pixastic library file (pixastic.core.js) and then each effect is factored out into its own JS file. A handy web interface lets you download your own minified subset of Pixastic.

Cool!

Posted by Ben Galbraith at 11:57 am
9 Comments

++++-
4 rating from 21 votes

Tuesday, December 16th, 2008

JavaScript Raster Bar Effect

Category: Canvas

This is a fun canvas demo by Stefan Pettersson that brings you back to your Amiga days (if you remember those, or weren't an Atari man).

You can check out the JavaScript that makes the world turn.

function start() {
        var resolution = 25;
        var speed = 0.02;
        var position = 150;
        var size = 50;

        var step = Math.PI * 2 / resolution;

        var bars = [];

        bars.push( new RasterBar(step, size, speed, getColor1) );
        bars.push( new RasterBar(step, size, speed, getColor2) );
        bars.push( new RasterBar(step, size, speed, getColor3) );

        var t = 0;
        setInterval(function() {
            ctx.clearRect(0,0,600,400);

            t += 0.03;
            if (t > Math.PI*2) t = 0;

            for (var i = 0; i < bars.length; i++) {
                bars[i].oldPos = bars[i].newPos;
                bars[i].newPos = position + Math.round(100 * Math.sin(t + i*(Math.PI*2) / 3));

                if (bars[i].oldPos >= bars[i].newPos) {
                    bars[i].draw(bars[i].newPos);
                }
            }

            for (var i = 0; i < bars.length; i++) {
                if (bars[i].oldPos < bars[i].newPos) {
                    bars[i].draw(bars[i].newPos);
                }
            }

        }, 25);
}

And as Stafan says, listen to this in the background!

Posted by Dion Almaer at 1:00 pm
11 Comments

++++-
4.5 rating from 17 votes

Thursday, December 4th, 2008

CanvasTurtle

Category: Canvas, JavaScript

Eiten Suez, author of jMatter, has been up to some fun hacking recently. He just released CanvasTurtle a JavaScript and Canvas version of the old favourite TurtlePascal.

You can build snow flakes with code like this:

JAVASCRIPT:
  1.  
  2. function side(size, level) {
  3.     if (level==0) {
  4.         fd(size);
  5.         return;
  6.     }
  7.     side(size/3, level-1);
  8.     lt(60);
  9.     side(size/3, level-1);
  10.     rt(120);
  11.     side(size/3, level-1);
  12.     lt(60);
  13.     side(size/3, level-1);
  14. }
  15.  
  16. function snowflake(size, level) {
  17.     (3).times(function() {
  18.         side(size, level);
  19.         rt(120);
  20.     });
  21. }
  22.  
  23.  
  24. clean();
  25. lt(30);
  26. setPos(0,-100);
  27. snowflake(250, 4);
  28.  

Or a pretty garden like this.

Posted by Dion Almaer at 6:15 am
3 Comments

++++-
4.1 rating from 14 votes

Monday, December 1st, 2008

AbstractCanvas: HTML Canvas and Java2D in one fell swoop

Category: Canvas, GWT, Java

Rodrigo Reyes has announced a new project called AbstractCanvas, a GWT project that sits on top of HTML Canvas and Java2D.

The same code can thus run in the browser, or on the server.

You can then write code such as:

JAVA:
  1.  
  2.  VerticalPanel vPanel = new VerticalPanel();
  3.  
  4.  CanvasPanelExt canvas1 = new CanvasPanelExt(300,150);
  5.  
  6.  canvas1.setFillStyle(Color.WHITE);
  7.  canvas1.setGlobalAlpha(1.0);
  8.  canvas1.fillRect(0, 0, canvas1.getCoordWidth(), canvas1.getCoordHeight());
  9.        
  10.  canvas1.addCanvasPainter(new ColorTest()); // <- Note the use of CanvasPainter here
  11.  canvas1.addCanvasPainter(new PathTest());     <- and here
  12.  
  13.  vPanel.add(canvas1);
  14.  

Posted by Dion Almaer at 7:09 am
Comment here

+++--
3.8 rating from 13 votes

Tuesday, November 25th, 2008

Car Navigation Map Mashup in Canvas

Category: Canvas

Ernest is up to his old canvas tricks again. This time he has published a car navigation demo that lets you drive around a set of tiles from a map (Google Maps, OpenStreetMap) and it paints your course at the same time.

How did he do it?

The key of the whole implementation is the use of the drawImage method for canvas. The fact that this method can take two possible source elements (an image element or another existing canvas element in the document) allows you to create very nice features like cropping images, image distortion or even a copy/paste selection feature as the one in photoshop.

In this case, Joshua already did the hard work of using the drawImage multiple times to split the original image into horizontal strips and then create the 3D effect. Another example of this technique is the one I did to create the Quicktime VR-style panorama effect using vertical strips instead.

For the car navigation map we have added an extra step to create the source image from the nine openstreetmap tiles. Merging first the tiles to a temporary canvas and then using this temporary canvas as the source of the final 3D map.

There's still more room to play around with it like improving the camera view or porting the collision system of the Mario Kart example.

A common issue some users find the first time they play with the canvas tag is the same origin policy which will prevent one from exporting the canvas to an image (using the toDataURL method) if the drawImage method uses images from another place. In order to solve that we need to proxy the images first.

Posted by Dion Almaer at 8:01 am
4 Comments

++++-
4.3 rating from 19 votes

Canvas Step by Step Tutorial

Category: Canvas

Bill Mill has created a nice step by step canvas tutorial that has you building a breakout clone, and you can interactively run code on the fly.

The code path takes you through the following steps:

  1. Introduction
  2. Draw a Circle
  3. Add Some Color
  4. Action
  5. Library: an Interlude
  6. Bounce
  7. Add a Paddle
  8. The Keyboard
  9. The Mouse
  10. The Bricks
  11. Finishing Touches

Posted by Dion Almaer at 12:01 am
3 Comments

++++-
4.4 rating from 24 votes