tags : Web Development

Graphics on the web

Immediate mode vs Retained mode

  • At the end of the day browser is rendering the UI to the screen via a Graphics API. There’s 2 ways to do it.
  • Good summary by Rob Rohan

Retained mode

  • HTML DOM is an example of retained mode UI

Immediate mode

  • React Framework is tries to use some ideas from immediate mode UI but ultimately does have to put everything back to the DOM
  • When we do things inside <canvas> element, we’re responsible for managing state, redrawing etc. So when you’re using CanvasAPI or webGL, you’re operating in Immediate mode.
  • Most games are usually in immediate mode.

Visual Media

AFAIK there are 4 types of visual media that browsers as of today can present.

  • Images
  • On the fly 2D and 3D graphics
    • Canvas API, WebGL, WebGPU
    • Using <canvas> element
  • Video
  • Icons/Emojis : Usually fonts, sometimes SVG.

Displaying visual media

AFAIK, to display visual media to humans, we need 3 things

  • A renderer: SVG, Canvas API, WebGL, WebGPU
  • A way to talk to the renderer: Javascript
  • A place where a renderer can display what it’s going to render: HTML DOM

The HTML DOM

  • It is the ultimate playground for graphics on the web.
  • Supports general things: Positioning, CSS layout, CSS transitions etc.
  • Renderers
    • SVG: Since SVG is directly written into the DOM, we can do almost everything we can do with other dom elements.
    • Canvas API, WebGL, WebGPU: Provides support via <canvas> element.

Aside on the DOM (political)

  • Found the following in a reddit comment. Interesting.
  • The DOM allows content indexing, and to address accessibility requirements.
  • Google would love, for example, to prevent ad-blocking. Ad blocking is much harder if ads are rendered straight to a canvas with no semantic data (and harder again if Google recommends proxying all ad serves through webhosts’ own domain, to prevent filtering before anything hits the canvas).

Renderers

Answer to when to use these is, ”it depends“.

SVG (via HTML)

  • Vector based
  • SVG is not really a renderer(?) but works out as one in our case. It directly plugs into the DOM transparently and allows us to style with CSS, and have events w js like other HTML elements.
  • When to use?

    • When we need vector stuff, easily displayed on smaller screens etc.
  • Issues

    • If the number of objects is too high, it’ll usually become a bottleneck because of reflow/repaint

Canvas API

  • Bitmap based. Better performance than SVG.
  • Part of HTML5. Can be used directly via CanvasRenderingContext2D but otherwise there are a lot of popular wrappers.
  • When to use?

    • When SVG is not cutting it for performance and using WebGL would be too extra
    • Anything that is more efficient to draw pixel-by-pixel than via the browser’s DOM rendering.
    • Drawing/whiteboarding app
    • Particle animations
    • Anything image manipulation
    • From SVG to Canvas
  • Issues

    • Mostly backbox debugging as not into the DOM
    • Most limited of 3 options (cannot use CSS on it, no shaders)

WebGL

  • When to use?

    • When we need most performance
    • When there’s a need of shaders/3d stuff
    • You can use webgl for 2D with a locked camera, I think figma uses it that way.
  • Issues

    • Mostly backbox debugging as not into the DOM

WebGPU

  • IDK anything about it but wanted to mark its existence.
  • Can use it outside the browser

Mixing renders

Using one render doesn’t limit you from using the other. One can use them in combination to get the desired visual result as well make it performant. All combination are possible. Some examples:

  • Canvas + Canvas
  • Canvas + WebGL
  • SVG + Canvas, eg. Have main layout in SVG, if inside the layout you have high number of dots to display you can use canvas/webgl for those and things will be performant.
  • SVG with blurring / color effects on top of image
  • Some JS framework side menus/event listeners, canvas/webgl in center etc.
  • Other examples

Animations

Things that are displayed by the renderes, can be animated.

CSS & JS animations

CSS transitions

CSS Transitions have a start and and end(only 2 states). A to B, visible to invisible etc.

CSS animations

More than 2 states. in fact you can have lots of them, and they can be used to create more complex animations.

SVG animations

  • There was SMIL but then it was deprecated
  • You can use CSS animations are used to animate SVGs. Things like path animations can be done w css.
  • You can also animate SVGs with JS, which is the case most of the time. Helper JS libraries(anime.js, GSAP, Snap.svg, SVG.js etc.)
  • For more complex stuff you can import animations w things like lottie, rive etc.

Canvas API animations

WebGL animations

WebAnimation API

Other libraries for animation

More on animations

The levels of web animation

I found this excellent comment on reddit, this is the summarization:

  • Level0 (State change): State change effects, hover, focus etc.
  • Level1 (Class transitions): Class change effects, changes that take place when class is changed. Class is changed with JS.
  • Level2 (CSS animations): Whenever we need keyframe animations, like spinners.
  • Level3 (Moving in/out of DOM)
    • This is fine for out of flow things like tooltip and stuff
    • For static things, where you know the size of the content(eg. accordion) you can use max-height etc.
    • For more dynamic things, you’ll have to use JS for that to measure the size of elements before and after they’re visible.
  • Level4 (Scroll transitions)
    • They can be as simple as using JS to detect when an element becomes visible and use basic state transitions
    • But it can also be complex, like really using the scroll distance to play the transition as the scroll happens
  • Level5 (Page transitions)
    • If you have the index page of a blog with list of posts that have an image and a title
    • the page transition would be that on click on a post, the post thumbnail moves to become the background of the page and the titles moves as well
    • before the rest of the content appears, as if you’d never left the page.

I feel like these level approach is nice but can be improved and extended. I should come back and improve this list someday.