Pan and zoom SVG, HTML or Canvas using mouse or touch input
npx @tessl/cli install tessl/npm-d3-zoom@3.0.0d3-zoom provides pan and zoom functionality for SVG, HTML, and Canvas elements using mouse, touch, or programmatic control. It implements a comprehensive interaction model that handles browser quirks and provides smooth, configurable zooming and panning behaviors for data visualizations and interactive applications.
npm install d3-zoomimport { zoom, zoomTransform, zoomIdentity, ZoomTransform } from "d3-zoom";For CommonJS:
const { zoom, zoomTransform, zoomIdentity, ZoomTransform } = require("d3-zoom");UMD (via CDN):
<script src="https://cdn.jsdelivr.net/npm/d3-zoom@3"></script>
<script>
const { zoom, zoomTransform, zoomIdentity } = d3;
</script>import { select } from "d3-selection";
import { zoom, zoomIdentity } from "d3-zoom";
// Create zoom behavior
const zoomBehavior = zoom()
.scaleExtent([0.5, 10])
.on("zoom", (event) => {
const { transform } = event;
svg.attr("transform", transform);
});
// Apply to SVG element
const svg = select("svg").call(zoomBehavior);
// Programmatic zoom
svg.transition()
.duration(750)
.call(zoomBehavior.transform, zoomIdentity.scale(2));d3-zoom is built around several key components:
zoom() function creates configurable zoom behavior instancesZoomTransform class represents zoom state with scale and translationCreates and configures zoom behavior instances that can be applied to DOM selections.
function zoom(): ZoomBehavior;
interface ZoomBehavior {
(selection: Selection): void;
transform(selection: Selection | Transition, transform: ZoomTransform | TransformFunction, point?: Point | PointFunction): ZoomBehavior;
translateBy(selection: Selection | Transition, x: number | NumberFunction, y: number | NumberFunction): ZoomBehavior;
translateTo(selection: Selection | Transition, x: number | NumberFunction, y: number | NumberFunction, p?: Point | PointFunction): ZoomBehavior;
scaleBy(selection: Selection | Transition, k: number | NumberFunction, p?: Point | PointFunction): ZoomBehavior;
scaleTo(selection: Selection | Transition, k: number | NumberFunction, p?: Point | PointFunction): ZoomBehavior;
on(typenames: string, listener?: EventListener | null): ZoomBehavior;
}Handles zoom transform state with scale and translation operations, including coordinate conversion.
function zoomTransform(node: Element): ZoomTransform;
class ZoomTransform {
constructor(k: number, x: number, y: number);
readonly k: number;
readonly x: number;
readonly y: number;
scale(k: number): ZoomTransform;
translate(x: number, y: number): ZoomTransform;
apply(point: [number, number]): [number, number];
applyX(x: number): number;
applyY(y: number): number;
invert(location: [number, number]): [number, number];
invertX(x: number): number;
invertY(y: number): number;
rescaleX(x: ContinuousScale): ContinuousScale;
rescaleY(y: ContinuousScale): ContinuousScale;
toString(): string;
}
const zoomIdentity: ZoomTransform;Provides extensive configuration for zoom behavior including scale limits, event filtering, and custom interpolation.
interface ZoomBehavior {
filter(filter?: FilterFunction): ZoomBehavior;
touchable(touchable?: TouchableFunction): ZoomBehavior;
wheelDelta(delta?: WheelDeltaFunction): ZoomBehavior;
extent(extent?: ExtentFunction | [[number, number], [number, number]]): ZoomBehavior;
scaleExtent(extent?: [number, number]): ZoomBehavior;
translateExtent(extent?: [[number, number], [number, number]]): ZoomBehavior;
constrain(constrain?: ConstrainFunction): ZoomBehavior;
duration(duration?: number): ZoomBehavior;
interpolate(interpolate?: InterpolateFunction): ZoomBehavior;
clickDistance(distance?: number): ZoomBehavior;
tapDistance(distance?: number): ZoomBehavior;
}Comprehensive event system for handling zoom interactions and responding to zoom state changes.
interface ZoomEvent {
readonly target: ZoomBehavior;
readonly type: "start" | "zoom" | "end";
readonly transform: ZoomTransform;
readonly sourceEvent: Event;
}
type EventListener = (this: Element, event: ZoomEvent, d?: any) => void;type Point = [number, number];
type PointFunction = (this: Element, event: any, d: any) => Point;
type NumberFunction = (this: Element, event: any, d: any) => number;
type TransformFunction = (this: Element, event: any, d: any) => ZoomTransform;
type FilterFunction = (this: Element, event: Event, d: any) => boolean;
type TouchableFunction = (this: Element) => boolean;
type WheelDeltaFunction = (this: Element, event: WheelEvent, d: any) => number;
type ExtentFunction = (this: Element, d: any) => [[number, number], [number, number]];
type ConstrainFunction = (transform: ZoomTransform, extent: [[number, number], [number, number]], translateExtent: [[number, number], [number, number]]) => ZoomTransform;
type InterpolateFunction = (a: any, b: any) => (t: number) => any;
interface Selection {
call(behavior: ZoomBehavior): Selection;
on(typenames: string, listener?: Function): Selection;
node(): Element;
}
interface Transition {
call(behavior: ZoomBehavior): Transition;
duration(duration: number): Transition;
}
interface ContinuousScale {
copy(): ContinuousScale;
domain(): number[];
domain(domain: number[]): ContinuousScale;
range(): any[];
range(range: any[]): ContinuousScale;
invert(value: any): number;
}