Skip to content

Commit

Permalink
doc updates
Browse files Browse the repository at this point in the history
  • Loading branch information
Christoph Nölle committed Mar 23, 2022
1 parent fbd5924 commit a3fa0ea
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 54 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ HTML example:
<body>
<canvas2d-zoom width="640" height="480" min-zoom="0.25" max-zoom="8"></canvas2d-zoom>
<script type="module">
import { Canvas2dZoom } from "canvas2d-zoom"; // TODO unpkg link?
import { Canvas2dZoom } from "canvas2d-zoom";
Canvas2dZoom.register();
const canvas = document.querySelector("canvas2d-zoom");
const ctx = canvas.getContext("2d");
Expand All @@ -47,7 +47,7 @@ ctx.stroke();

## Configuration

All `canvas` attributes are supported, such as `width` and `height`. Furthermore,
The `canvas` attributes `width` and `height` are supported, and furthermore:

* **zoom**: A boolean value, can be used to disable zoom behaviour. Default value: `"true"`
* **pan**: A boolean value, can be used to disable pan behaviour. Default value: `"true"`
Expand Down Expand Up @@ -75,7 +75,7 @@ Currently only mouse and keyboard interactions are supported (no mobile gestures

## How it works

The element remembers all calls to the [CanvasRenderingContext2D](https://developer.mozilla.org/de/docs/Web/API/CanvasRenderingContext2D) methods relevant to drawing, such `ctx.beginPath()`, `ctx.rect()` or `ctx.stroke()`. When the user pans or zooms (via mouse or keyboard interactions), the canvas is cleared, a transformation appropriate for the zoom and pan state is set, and the canvas is redrawn.
The element remembers all calls to the [CanvasRenderingContext2D](https://developer.mozilla.org/de/docs/Web/API/CanvasRenderingContext2D) methods relevant to drawing, such as `ctx.beginPath()`, `ctx.rect()` or `ctx.stroke()`. When the user pans or zooms (via mouse or keyboard interactions), the canvas is cleared, a transformation appropriate for the zoom and pan state is set, and the canvas is redrawn.

## Development

Expand Down
71 changes: 42 additions & 29 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/**
* A webcomponent that wraps a 2D HTML canvas element, making it zoomable and pannable.
* The default tag name is "canvas2d-zoom".
* Usage: add a tag <canvas2d-zoom> to your HTML, import this module in Javascript and call CanvasZoom.register() once.
* Usage: add a tag <canvas2d-zoom> to your HTML, import this module in Javascript and call Canvas2dZoom.register() once.
* Drawing on the canvas should work like for ordinary 2D canvas, i.e. (in typescript, for javascript remove types)
* <code>
* CanvasZoom.register();
* const canvas: CanvasZoom = document.querySelector("canvas2d-zoom");
* Canvas2dZoom.register();
* const canvas: Canvas2dZoom = document.querySelector("canvas2d-zoom");
* const ctx: CanvasRenderingContext2D = canvas.getContext("2d");
* ctx.beginPath();
* ...
Expand All @@ -14,44 +14,58 @@
export declare class Canvas2dZoom extends HTMLElement {
/**
* Call once to register the new tag type "<canvas2d-zoom></canvas2d-zoom>"
* @param tag
* @param tag may be used to register a different tag name.
*/
static register(tag?: string): void;
/**
* Retrieve the registered tag type for this element type, or undefined if not registered yet.
*/
static tag(): string | undefined;
get debug(): boolean;
set debug(debug: boolean);
get width(): number;
set width(width: number);
get height(): number;
set height(height: number);
get zoom(): boolean;
set zoom(zoom: boolean);
get pan(): boolean;
set pan(pan: boolean);
get maxZoom(): number | undefined;
set maxZoom(max: number | undefined);
get minZoom(): number | undefined;
set minZoom(min: number | undefined);
get zoomFactor(): number;
/**
* Gets or sets the debug property. If set to true, some debug methods will be available on the HTMLElement. Default: false.
*/
debug: boolean;
/**
* Gets or sets the height of a canvas element on a document.
*/
height: number;
/**
* Gets or sets the width of a canvas element on a document.
*/
width: number;
/**
* Controls whether the user can zoom in and out on the canvas. Default: true.
*/
zoom: boolean;
/**
* Controls whether the user can pan/move the canvas. Default: true.
*/
pan: boolean;
/**
* Controls the maximum zoom level of the canvas. A number > 1. Default: undefined
*/
maxZoom: number | undefined;
/**
* Controls the minimum zoom level of the canvas. A number < 1. Default: undefined
*/
minZoom: number | undefined;
/**
* The zoom factor determines how fast the zoom effect is, larger values lead to faster zoom.
* factor must be positive, and usually is greater than 1. Default value: 2.
* A positive number, usually greater than 1. Default value: 2.
*/
set zoomFactor(factor: number);
get overlapX(): number;
get overlapY(): number;
zoomFactor: number;
/**
* Indicates that upon zoom or pan operations a region beyond the horizontal vertical borders
* of the canvas needs to be cleared (for positive values), resp. a certain area within
* the visible range shall not be cleared (for negative values). Default: 0.
*/
set overlapX(pixels: number);
overlapX: number;
/**
* Indicates that upon zoom or pan operations a region beyond the visible vertical borders
* of the canvas needs to be cleared (for positive values), resp. a certain area within
* the visible range shall not be cleared (for negative values). Default: 0.
*/
set overlapY(pixels: number);
overlapY: number;
/**
* Returns an object that provides methods and properties for drawing and manipulating images and graphics on a
* 2D canvas element in a document. A context object includes information about colors, line widths, fonts, and
Expand All @@ -62,8 +76,7 @@ export declare class Canvas2dZoom extends HTMLElement {
*/
getContext(type: "2d", options?: CanvasRenderingContext2DSettings): CanvasRenderingContext2D;
/**
* The wrapped canvas element. Usually this should not be used directly;
* all drawings via canvas().getContext("2d") will disappear on zoom and/or pan.
* Returns the wrapped canvas element.
*/
canvas(): HTMLCanvasElement;
/**
Expand All @@ -79,8 +92,8 @@ export declare class Canvas2dZoom extends HTMLElement {
applyZoom(scale: number, center?: DOMPointInit): void;
/**
* Move/pan/translate the canvas.
* @param x
* @param y
* @param x number of horizontal pixels
* @param y number of vertical pixels
*/
applyTranslation(x: number, y: number): void;
}
9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "canvas2d-zoom",
"version": "0.1.0",
"description": "",
"description": "A webcomponent that adds zoom and pan behaviour to a canvas element",
"type": "module",
"exports": "./dist/canvas2d-zoom.js",
"files": [
Expand All @@ -15,17 +15,16 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/cnoelle/canvas-zoom.git"
"url": "git+https://github.com/cnoelle/canvas2d-zoom.git"
},
"keywords": ["canvas", "zoom"],
"author": "cnoelle",
"license": "MIT",
"bugs": {
"url": "https://github.com/cnoelle/canvas-zoom/issues"
"url": "https://github.com/cnoelle/canvas2d-zoom/issues"
},
"homepage": "https://github.com/cnoelle/canvas-zoom#readme",
"homepage": "https://github.com/cnoelle/canvas2d-zoom#readme",
"devDependencies": {
"@types/node": "^17.0.21",
"cpy-cli": "^4.1.0",
"del-cli": "^4.0.1",
"html-webpack-plugin": "^5.5.0",
Expand Down
9 changes: 5 additions & 4 deletions src/ContextProxy.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export class ContextProxy implements ProxyHandler<CanvasRenderingContext2D> {

// zoom related
#maxZoom: number|undefined = 6;
#minZoom: number|undefined = 0.1;
#maxZoom: number|undefined = undefined;
#minZoom: number|undefined = undefined;
#zoomFactor: number = 2;

#clearXBorder: number = 0;
Expand All @@ -13,9 +13,10 @@ export class ContextProxy implements ProxyHandler<CanvasRenderingContext2D> {

get(target: CanvasRenderingContext2D, p: PropertyKey): any {
const result = (target as any)[p];
if (typeof result !== "function" || (typeof p === "string" && p.startsWith("get"))) {
if (typeof result !== "function")
return result;
if (typeof p === "string" && p.startsWith("get"))
return result.bind(target);
}
const pipe: Array<CallObject> = this.#pipe;
function _internalFunc() {
pipe.push({target: target, key: p, arguments: arguments, type: "method"});
Expand Down
62 changes: 49 additions & 13 deletions src/canvas2d-zoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { MouseEventListener, Point } from "./internalTypes.js";
/**
* A webcomponent that wraps a 2D HTML canvas element, making it zoomable and pannable.
* The default tag name is "canvas2d-zoom".
* Usage: add a tag <canvas2d-zoom> to your HTML, import this module in Javascript and call CanvasZoom.register() once.
* Usage: add a tag <canvas2d-zoom> to your HTML, import this module in Javascript and call Canvas2dZoom.register() once.
* Drawing on the canvas should work like for ordinary 2D canvas, i.e. (in typescript, for javascript remove types)
* <code>
* CanvasZoom.register();
* const canvas: CanvasZoom = document.querySelector("canvas2d-zoom");
* Canvas2dZoom.register();
* const canvas: Canvas2dZoom = document.querySelector("canvas2d-zoom");
* const ctx: CanvasRenderingContext2D = canvas.getContext("2d");
* ctx.beginPath();
* ...
Expand All @@ -36,6 +36,9 @@ export class Canvas2dZoom extends HTMLElement {
}
}

/**
* Retrieve the registered tag type for this element type, or undefined if not registered yet.
*/
static tag(): string|undefined {
return Canvas2dZoom._tag;
}
Expand Down Expand Up @@ -122,14 +125,19 @@ export class Canvas2dZoom extends HTMLElement {
return this.getAttribute("debug")?.toLowerCase() === "true";
}

/**
* Gets or sets the debug property. If set to true, some debug methods will be available on the HTMLElement. Default: false.
*/
set debug(debug: boolean) {
this.setAttribute("debug", debug + "");
}

get width(): number {
return this.#canvas.width;
}

/**
* Gets or sets the width of a canvas element on a document.
*/
set width(width: number) {
this.setAttribute("width", width + "");
}
Expand All @@ -138,6 +146,9 @@ export class Canvas2dZoom extends HTMLElement {
return this.#canvas.height;
}

/**
* Gets or sets the height of a canvas element on a document.
*/
set height(height: number) {
this.setAttribute("height", height + "");
}
Expand All @@ -155,7 +166,9 @@ export class Canvas2dZoom extends HTMLElement {
get zoom(): boolean {
return this.#zoom;
}

/**
* Controls whether the user can zoom in and out on the canvas. Default: true.
*/
set zoom(zoom: boolean) {
this.setAttribute("zoom", zoom + "");
}
Expand All @@ -169,15 +182,19 @@ export class Canvas2dZoom extends HTMLElement {
get pan(): boolean {
return this.#pan;
}

/**
* Controls whether the user can pan/move the canvas. Default: true.
*/
set pan(pan: boolean) {
this.setAttribute("pan", pan + "");
}

get maxZoom(): number|undefined {
return this.#proxy.getMaxZoom();
}

/**
* Controls the maximum zoom level of the canvas. A number > 1. Default: undefined
*/
set maxZoom(max: number|undefined) {
if (isFinite(max))
this.setAttribute("max-zoom", max + "");
Expand All @@ -188,7 +205,9 @@ export class Canvas2dZoom extends HTMLElement {
get minZoom(): number|undefined {
return this.#proxy.getMinZoom();
}

/**
* Controls the minimum zoom level of the canvas. A number < 1. Default: undefined
*/
set minZoom(min: number|undefined) {
if (isFinite(min))
this.setAttribute("min-zoom", min + "");
Expand All @@ -203,7 +222,7 @@ export class Canvas2dZoom extends HTMLElement {

/**
* The zoom factor determines how fast the zoom effect is, larger values lead to faster zoom.
* factor must be positive, and usually is greater than 1. Default value: 2.
* A positive number, usually greater than 1. Default value: 2.
*/
set zoomFactor(factor: number) {
this.setAttribute("zoom-factor", factor + "");
Expand Down Expand Up @@ -235,7 +254,7 @@ export class Canvas2dZoom extends HTMLElement {
this.setAttribute("overlap-y", pixels+ "");
}

// ============= End Properties ===============
// ============= Internal methods ===============

connectedCallback() {
if (!this.hasAttribute("tabindex"))
Expand Down Expand Up @@ -294,18 +313,35 @@ export class Canvas2dZoom extends HTMLElement {
}
}

// ============= API ===============

/**
* Returns an object that provides methods and properties for drawing and manipulating images and graphics on a
* 2D canvas element in a document. A context object includes information about colors, line widths, fonts, and
* other graphic parameters that can be drawn on a canvas.
* (from HTMLCanvasElement)
* @param type
* @param options
*/
getContext(type: "2d", options?: CanvasRenderingContext2DSettings): CanvasRenderingContext2D {
if (type !== "2d")
throw new Error("This canvas only supports 2d mode, invalid context id " + type);
return new Proxy(this.#canvas.getContext("2d", options), this.#proxy);
}

/**
* The wrapped canvas element. Usually this should not be used directly;
* all drawings via canvas().getContext("2d") will disappear on zoom and/or pan.
* Returns the wrapped canvas element.
*/
canvas(): HTMLCanvasElement {
return this.#canvas;
const c2d: Canvas2dZoom = this;
return new Proxy(this.#canvas, {
get(target: HTMLCanvasElement, p: PropertyKey): any {
if (p === "getContext")
return c2d.getContext.bind(c2d);
const result: any = (target as any)[p];
return typeof result === "function" ? result.bind(target) : result;
}
});
}

/**
Expand Down

0 comments on commit a3fa0ea

Please sign in to comment.