Skip to content

Space Adventure

This demo uses pinch() from @cereb/pinch to implement zoom in/out on a space-themed canvas with stars and nebulae.

Zoom Mode
Tip. Pinch or change slider to zoom.
In Desktop, use 'z' + '+/-' or 'wheel' to zoom.
Zoom
Signal Snapshot
SCALE 1.00
INPUT -

Code

import { wheel, keyboard, keyboardHeld, domEvent } from "cereb";
import { zoom, extend, when } from "cereb/operators";
import { pinch } from "@cereb/pinch";
// 'z' key pressed to enter Zoom Mode Stream
const isInZoomMode$ = keyboardHeld(window, { key: "z" });
isInZoomMode$.on(toggleZoomModeIndicator);
// Pinch Zoom
pinch(box, { threshold: 10 })
.pipe(
zoom({ minScale: MIN_SCALE, maxScale: MAX_SCALE })
)
.on(render);
// 'z' + '+/-'
keyboard(window, { key: ["+", "=", "-"], preventDefault: true })
.pipe(
when(isInZoomMode$),
extend<KeyboardSignal, ZoomInput>((signal) => ({
ratio: zoomManager.getScale() + (signal.value.key === "+" || signal.value.key === "=" ? 0.15 : -0.15),
})),
zoom({ minScale: MIN_SCALE, maxScale: MAX_SCALE }),
)
.on(render);
// 'CTRL' + 'wheel'
wheel(box, { passive: false, preventDefault: true })
.pipe(
when(isInZoomMode$),
extend<WheelSignal, ZoomInput>((signal) => ({
ratio: zoomManager.getScale() + (-signal.value.deltaY * 0.005),
})),
zoom({ minScale: MIN_SCALE, maxScale: MAX_SCALE }),
)
.on(render);
// 'Slider Input'
domEvent(slider, "input")
.pipe(
extend<DomEventSignal<Event>, ZoomInput>((signal) => {
const inputElement = signal.value.target as HTMLInputElement;
const value = Number(inputElement.value);
const logScale = logMin + (value / 100) * (logMax - logMin);
const scale = Math.exp(logScale);
return {
ratio: clamp(scale, MIN_SCALE, MAX_SCALE),
};
}),
zoom({ minScale: MIN_SCALE, maxScale: MAX_SCALE, baseScale: zoomManager.getScale() }),
)
.on(render);