Интерактивная компьютерная графика

порт демок из курса Такео Игараши на JavaScript

Bubble demo

Наткнулся на онлайн-курс Interactive Computer Graphics от Такео Игараши — японского исследователя в области HCI и компьютерной графики. К части демонстраций прилагался исходный код на Java. Захотелось оживить их в браузере.

Демок три:

  • Ninja Cursors — несколько виртуальных курсоров, управляемых одной мышью. Разные стратегии выбора активного курсора: очередь, одновременная активация, расширяющиеся пузыри-допуски. Идея в том, что на большом экране одного курсора мало.

  • Autozoom — перетаскивание фрактальной плитки. Чем быстрее тянешь — тем сильнее масштаб «съезжает», чтобы картинка не размывалась в кашу. При отпускании плавно возвращается к нормальному масштабу.

  • Bubble — жёлтые квадраты, которые при сближении объединяются в «пузыри» с плавной границей. Пузыри можно таскать целиком, двойной клик — разбрасывает квадраты в стороны и возвращает обратно.

Технически

Проект собирается Vite как multi-page app — каждая демка живёт в своём подкаталоге со своим index.html. Ninja Cursors и Autozoom написаны на TypeScript, Bubble — на чистом JavaScript (оригинал был на Java, без типов, так и оставил).

Никаких фреймворков — только Canvas 2D и браузерные API.

Ninja Cursors

Самое интересное здесь — Pointer Lock API: мышь захватывается, и дальше работаем с относительным смещением, а не с координатами. Курсоры двигаются в пределах канваса, оборачиваясь через края.

Четыре режима переключаются клавишами 1–4. В режиме Bubble каждый курсор рисует расширяющуюся окружность — цель захватывается, когда круг её касается.

Autozoom

Паттерны — два рисунка (медвежонок и муравей), нарисованных отрезками. Они тайлятся на плоскости на двух масштабных уровнях (×1 и ×0.1), образуя фрактал. Логика ускорения/замедления скролла и анимации возврата масштаба взята один в один из оригинального Java-апплета.

Bubble

Самая интересная часть с точки зрения алгоритмов.

Каждый квадрат — источник радиального поля (метабол). Граница кластера — изолиния поля на уровне 1.0. Строится методом Marching Squares: сетка, 16 вариантов ячеек, трассировка замкнутых полигонов, сглаживание Лапласа.

Объединение квадратов в кластеры — Union-Find с гистерезисом: порог слияния и порог разъединения разные (50 и 80 пикселей), чтобы граница не дёргалась туда-сюда.

Анимация «разброса» — итеративное расталкивание точек до минимального расстояния, потом smooth-step интерполяция туда и обратно через requestAnimationFrame.