Skip navigation

Hypnoglow with <canvas>

I submitted an entry to the js1k contest. You can view it here. It’s not terribly fast so I suggest using Chrome to view it.

Prior art

What I describe in this post is neither new nor advanced. It’s just my implementation. Mathieu “p01” Henri did <canvas> hypnoglow 2 years ago, and won the 20 lines “Zoom” Javascript contest. Also here. I didn’t know about other Javascript contests before js1k.


I wanted to introduce a recursive, large kernel blur with my entry. I stumbled upon the W3C page which says this:

To draw images onto the canvas, the drawImage method can be used.

  • drawImage(image, dx, dy)
  • drawImage(image, dx, dy, dw, dh)
  • drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)

Each of those three can take either an HTMLImageElement, an HTMLCanvasElement, or an HTMLVideoElement for the image argument.

So my initial entry was doing something recursive like that:

context.drawImage(canvas, 4, 4, width-8, height-8, 0, 0, width, height);

where context is the context associated with canvas. This actually looked like crap, but worked.

Then, while testing on all 4 browsers requested by the js1k rule, I found out that only Firefox 3 would support blitting a canvas to itself. It wasn’t working at all with Chrome, Opera and Safari. It wasn’t even working with Firefox 4 beta.

Yet, Inopia/Aardbei‘s entry was using recursive blur with success. Digging into the cleverly size-optimized source, I found that it was using an additional offscreen <canvas> as a temporary buffer.

The hidden rule seems to be: you  can draw any rectangular area of a canvas A into any rectangular area of a canvas B, provided A is not B. This is actually matching how graphics cards works, where in the general case you cannot render in a texture you are using. A lot of thing remains possible : mipmap pyramids, feedback effets… I guess using Canvas 2D transformations and clipping regions would lead to even more effects.

ERRATUM: p01 proved the above paragraph wrong, drawing a canvas on itself seems to work.

Starting again

Taking some inspiration from rez’s work, I made a kaleidoscope-like visual too with a large-kernel blur.

Each frame in the entry follow this algorithm:

  • The main canvas is darkened by a half-transparent black rectangle.
  • Circles are added in various colors and size, using black <canvas> shadows.
  • The main canvas is downsampled to a 8x smaller canvas
  • …which is downsampled to a 2x smaller canvas, three times in a row (much like mipmapping). This amounts to 4 offscreen canvases.
  • The two smaller canvases (32x smaller and 64x smaller) are added to the main canvas to add glow.
  • The two larger offscreen canvas (8x smaller and 16x smaller) are added to the main canvas, but 4 times and with an offset, to add feedback.

This looked like this:

For those interested, I made an archive with the source, using stats.js from Mr Doob (use it!).

When size-optimizing, I had to change colors to save bytes and went with short HTML color names (“Red” is 1-byte shorter than “#f00”). So it’s different from the final version.


Safari, Chrome and Firefox 4 seem to take in account the sRGB color space when blitting an image.

Firefox 3 and Opera do not. Thus the entry is darker on these browsers, and doesn’t look good.


Yet another bugfix  release

Wormhol 1.4 changes:

  • Some people asked for more FPS-like controls. So be it. You can use WASD and your mouse to play the game. Yay! It’s not perfect, maybe A and D should make the ship strafe instead of turn (and one would turn with the mouse). If it doesn’t feel right to you, please tell.
  • Fixed icons in Windows 7. New icon (still ugly though).
  • Fixed ATI HD compatibility.

I’ve discovered a rare “everything gets black” bug yesterday, in a ship-collision. The problem is: I’m pretty confident it’s not introduced by this release. Not sure how I could eliminate a bug which happen once in a year.

EDIT: This release had an annoying bug so I removed the download link. Use 1.5 now.

What’s new

I’ve been lately busy with the Games From Mars website, learning server administrating, javascript and such.

I know, I should have work on Wormhol. But there was a couple of annoying things left in Vibrant that I think deserved a bugfix update. There it is.

>>> DOWNLOAD <<<

Vibrant 1.3 changes:

  • installer: there is a problem when launching the game from the download directory. Nothing happens. The installer now avoids that. If you dislike the idea of an installer let me know.
  • AMD/ATI compatibility: Vibrant should now support all NVIDIA cards, all AMD HD cards and some earlier AMD. The latter are very different from a bug point of view, so it may or may not work.
  • the game fallback in a degraded mode when OpenGL 2.0 is not detected. The game now has been reported to work on an Intel card, which was yet to see, but had problems with some old ATIs. (NOTE: the degraded mode was broken on release but has been fixed)
  • minor gameplay changes: less powerups in high levels, the turbo mode is a bit more powerful and costly, the auto-aiming is now weaker. So it’s harder to aim for newbies, while more rewarding for advanced players. I wan’t Vibrant’s gameplay to be hard and unfriendly, be prepared :).
  • ACHTUNG! The 1.3 version works improperly on ATI HD cards, use the 1.2 version instead.

As always, I would be midly happy to get your bug reports (the auto-generated log.htm file in the game directory) and rants.

What is Wormhol

It’s basically a classic snake game, revamped to fit an omni-directional 3D world made of abstract surfaces. It means that your snake is not on a boring plane and sticks to the surface underneath. It also mean that the curvature of the surfaces changes the gameplay quite a bit.



We released it at the last ever Breakpoint demoparty where people showed some interest.

However, this first release was totally a bit rushed and a number of features did not get into the 1.0 release.

  • ATI compatibility
  • Torii
  • Arbitrary mesh
  • Editable levels
  • IA players
  • Rebindable keys
  • Joystick support
  • More speed
  • One-click installer
  • A replacement for this Black Ugly Background©
  • etc…

The game is playable as is, but you need 1, 2 or better 3 buddies to play with you.

Seems tough?

Consider it as a social game: a game where you actually socialize, with face-to-face real-time interaction.

What Optimus said about Wormhol

So what ?

Do you see ? That’s 15 fucking “o” ! Can you do better?

The story behind Wormhol

Three years ago, I was hired by a mathematics researcher to create an educational CD-rom. I created a very similar snake mini-game on a misunderstanding with my boss. Unfortunately the CD was not published and I finally came to the conclusion it would never be. My little sister, who was still playing the snake mini-game with friends, demanded an upgrade as her birthday present.

The fact was, I didn’t hold the IP, nor the development tools. I had to rewrite it.

I wanted to try something new, so firstly I started with XNA. I stopped when I realized the 2D vector class had virtual methods. Then I tried C++/DirectX, and realized it would take too much effort to rewrite all my engine. Finally I came back to the one and only D programming language. Thanks to that, the birthday dead-line was blown up by just a month.

This is my last production labelled under the Adinpsz name.