Алгоритм примерно такой:
- Берем обычный canvas, на нем что-то пишем или выводим картинку (в данном случае строго 2 цвета).
- Берем imageData у того, что получилось.
- Проходим по всем пикселям этой imageDatы с каким-то шагом, делаем объект "частица" с нужными координатами когда цвет соответствует определенному (если писали черным по белому - значит если цвет пикселя черный).
- Стираем надпись.
- Проходим по массиву частиц, рисуем небольшой круг (что угодно, но пусть будет круг) на месте с координатами этой частицы.
- PROFIT.
По вкусу к частице добавляется параметр "цвет" (лучше полупрозрачный) и "размер". Можно сделать функцию обновления, которая будет менять эти параметры и координаты, requestAnimationFrame нам в помощь. Координаты частицы меняются по определенному закону в каком-то радиусе от ее изначального положения, можно взять параметрическое уравнение любой замкнутой кривой и использовать его для вычисления отклонения частицы от ее изначального положения.