Activate your free membership today | Log-in

Tuesday, June 16th, 2009

Doodle: Sprite library for Canvas

Category: Canvas

Billy Lamberta got tired having to get so low-level as you do with the raw Canvas API. So, he create a small abstraction layer:

Doodle.js attempts to create a fun and easy way to interact with the Canvas that is lightweight, flexible, and functional. While it contains a few shape primitives it is not meant to be a full-fledged drawing api, rather a framework that allows you to build sprites and interact with them in an expressive way.

He gives plenty examples, but here is one that animates the spiral that you see:

JAVASCRIPT:
  1.  
  2.  var r = 5;
  3.  var a = 0;
  4.  var frame = 0;
  5.  
  6.  dot.loop(function(obj) {
  7.               obj.modify({x:circle_x(a),
  8.                           y:circle_y(a),
  9.                           fill:random_color() });
  10.  
  11.               frame += 1; //update frame count
  12.               a += 10; //update angle rotation
  13.               r += 0.3; //update radius
  14.  
  15.               if(a % 15 == 0){ dot.fill = '#000000'; }
  16.               else{ dot.fill = random_color(); }
  17.  
  18.               //clear canvas every 800th frame, reset radius
  19.               if(frame % 800==0){oo.canvas().clear(); r = 5;}
  20.  
  21.           }, 0, '48fps'); //loop indefinitely at 48 frames/sec
  22.  

Best part of the framework? How he choose the "oo" convention for the main object:

The “oo” variable was picked because it’s easy to type, easy to remember (d-oo-dle), and easy for our eyes to parse when we look over the code (it only takes a very cursory knowledge of male psychology to understand that).

I was actually surprised that I hadn't already posted on this... or CAKE which I will mention next...

Posted by Dion Almaer at 5:36 am
2 Comments

++++-
4 rating from 25 votes

Tuesday, June 9th, 2009

Finally, a useful blink tag! Detecting your user blinking

Category: Canvas, Showcase

Dave Burke just gave an awesome demo at GDD Beijing. Fire up Firefox 3.5beta (for now) and head over here and watch the human blink detection in action!

Here Dave tells us more about his awesome hack:

Inspired by a demo by Paul Rouget, I've created an image processing demo that detects eye blinks in real-time. It uses a combination of <video>, <audio>, <canvas> and worker threads. The <video> frames are "projected" on to a <canvas> to get access to the raw pixels. The Euclidean colour distance is calculated inter-frame and thresholded, resulting in a view that shows movement (shown on a second canvas). A worker thread then performs several algorithms including tracing, sorting, and positioning check of the blobs of pixels. If the worker thread determines an eye blink, it posts back to the main thread which uses the canvas to draw bounding boxes around the eyes. The algorithm is based on a paper I wrote almost 10 years ago describing a communication system I built for a patient with severe spinal injuries. I had originally implemented it in C++ using Microsoft's "Video For Windows" (a precursor to DirectShow). I bet I would have laughed if someone said that I'd be able to write the same system in JavaScript less than 10 yrs later!

Thanks Dave!

Posted by Dion Almaer at 11:59 am
15 Comments

++++-
4.5 rating from 25 votes

Tuesday, May 19th, 2009

Locking onto beat; More visualizations of music

Category: Canvas, Showcase

"darkimmortal" has created another really nice visualization of music that uses Canvas and SoundManager2 to do its work.

Do yourself a favour, and hit play to see the funk

The example uses two canvases, one to do the logic wave work, and then it is copied into the main canvas that you see ctxR.drawImage( ctxL.canvas, 0, 0 );.

Here's some of the fun:

JAVASCRIPT:
  1.  
  2. function render(event){
  3.         var now = new Date().getTime();
  4.         ctxL.clearRect( 0, 0, 200, 100 );
  5.         var cdex = ~~((now/100)%21);
  6.         var colors = [_calone[cdex], _caltwo[cdex], 'rgb('+~~(24+(_vis||[0,0])[1]/19+34*Math.cos(now/8192+(_vis||[0,0])[0]/92))+','+~~(16+20*Math.cos(2+now/7192+(_vis||[0,0])[1]/71))+','+~~(32+24*Math.cos(4+now/5192+(_vis||[0,0])[0]/87))+')'];
  7.         for( var j=0; j<colors .length; j++ ){
  8.                 ctxL.beginPath();
  9.                 ctxL.moveTo( 250,50 );
  10.                 ctxL.fillStyle = colors[j];
  11.                 var ii;
  12.                 for( var i=0; i&lt;128; i+=3 ){
  13.                         ii = Math.abs(i-64);
  14.                         // Wave equation from Dynamic Hypnoglow
  15.                         // Optimised and made epic by Darkimmortal
  16.                         ctxL.lineTo( ii*4-32, 32+(64+ii/2)*(.1+.2*Math.cos(j+(now/352)+i/31))+(i&64)*1/(68-ii)+16*Math.sin( (now+(_vis||[0,0])[0]/1337 )/( (788-j*287)%1337 ) - ii*(.07+j/43+(_vis||[0,0])[1]/1973-(_vis||[0,0])[0]/1837) ) );
  17.                         // End of wave equation.
  18.                 }
  19.                 ctxL.closePath();
  20.                 ctxL.fill();
  21.         }
  22.  
  23.         ctxR.clearRect( 0, 0, 200, 100 );
  24.         ctxR.drawImage( ctxL.canvas, 0, 0 );
  25.         ctxR.globalCompositeOperation = 'lighter';
  26.         if(_bright){
  27.                 _bright2 ++;
  28.         }
  29.         if(_bright2> 3){
  30.                 _bright = false;
  31.                 _bright2=0;
  32.         }
  33.         ctxL.globalCompositeOperation = _bright ? 'lighter' : 'copy';
  34.        
  35.         for( var i=0; i&lt;6; i++ ){
  36.                 ctxL.drawImage(ctxL.canvas, 0, 0, 200>>i, 100>>i, 0, 0, 100>>i, 50>>i)
  37.                 ctxR.drawImage(ctxL.canvas, 0, 0, 100>>i,  50>>i, 0, 0, 200, 100);
  38.         }
  39.         _overlay.style.backgroundPosition = ~~((_vis[_axis]/2.5) % 600 ) +'px '+ (_firefox + (_aim> 2800 ? 10 : (_aim <500 ? -10 : 0))) +'px';
  40.        
  41.         if(_vis[_axis] <_aim){
  42.                 _vis[_axis]+= 20;
  43.         }
  44.         if(_vis[_axis]> _aim){
  45.                 _vis[_axis]-= 20;
  46.         }
  47.        
  48.         _fpsb ++;
  49.         if(_fpsc + 1000 <now){
  50.                 _fpsc = now;
  51.                 _fps = _fpsb;
  52.                 _fpsb = 0;
  53.         }       
  54. }
  55.  

Posted by Dion Almaer at 7:31 am
17 Comments

++---
2.5 rating from 33 votes

Monday, April 27th, 2009

Google and Mozilla 3D Round-up

Category: 3D, Canvas, SVG

About a month ago, we covered an announcement about Mozilla's plans to basically put OpenGL ES in the browser and call it Canvas 3D and to do so working with a new working group over at the OpenGL standards body, Khronos.

This week, we covered Google's own 3D announcement, a plug-in offering a high-level scene graph API and embedded V8 run-time.

And of course, don't forget about Opera's 3D work, which we covered back in November 2007.

So now there are three approaches to 3D:

  • Mozilla: Low-level, OpenGL wrapper
  • Opera: Mid-level proprietary scene-graph-ish API
  • Google: The full COLLADA monty

Where should the web go? Mozilla's Chris Blizzard compares the debate to Canvas vs. SVG:

Canvas is a very simple API, much like what we’ve proposed to Khronos for 3D support. It’s well-scoped, well understood and integrates very well with other web technologies. And it’s been getting a huge amount of traction on the web. People are writing all kinds of really neat technology on top of it, including useful re-usable libraries for visualization. Have a look through Google’s own promotional site for Chrome - a huge number of them use canvas. It has traction. And we’ve gone through a couple of iterations - we’ve added support for text and a couple of other odds and ends once we understood what people were trying to do with it.

Now compare this to SVG and SMIL. Each of those specs are multi-hundred page documents with very large APIs and descriptions of how to translate their retained-mode graphics into something that’s usable on the web. (SVG 1.1 is a 719 page PDF. SVG 1.2 Tiny is 449 pages. The spec for SMIL is a 2.7MB HTML file.) We’ve seen some implementation of SVG and SMIL in browsers, but it’s been slow in coming and hasn’t seen full interoperability testing nor any real pick up on the web. The model for these specs was wrong, and I think it shows.

Chris doesn't directly say that Google's approach is "wrong", but he wonders if the Google proposal of a bigger and more ambitious API would represent too great a compatibility burden for browser vendors and developers.

In the comments of his post, Henry Bridge of the Google O3D team replied; here's a lightly edited excerpt:

We agree that to keep a standards process focused, APIs should be as minimal as possible while remaining useful, and so we would likely keep things like that out of any first attempt at a standard and, as you say, let it evolve over time. But the usefulness question brings up an important, and we think, unresolved point. We’d love to build the animation and skinning system in JS, but we just couldn’t get a JS-based animation system fast enough — even on our retained-mode API. Javascript is getting faster all the time and we love that, but until someone builds some apps it’ll be hard to know what’s fast enough.

Standardizing [an Open GL-like] immediate mode API for JS makes total sense. It’s a well defined problem, lots of people know GL, and we think it will be useful. But some of the demos we wrote _already_ don’t run well without a modern JS implementation, and moving to [Open GL] won’t help that (but we’d love to be proven wrong). That’s why we think it makes sense to explore both an immediate and a retained mode 3D, and make sure they work well together.

What do you think?

Posted by Ben Galbraith at 7:00 am
14 Comments

+++--
3.9 rating from 19 votes

Wednesday, April 22nd, 2009

Dynamic Content Injection with HTML5 Canvas and Video

Category: Canvas, Examples, Firefox, Video

Paul Rouget and Tristan Nitot are having a lot of obvious fun with Canvas and <video> these days. The latest goodness is a demo by Paul that shows real-time dynamic content injection.

Notice the Firefox logo in between the two phones with bright screens? That is injected into the world thanks to Canvas.

How did Paul do this? He told us:

Obviously, I use the <video/> tag.
But what you see is not the video element (display: none;), but a
<canvas/> tag.
All the patterns you see on the top right are regular <img/>,
<video/> and <canvas/> elements. The play/pause button is
a <svg/> element
(position: absolute;) on the top of the main <canvas/> element.

A canvas element provides a method named drawImage which let you
inject the content of a DOM element in the canvas (like a screenshot). It works
with three kinds of elements: <img/>, <canvas/> and
<video/>.

When you click on the <svg/> button, the Javascript code launches the
main video. Then, the main javascript loop is executed each 10
milliseconds.

Here are key things that occur during the main loop:

  • first, the content of the video is injected in the main canvas. That's why
    the canvas element looks like a video element;
  • second, the position of the 2 brighter areas of the canvas are computed
    (you have access to all pixels values);
  • third, the required transformation is computed (rotation, scale,
    translation);
  • fourth, the content of the selected pattern is injected in the main canvas
    following the transformation.

A little drawing:

DCI

Check out the demo in a bleeding edge Firefox browser, or watch the video:

Crazy cool stuff :)

Posted by Dion Almaer at 8:50 am
5 Comments

++++-
4.7 rating from 36 votes

Monday, April 20th, 2009

Visualizing sort algorithms with Canvas

Category: Canvas, Fun

The image above is a visualization of a bubble sort with 15 elements.

Jacob came up with the goods again as he was inspired by Aldo Cortesi's work doing this with Cairo.

Nicely done guys. If we ever get a sort algorithm question again not only will we be able to give the big O notation, but imagine pulling out some Canvas code to visualize ;)

Posted by Dion Almaer at 2:36 am
1 Comment

++++-
4.1 rating from 16 votes

Tuesday, April 14th, 2009

Metatunnel: The (Future) Web Strikes Back

Category: Canvas, Fun

Last week, we posted a story on the Metatunnel demo, a concisely-written Linux and Win32 demo that Paulo Falcão ported to JS. We looked at the pitiful performance of the JS version as evidence that, high-speed JS engines notwithstanding, the web's got a ways to go on the fx front.

We didn't dig deep enough.

Someone posted a follow-up to our story saying that the JS code was poorly optimized and that the JS version could be made to run faster. That got me wondering how efficient the desktop version was, and how apples-to-apples the versions were in terms of total calculations performed per frame. My thinking was that if the JS version could be made faster but via optimization contortions that the desktop version didn't require, that's missing the point.

It turns out the desktop source is trivial: it's an assembler bootstrap for passing OpenGL shader instructions to the system's OpenGL driver:

JAVA:
  1. // we don't have a "shader" syntax highlighting;
  2. // using "Java" instead :-)
  3. vec2 v=(gl_FragCoord.xy-vec2(400,300))/vec2(400,300);
  4. float w=dot(gl_Color.xyz,vec3(1,256,65536))*.25;
  5. const float s=0.4;
  6.  
  7. float obj(vec3 pos){
  8.         float final=1.0;
  9.         final*=distance(pos,vec3(cos(w)+sin(w*0.2),0.3,2.0+cos(w*0.5)*0.5));
  10.         final*=distance(pos,vec3(-cos(w*0.7),0.3,2.0+sin(w*0.5)));
  11.         final*=distance(pos,vec3(-sin(w*0.2)*0.5,sin(w),2.0));
  12.         final *=cos(pos.y)*cos(pos.x)-0.1-cos(pos.z*7.+w*7.)*cos(pos.x*3)*cos(pos.y*4.)*0.1;
  13.         return final;
  14. }
  15.  
  16. void main(){vec3 o=vec3(v.x,v.y*1.25,0.0);
  17.         vec3 d=vec3(v.x+cos(w)*.3,v.y,1.0)/64.0;
  18.         vec4 color=vec4(0.0);
  19.         float t=0.0;
  20.         for(int i=0;i&lt;75;i++) {
  21.                 if(obj(o+d*t)&lt;s){
  22.                         t-=5.0;
  23.                         for(int j=0;j&lt;5;j++){
  24.                                 if(obj(o+d*t)&lt;s){
  25.                                         break;
  26.                                 }
  27.                                 t+=1.0;
  28.                         }
  29.                         vec3 e=vec3(0.01,.0,.0);
  30.                         vec3 n=vec3(0.0);
  31.                         n.x=obj(o+d*t)-obj(vec3(o+d*t+e.xyy));
  32.                         n.y=obj(o+d*t)-obj(vec3(o+d*t+e.yxy));
  33.                         n.z=obj(o+d*t)-obj(vec3(o+d*t+e.yyx));
  34.                         n=normalize(n);
  35.                         color+=max(dot(vec3(0.0,0.0,-0.5),n),0.0)+max(dot(vec3(0.0,-0.5,0.5),n),0.0)*0.5;break;
  36.                 }
  37.                 t+=5.0;
  38.         }
  39.         gl_FragColor=color+vec4(0.1,0.2,0.5,1.0)*(t*0.025);
  40. }

Shoot, passing instructions to the video card? That's not a fair fight. It turns out Firefox 3.5 has a prototype Canvas 3D plug-in, and it exposes an OpenGL API. It was quick work for one of Mozilla's graphics gurus and the plug-in's primary developer, Vlad Vukicevic, to port the Metatunnel demo to Canvas 3D. The result is quite impressive:

See for yourself, but you'll need Firefox 3.5 Beta 3 or later and the Canvas 3D plug-in.

We should also mention that Paulo, Jacob Seidelin, and Hans Schmucker collaborated on optimizations in the JS software-rendering version that resulted in much higher FPS on "next-gen JS" browsers (Safari 4, Chrome, and Firefox 3.5). Note, on this demo you can use the Q and W keys to adjust quality.

Posted by Ben Galbraith at 7:00 am
9 Comments

++---
2.9 rating from 25 votes

Friday, April 10th, 2009

Metatunnel 1k Demo: JS vs. OS

Category: Canvas, Fun

Dion and I talk frequently about how the web platform's capabilities are approaching the desktop, which features like canvas and faster JavaScript run-times. It's great to get a piece of humble pie like this one.

FRequency created an interesting demo (as in "demo scene") of a "metatunnel":

Paulo Falcão ported this to JavaScript using <canvas>; how well does the JS version perform, you ask?

You get about 5 FPS at that size on Google Chrome, Safari 4 and Firefox 3.5 pre-releases; much worse on earlier browsers of course.

We've got a ways to go. ;-)

Posted by Ben Galbraith at 7:00 am
16 Comments

++---
2.5 rating from 14 votes

Thursday, April 9th, 2009

canvas-text: Add text functions to subpar canvas implementations

Category: Canvas

Fabien Ménager has created an interesting new library called canvas-text that simply "adds the three canvas text functions (strokeText, fillText and measureText) to the canvas implementation of the browsers which don't already have these functions (Firefox 2/3.0, Internet Explorer 6+, Opera 9+, Safari 3, Chrome 1.0). It doesn't change the already implemented functions in Firefox 3.1+, Safari 4 and Chrome 2."

Having the methods work is one thing, but what about the performance?

Well, there are some interesting examples for you to test:

I talked to Fabien about performance and he shed some more light:

The only bad performance issues are the font face download, JSON eval,
and data parsing. I try to use a cache when possible, but it's not
always possible.

A workaround would be to have two font face files : a full one, with
lots of characters, and a reduced one, with only the common ones. The
browser cache does the rest for the font face file download
(downloaded via Ajax or a script tag).

For IE, I think I'll have to make a VML renderer for IE that wouldn't send the
instructions to ExCanvas but would work directly on the VML.

Obviously, this is something I really want to play with and see how far we can get with this type of thing and Bespin. It is very much in an alpha state right now, but looking good.

Posted by Dion Almaer at 8:06 am
6 Comments

++++-
4 rating from 49 votes

Safari-style Candybars for Everyone

Category: Canvas, JavaScript, Library, UI

Christian Effenberger wrote in with another impressive piece of work:

Gauge.js 1.0 allows you to add programmable gauges (with shading and reflection) to your webpages.
It uses unobtrusive javascript to keep your code clean.

It works in all the major browsers - Mozilla Firefox 1.5+, Opera 9+, IE6+ and Safari.
On older browsers, it'll degrade and your visitors won't notice a thing.

Add to Firebug? ;-)

Posted by Ben Galbraith at 7:00 am
5 Comments

++++-
4 rating from 43 votes

Monday, April 6th, 2009

Great visualizations with Protovis

Category: Canvas, JavaScript

I have been very impressed with Andrew Sutherland of the Mozilla Messaging team (which is one reason that I have faith that I will dump Gmail for something he and the Messaging team come up with one day ;) and the visualizations that he is playing with are quite cool indeed. Seeing your email in different ways (not just in a table) can open the eyes.

Andrew is using Protovis "a visualization toolkit for JavaScript using the canvas element. It takes a graphical approach to data visualization, composing custom views of data with simple graphical primitives like bars and dots. These primitives are called marks, and each mark encodes data visually through dynamic properties such as color and position."

There are some cool examples such as:

JAVASCRIPT:
  1.  
  2. new pv.Panel().width(150).height(150)
  3.     .add(pv.Panel)
  4.       .data([[Math.sin(x / y)
  5.              for (x in pv.range(50))]
  6.              for (y in pv.range(3, 9))])
  7.     .add(pv.Area)
  8.       .data(function(d) d)
  9.       .fillStyle(pv.Colors.category19.unique)
  10.       .bottom(function() let (c = this.cousin())
  11.           c ? (c.bottom + c.height) : 0)
  12.       .height(function(d) (d + 1) * 13)
  13.       .left(function() this.index * 3)
  14.     .root.render();
  15.  

which produces .

Very cool indeed!

Posted by Dion Almaer at 8:29 am
5 Comments

++++-
4.3 rating from 15 votes

Wednesday, March 25th, 2009

3D APIs are coming to the Web in force

Category: Canvas, Mozilla

There have been a few posts on the news that "in response to a proposal from Mozilla, Khronos has created an ‘Accelerated 3D on Web’ working group that Mozilla has offered to chair."

Chris Blizzard (Director of Evangelism for Mozilla, and top chap) has some really good comments:

We’ve started to see more and more libraries being built to support use cases with Canvas in a 2D context but we really want to take things to the next level and start to allow people to use 3D capabilities as well.  Accelerated 3D graphics with the super-fast next-generation JavaScript engines from nearly every  web browser vendor means that we’re going to be able to start to see more and more advanced applications written using open web technologies.  3D is a huge part of that story and we’re happy to bring our proposal to the table.

The proposed spec (found in one of vlad’s post on 3D Canvas) is a pretty light wrapper on top of OpenGL ES 2.0, with some changes to support some JavaScript pleasantries.  OpenGL ES is a decent starting point, which is why we picked it.  OpenGL is supported as part of every major operating system and in it’s being picked up as a standard on mobile devices as well.  Compared to the full OpenGL spec, the ES variant is a smaller subset that reflects the reality of what’s being used on the ground and most hardware and software vendors have actually been re-tooling to support OpenGL ES with support for older versions of full OpenGL emulated on top of OpenGL ES.  Mixed with the fact that there’s a decent amount of knowledge out there in the industry of how to use OpenGL, we think that this smooths the integration between the current set of OpenGL users and larger web developer community.

And, there is the link back to Vladimir Vuki?evi?, the engineer who did the initial work (and who has been a huge help for Ben and I at Mozilla wrt Canvas and much more).

This is great stuff, and is it is important to clarify that this isn't about 3D virtual worlds, like some people think. This isn't VRML. The iPhone and the Mac are doing really nice 3D effects all the time these days. Close a window in OS X / Vista. Launch and quit Time Machine.

I am also glad to see OpenGL ES instead of yet another attempt at doing the 3D. There are a lot of tools and mindshare around this, and people will build great libraries on top of it I am sure for particular niches (apply some effects etc) and maybe we can get some uplift to CSS itself :) Oh, and i am really glad to see Google involved too!

I also saw Ryan Stewart weighing in and liked some of what he had to say, but was surprised by:

So it’s unfortunate to see that even the browser vendors have given up on moving the open web forward through standards. Whether it’s the WHATWG versus the W3C or the trials and tribulations of actually implementing HTML5, things are very broken and everyone is moving on regardless. I don’t blame any of them, but it doesn’t seem like it’s good for web developers.

Standards groups aren't the place to innovate. Browsers should be creating compelling features, other browsers should copy the good ones, and then we can standardize. XMLHttpRequest wasn't grown in the W3C. The cool CSS ideas that have been implemented in multiple browsers recently weren't either. Browsers need to push more, not less. And, then we need the standards groups to rally and try to turn the -vendor-bar-baz into bar-baz. Giving Web developers more APIs is good for Web developers!

Posted by Dion Almaer at 8:59 am
12 Comments

++++-
4.1 rating from 31 votes

JuicyDrop: More fun with music visualizations

Category: Canvas, JavaScript, Showcase

Jacob Seidelin is at it again, with another music visualization using canvas and more:

A couple of weeks ago I played around with music visualization using JavaScript/canvas and SoundManager2. Well, I couldn't leave it at that and as I mentioned in the comments, I had an eye on the MilkDrop plugin for Winamp. The result so far is a little Winamp lookalike called JuicyAmp with its own music visualizer JuicyDrop that feeds on Milkdrop preset files.

If you just want to see the pretty colors -> CLICKY. (But please use Chrome or Firefox 3+)

MilkDrop is nice because, although there's a built-in editor in the plugin, the presets are in plain text. They are basically just lists of variables and equations that, with a bit of mangling, can be evaluated as JavaScript. There are also extensive guides that explain how to author presets and how variables are passed around between the different equations. And, even better, the source code for the plugin was released a couple of years ago.

MilkDrop presets consist of a number of different elements (waveforms, shapes, per-pixel effects, etc). Some of them I haven't touched at all, but JuicyDrop supports enough at the moment that a good handful of presets run just fine. That said, there are a whole bunch of problems to work out and the presets included were selected because they looked alright and didn't make it blow up.

I strongly recommend using Chrome for this. Firefox 3 can play too but is probably somewhat slower. There's something screwy going on with Safari, it's like it's refusing to update the display (try holding down a key on your keyboard), I'm not sure what exactly is causing it. Opera is a mixed experience for me and it seems to have a problem with playing the music that I haven't found the reason for yet.

Posted by Dion Almaer at 4:17 am
5 Comments

++++-
4.8 rating from 31 votes

Monday, March 23rd, 2009

Explorer Canvas updated for IE 8 and more

Category: Canvas

Erik Arvidsson, one of our Knights, has shared a new Explorer Canvas release that has enabled excanvas folks to keep on trucking wrt IE 8 users. The way IE 8 does VML has been tweaked, so the library had to be changed accordingly.

You can also check out the Silverlight bridge too.

Here are the release notes:

  • Implement transform and setTransform. This passes all the tests in the HTML5 canvas tests for 2d.transformation.*
  • Remove fallback content that caused some issues when resizing the canvas element.
  • Fix issue where strokeRect, fillRect and clearRect incorrectly cleared the current path.
  • Added 2 new tests and modified an existing test to ensure that the new code works as expected and tested this in all modern browsers
  • Fix for IE8. This involved passing one more argument to namespaces.add as well as ensuring all CSS lengths have units (px). Passes all the test cases in all modes in IE8.
  • Fixes for linear gradients.
  • Added two test cases for linear gradients.
  • Changed the calculation method of line width. An averaged line width is calculated from the determinant of matrix, which is valid even when transform() method is implemented someday.
  • Improved the rendering of lines. Lines with the width less than 1px look better now.
  • Fixed the bug that stroke() ignored lineCap, lineJoin and miterLimit when fillStyle attribute was set.
  • Removed the settings of strokeweight, strokecolor and fillcolor. They are unnecessary since they are overridden by the weight and color attributes in <v:stroke> and <v:fill>. </v:fill></v:stroke>
  • This fixes issues where translate, rotate and scale is used during a path is being constructed. Previously we did the coord translations just before we draw the path. That is incorrect and now we do the translations when we add each individual piece to the path
  • Added very limited support for scaling of the stroke width. Currently we do the scaling by calculating the position in the final coordinate space and we therefore cannot do non uniform scaling of the stroke. For now we just do the max x/y scale factor.
  • Fix stroke. It should not close the path
  • Fix memory leaks
  • Fix issue where the path was not closed when strokeRect/fillRect was called.
  • Use the document.createElement('canvas') hack that was exposed by Sjoerd Visscher last week. This allows us to remove fixElement_ completely.
  • Added globalAlpha to the list of attributes copied for save/restore, as per the canvas specification.

Posted by Dion Almaer at 5:18 am
2 Comments

++++-
4.2 rating from 14 votes

Tuesday, March 17th, 2009

Unobstrusive Image Puzzle Maker with Canvas

Category: Canvas, Fun

Wow. Christian Effenberger pointed us to his impressive Snapfit.js project.

Snapfit takes any picture and, if the browser has support for canvas (or VML), will make it into a puzzle. Not just any puzzle, mind. A potentially wicked hard puzzle where the pieces can be mirrored in either axis. But, not to worry, if you need the puzzle solved, it will do an animated transition showing where the pieces should go, etc.

Christian sent us a few notes about performance, etc.:

The speed depends generally on picture dimension and number of puzzle pieces and particularly on browsers Javascript-Canvas-Performance.

It seems that Opera 9.x and Firefox 1.5 are to slow to be practicable, at least on my system (G4/1.25GHz).
Internet Explorer implementation in VML do not support all features and is unable to provide sub pixel precision. So don't expect to much.

It works in all the major browsers - Mozilla Firefox 1.5+, Opera 9+, IE6+ and Safari.
On older browsers, it'll degrade and your visitors won't notice a thing.

Drop it into your site!

Posted by Ben Galbraith at 7:00 am
2 Comments

++++-
4.6 rating from 23 votes

Monday, March 16th, 2009

Going full circle: could falling back to Flash solve IE’s lack of canvas support?

Category: Canvas, Flash, IE

There is an interesting blog post* and demo code on Azarask explaining Flash Canvas as a solution for IE's lack of support for Canvas:

How does FlashCanvas work?

FlashCanvas is modeled after ExplorerCanvas which means it is a turn-key solution for adding Canvas support to IE. You can code away, happily using open standards and then use FlashCanvas to forcefully and silently upgrade IE to also being standards compliant.

There are two main components in FlashCanvas: the base FlashCanvas.swf flash file (a mere 688 bytes), and the FlashCanvas.js wrapper. I’ve used the excellent swfobject.js to embed the Flash into the page.

The FlashCanvas.js file implements a fake-canvas object and converts all existing canvas element into a flash object. The javascript intercepts canvas commands and forwards them to the FlashCanvas.swf movie file using the ExternalInterface provided by the flash player. The flash movie clip then interprets the command and draws accordingly.

Aza originally thought that this would also solve the performance problems other fallbacks to VML have but found out that sadly enough this is not the case because of the lag between ActionScript and JavaScript via ExternalInterface.

Each call via the ExternalInterface is taking approximately 0.5 ms. Since we know the time it takes to call an actionscript method from javascript, we can deduce the amount of time it takes for Flash to render. For the example1.htm page it takes ~24 ms to render 20 anti-aliased lines. In Safari a call into actionscript takes roughly 0.4 ms — this is only the call time, it doesn’t include the time to render anything. For example1.htm a single “particle” calls actionscript 3 times with the commands: [lineStyle,moveTo,lineTo]; each particle takes 1.2 ms in JS-to-AS calls; to take 1 second to render the frame ~833 particles need to be rendered.

There are few more ideas in the comments to the article and this might be an interesting concept to take further. Somehow it seems ironic to go back to Flash to make IE render standards, but then again VML is proprietary, too.

* Hat tip to Scott Schiller for pointing out this older, but somehow forgotten post.

Posted by Chris Heilmann at 4:43 pm
18 Comments

++++-
4.3 rating from 22 votes

Next Page »