Monochrome Image Dithering Explained

Surma digging into the oldskool dithering technique:

I always loved the visual aesthetic of dithering but never knew how it’s done. So I did some research. This article may contain traces of nostaliga and none of Lena.

Turns out there’s quite a lot to it 😅

Ditherpunk — The article I wish I had about monochrome image dithering →
Ditherpunk Demo Page →

css-houdini-circles — A Houdini Paint Worklet that draws Colorful Background Circles

Last night — inspired by the Paint Worklet demos on Houdini.how — I decided to give Houdini a spin myself and created my own Paint Worklet. The result is css-houdini-circles which draws a bunch of random circles on the background.

🎩 Houdini, ain't that a magician?

Houdini is a set of low-level APIs that exposes parts of the CSS engine, giving developers the power to extend CSS by hooking into the styling and layout process of a browser’s rendering engine. Houdini is a group of APIs that give developers direct access to the CSS Object Model (CSSOM), enabling developers to write code the browser can parse as CSS, thereby creating new CSS features without waiting for them to be implemented natively in browsers.

It really is magic, hence it's name Houdini. I'd recommend this slidedeck and this video to get you started

As a user you can configure the number of circles, the size range, the opacity range, and the colors to use. In true Houdini style these are all configured using CSS Custom Properties.

.element {
    --colors: #f94144, #f3722c, #f8961e, #f9844a, #f9c74f, #90be6d, #43aa8b, #4d908e;
    --min-radius: 20;
    --max-radius: 100;
    --num-circles: 30;
    --min-opacity: 10;
    --max-opacity: 50;

    background-image: paint(circles);
}

~

Here’s a CodePen demo for you to play with:

(Hit “Edit on CodePen” and change the CSS Custom Properties to your liking)

~

What first started out as a demo on CodePen, eventually led to me creating and publishing it as a package on NPM.

npm install css-houdini-circles

Furthermore I also created a pull request to add the site to the Houdini.now website. I was quite surprised to learn it already got merged and is already published on the website 🙂

~

Feel free to fork the repo to have a starting point to creating your own Paint Worklet. If you know how to work with HTML canvas, I’m confident you’ll find it very easy to do so.

css-houdini-circles source (GitHub) →
css-houdini-circles on npm →

Rough.js – Create SVGs with a hand-drawn, sketchy, appearance

Rough.js is a light weight (~8k), Canvas based library that lets you draw in a sketchy, hand-drawn-like, style. The library defines primitives to draw lines, curves, arcs, polygons, circles, and ellipses. It also supports drawing SVG paths.

To get started first create a rough canvas:

const rc = rough.canvas(document.getElementById('canvas'));

On that rough canvas you can then start drawing things, and tweak the “roughness” along with that:

rc.rectangle(15, 15, 80, 80, { roughness: 0.5, fill: 'red' });
rc.rectangle(120, 15, 80, 80, { roughness: 2.8, fill: 'blue' });
rc.rectangle(220, 15, 80, 80, { bowing: 6, stroke: 'green', strokeWidth: 3 });

The code above evaluates to this:

Rough.js – Create SVGs with a hand-drawn, sketchy, appearance →

How Reddit built r/Place

Each year for April Fools’, rather than a prank, we like to create a project that explores the way that humans interact at large scales. This year we came up with Place, a collaborative canvas on which a single user could only place a single tile every five minutes. This limitation de-emphasized the importance of the individual and necessitated the collaboration of many users in order to achieve complex creations. Each tile placed was relayed to observers in real-time.

This post details how we approached building Place from a technical perspective.

Next to detailing how the data is stored, synced, and drawn on the canvas; the article also covers some realtime problem solving after the RabbitMQ CPU load avg shot up from 6 to 60 (!) …

The 72h timelapse – condensed to 4’30 – is embedded above. The source code of r/Place is also available.

Reddit Blog: How We Built r/Place →
r/Place Source (GitHub) →

Copycat JavaScript Game

Fun little game in which you control more than one character at once in a level, all bound to the same controls. Using walls and other obstacles you can sync up the locations between characters in order for each character to reach its own target.

The game itself is written in “vanillaJS”, sans external libraries, and renders onto a <canvas> element. Be sure to check out the source to see how it’s built (knowing French might come in handy whilst doing so ;)). The level design for example is interesting, as they are just multidimensional arrays:

{
    "nom": "debut",
    "indice": "try to move forward",
    "geometrie": [
      [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
      [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
      [0, 0, 1, 1, 1, 1, 1, 8, 8, 8, 1, 1, 1, 1, 1, 1],
      [0, 1, 1, 1, 1, 1, 1, 8, 1, 8, 1, 1, 1, 1, 1, 1],
      [1, 1, 1, 1, 1, 1, 1, 8, 4, 8, 1, 1, 1, 1, 1, 1],
      [1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 1, 1, 1, 1, 1, 1],
      [1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 1, 1, 1, 1, 1, 0],
      [1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 1, 1, 1, 1, 0, 0],
      [1, 1, 1, 1, 1, 1, 1, 8, 5, 8, 1, 1, 1, 0, 0, 0],
      [1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 1, 1, 0, 0, 0, 0],
      [1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 1, 1, 0, 0, 0, 0],
      [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
      [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
      [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
      [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
      [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
    ]
  }

Copycat →

Flipboard Engineering: 60fps on the mobile web

scrolling

Since earlier this week Flipboard now is a website too. As they wanted to mimic their mobile apps, it would sport lots of animations. During their first tests, they found the DOM being too slow (although that’s not entirely true, see this video and its description for example). And then, an epiphany:

Most modern mobile devices have hardware-accelerated canvas, so why couldn’t we take advantage of this? HTML5 games certainly do. But could we really develop an application user interface in canvas?

And so they did. They’ve built react-canvas for this, “high performance <canvas> rendering for React components”. Reminds me of Letterpress, which is an optimized OpenGL scene, and acko.net, which is a WebGL layer which renders the site.

60fps on the mobile web — Flipboard Engineering →
react-canvas →

Realtime Audio-Visualizations with JavaScript

window.onload = function() {
  var ctx = new AudioContext();
  var audio = document.getElementById('myAudio');
  var audioSrc = ctx.createMediaElementSource(audio);
  var analyser = ctx.createAnalyser();
  // we have to connect the MediaElementSource with the analyser 
  audioSrc.connect(analyser);
  // we could configure the analyser: e.g. analyser.fftSize (for further infos read the spec)
 
  // frequencyBinCount tells you how many values you'll receive from the analyser
  var frequencyData = new Uint8Array(analyser.frequencyBinCount);
 
  // we're ready to receive some data!
  // loop
  function renderFrame() {
     requestAnimationFrame(renderFrame);
     // update data in frequencyData
     analyser.getByteFrequencyData(frequencyData);
     // render frame based on values in frequencyData
     // console.log(frequencyData)
  }
  audio.start();
  renderFrame();
};

Web Audio API + Canvas + Some math. I would have chosen a different track though 😉

How to create Audio-Visualizations with JavaScript & HTML →
Realtime Audio-Visualizations (Demo) →

Isomer – An isometric graphics library for HTML5 canvas

isomer

var Shape = Isomer.Shape;
var Point = Isomer.Point;

iso.add([
  Shape.Prism(Point.ORIGIN, 3, 3, 1),
  Shape.Pyramid(new Point(0, 0, 1)),
  Shape.Pyramid(new Point(0, 2, 1)),
  Shape.Pyramid(new Point(2, 0, 1)),
  Shape.Pyramid(new Point(2, 2, 1))
]);

Did somebody out there recreate Monument Valley using this yet?

Isomer →