
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Pinch to zoom text, not the page. Canvas-based text scaling for mobile web.
Three canvas-based text effects for mobile web, built on @chenglou/pretext.
npm install pinch-type @chenglou/pretext
import { createPinchType, createScrollMorph, createPinchMorph } from 'pinch-type';
// 1. Pinch Type — uniform text, pinch gestures scale all text
const pt = createPinchType(document.getElementById('reader'));
pt.setText('Your long article text here…');
// 2. Scroll Morph — fisheye effect, no pinch zoom
const sm = createScrollMorph(document.getElementById('reader'));
sm.setText('Your long article text here…');
// 3. Combined — fisheye + pinch-to-zoom (the original behavior)
const pm = createPinchMorph(document.getElementById('reader'));
pm.setText('Your long article text here…');
// Clean up when done:
instance.destroy();
The container element should have a defined width and height (e.g. 100vw × 100vh). Each function creates a fullscreen <canvas> inside it.
createPinchType(element, options?)Uniform text rendering with pinch-to-zoom scaling.
| Option | Type | Default | Description |
|---|---|---|---|
fontSize | number | 18 | Base font size |
minFontSize | number | 8 | Smallest size reachable via pinch |
maxFontSize | number | 60 | Largest size reachable via pinch |
fontFamily | string | "Inter", system-ui, sans-serif | CSS font-family |
lineHeight | number | 1.57 | Line-height ratio |
padding | number | 28 | Content padding (px) |
background | string | #0a0a0a | Canvas background color |
friction | number | 0.95 | Scroll momentum friction (0–1) |
onZoom | (fontSize) => void | — | Callback after each pinch zoom |
createScrollMorph(element, options?)Fisheye scroll effect. No pinch-to-zoom.
| Option | Type | Default | Description |
|---|---|---|---|
centerFontSize | number | 26 | Font size at viewport center |
edgeFontSize | number | 11 | Font size at viewport edges |
morphRadius | number | 300 | Radius (px) of the center→edge gradient |
fontFamily | string | "Inter", system-ui, sans-serif | CSS font-family |
lineHeight | number | 1.57 | Line-height ratio |
padding | number | 28 | Content padding (px) |
background | string | #0a0a0a | Canvas background color |
friction | number | 0.95 | Scroll momentum friction (0–1) |
createPinchMorph(element, options?)Combined: fisheye scroll effect + pinch-to-zoom.
| Option | Type | Default | Description |
|---|---|---|---|
centerFontSize | number | 26 | Font size at viewport center |
edgeFontSize | number | 11 | Font size at viewport edges |
minFontSize | number | 8 | Smallest size reachable via pinch |
maxFontSize | number | 60 | Largest size reachable via pinch |
morphRadius | number | 300 | Radius (px) of the center→edge gradient |
fontFamily | string | "Inter", system-ui, sans-serif | CSS font-family |
lineHeight | number | 1.57 | Line-height ratio |
padding | number | 28 | Content padding (px) |
background | string | #0a0a0a | Canvas background color |
friction | number | 0.95 | Scroll momentum friction (0–1) |
onZoom | (center, edge) => void | — | Callback after each pinch zoom |
| Method | Description |
|---|---|
setText(text) | Update displayed text and re-layout |
resize() | Force re-layout (auto-called on window resize) |
destroy() | Remove canvas, listeners, and animation loop |
canvas | The underlying <canvas> element (read-only) |
Just want pinch-to-zoom on your existing page? Use the lightweight API — no canvas, no dependencies, ~1KB. Want the full canvas rendering experience? Use createPinchType / createScrollMorph / createPinchMorph above.
pinchZoom(options?) — Vanilla JSimport { pinchZoom } from 'pinch-type';
const cleanup = pinchZoom({
target: document.getElementById('article'), // default: document.documentElement
min: 12, // min font size, default 12
max: 32, // max font size, default 32
initial: 16, // starting size, default 16
step: 1, // px per zoom step, default 1
onZoom: (size) => console.log(size),
});
// Later: remove all listeners
cleanup();
Detects two-finger touch pinch and trackpad pinch (ctrl+wheel / meta+wheel). Single-finger scroll is unaffected. Applies font-size directly to the target element.
usePinchZoom(options?) — React HookRequires react as a peer dependency.
import { usePinchZoom } from 'pinch-type';
function Reader() {
const { fontSize, ref } = usePinchZoom({ min: 12, max: 32 });
return <article ref={ref} style={{ fontSize }}>...</article>;
}
| Option | Type | Default | Description |
|---|---|---|---|
min | number | 12 | Minimum font size |
max | number | 32 | Maximum font size |
initial | number | 16 | Starting font size |
step | number | 1 | Pixels per zoom step |
onZoom | (size) => void | — | Callback after each zoom |
Text is measured and wrapped using @chenglou/pretext for accurate segment-aware line breaking. Each frame, lines are drawn to a canvas. For scroll morph, font size and opacity are interpolated based on distance from the viewport center (ease-out cubic). Touch events drive momentum scrolling with configurable friction, and two-finger pinch gestures scale the font size range in real time.
MIT — Lucas Crespo
FAQs
Pinch to zoom text, not the page. Canvas-based text scaling for mobile web.
We found that pinch-type demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.