Hey folks,
I recently decided to learn SVG to see how it could help me with creative coding / generative art. Safe to say, I was blown away by how incredibly simple and easy it was to create truly responsive, scalable works that I could embed anywhere.
This was amazing for a while, until I started getting a craving for some bitmap action.
Cool, I thought. Let's got to <canvas>
land.
...
Nope, not cool. I had forgotten how painful it was to make <canvas>
actually look good.
The default <canvas>
element was a million miles away from the responsive, crisp rendering nirvana of SVG.
Everything looked blurry on my retina screen, making the element fluid was a living nightmare and loosing my drawing state on resize made me sad (especially for generative stuff)
VBCanvas to the rescue
As a remedy to the issues outlined above, I have created a JavaScript library - VBCanvas
that addresses the responsive issues of the default <canvas>
element.
It does this by introducing a viewBox
attribute that works just like SVG's.
You can check the library out here on Github or here on NPM
How it works
In short, you can define a viewBox
for your canvas - say 0 0 100 100
(x, y, w, h) and draw everything relative to those coordinates. The setup looks something like this:
const { ctx, el } = VBCanvas.createCanvas({
// viewBox (x, y, width, height)
viewBox: [0, 0, canvasWidth, canvasHeight],
// where to mount the <canvas> element
target: '.canvas-wrapper',
});
// draw stuff with ctx!
The <canvas>
element will then automatically scale / respond exactly like an <svg>
element. You can set any dimensions you like, VBCanvas will take care of all the scaling for you.
This makes creative truly responsive <canvas>
elements extremely easy!
Here is a simple example in which the canvas is always scaled to fit it's container. Much like background-size: contain;
in CSS or xMidYMid meet
for SVG.
And here is an example where the canvas is scaled to fill it's container. Much like background-size: cover
in CSS or xMidYMid slice
for SVG.
The code for the two above examples is exactly the same, apart from the scaleMode
option which defines how the canvas should scale.
Note: I have noticed that requestAnimationFrame
sometimes jumps frame rate in iFrames / embeds, if you notice some slightly wacky speed stuff in the examples, it's that.
I suggest opening the examples up and seeing how the canvas responds to resizing the viewport.
Have a play!
I hope some people find this library useful, and please do give me a shout on twitter @georgedoescode if you have any feedback. PRs / issues are of course always welcome 🙏