diff --git a/README.md b/README.md index 324d644..a6a0f5a 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,19 @@ # declarative-canvas + [![npm version](https://badge.fury.io/js/declarative-canvas.svg)](https://www.npmjs.com/package/declarative-canvas) JavaScript/TypeScript library which lets you draw on HTML5 Canvas in a declarative way. ## Installation + ``` npm install declarative-canvas ``` ## Example Usage + The following code draws a rectangle and a circle on a canvas. + ```js import { createDrawFunction, objectTypes } from 'declarative-canvas'; @@ -27,20 +31,26 @@ draw({ context, objects: objectsToRender }); ``` ## Storybook + More examples can be found in the [storybook](https://lukix.github.io/declarative-canvas). Source code of storybook stories is placed in the [src/stories](./src/storybook/stories) directory. ## API Reference + `declarative-canvas` exports four objects/functions: + - `createDrawFunction` - draw function factory, - `objectTypes` - dictionary object of available object types which can be drawn, - `drawMethods` - dictionary object of available drawing methods. - `convertCanvasCoordinates` - lets you convert canvas coordinates to base coordinates that you use to render objects. ### createDrawFunction + A factory function that takes one optional argument: + ```ts -(customDrawHandlers = {}) => Function +(customDrawHandlers = {}) => Function; ``` + `customDrawHandlers` argument is described in [Custom draw handlers](#custom-draw-handlers) chapter. A function returned from this factory has the following signature: @@ -52,10 +62,14 @@ A function returned from this factory has the following signature: canvasWidth = context.canvas && context.canvas.width, canvasHeight = context.canvas && context.canvas.width, camera = { position: { x: canvasWidth / 2, y: canvasHeight / 2 }, zoom: 1, rotation: 0 }, + clearCanvas = true, }) => void ``` +`clearCanvas` option clears canvas before rendering objects. + ### objectTypes + ```js { CIRCLE: 'CIRCLE', @@ -68,6 +82,7 @@ A function returned from this factory has the following signature: ``` ### drawMethods + ```js { FILL: 'FILL', @@ -75,10 +90,12 @@ A function returned from this factory has the following signature: FILL_AND_STROKE: 'FILL_AND_STROKE', } ``` + Draw method tells the renderer if the given graphical object should be drawn by filling it with some color or just by drawing its outline (or both). ### convertCanvasCoordinates + ```ts ( x: number, @@ -88,11 +105,13 @@ or just by drawing its outline (or both). camera: Camera ) => { x: number, y: number } ``` + A function that converts canvas coordinates (for example `event.offsetX` and `event.offsetY` from `onclick` event) to base coordinates that you use to render objects (taking into account any transformations caused by camera's position, rotation and zoom). ## Available graphical objects ### Rectangle + ```ts { type: objectTypes.RECT; @@ -105,16 +124,17 @@ A function that converts canvas coordinates (for example `event.offsetX` and `ev rotation?: number; } ``` -`contextProps` - [Canvas context props](#Context-Props). *Default: `{}`* -`drawMethod` - [Draw method](#drawMethods). *Default: `drawMethods.FILL`* + +`contextProps` - [Canvas context props](#Context-Props). _Default: `{}`_ +`drawMethod` - [Draw method](#drawMethods). _Default: `drawMethods.FILL`_ `x` - position of the center of rectangle in X axis `y` - position of the center of rectangle in Y axis `width` - rectangle width `height` - rectangle height -`rotation` - rectangle rotation in radians. *Default: `0`* - +`rotation` - rectangle rotation in radians. _Default: `0`_ ### Circle + ```ts { type: objectTypes.CIRCLE; @@ -125,13 +145,15 @@ A function that converts canvas coordinates (for example `event.offsetX` and `ev radius: number; } ``` -`contextProps` - [Canvas context props](#Context-Props). *Default: `{}`* -`drawMethod` - [Draw method](#drawMethods). *Default: `drawMethods.FILL`* + +`contextProps` - [Canvas context props](#Context-Props). _Default: `{}`_ +`drawMethod` - [Draw method](#drawMethods). _Default: `drawMethods.FILL`_ `x` - position of the center of circle in X axis `y` - position of the center of circle in Y axis `radius` - circle radius ### Path + ```ts { type: objectTypes.PATH; @@ -141,12 +163,14 @@ A function that converts canvas coordinates (for example `event.offsetX` and `ev closePath?: boolean, } ``` -`contextProps` - [Canvas context props](#Context-Props). *Default: `{}`* -`drawMethod` - [Draw method](#drawMethods). *Default: `drawMethods.FILL`* + +`contextProps` - [Canvas context props](#Context-Props). _Default: `{}`_ +`drawMethod` - [Draw method](#drawMethods). _Default: `drawMethods.FILL`_ `points` - array of points that make the path -`closePath` - indicates if the last point should be connected to the first point. *Default: `false`* +`closePath` - indicates if the last point should be connected to the first point. _Default: `false`_ ### Image + ```ts { type: objectTypes.IMAGE; @@ -159,15 +183,17 @@ A function that converts canvas coordinates (for example `event.offsetX` and `ev rotation?: number; } ``` -`contextProps` - [Canvas context props](#Context-Props). *Default: `{}`* + +`contextProps` - [Canvas context props](#Context-Props). _Default: `{}`_ `image` - [Image](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image) object `x` - position of the center of image in X axis `y` - position of the center of image in Y axis -`width` - image width. *Defaults to image orginal width* -`height` - image height. *Defaults to image orginal height* -`rotation` - image rotation in radians. *Default: `0`* +`width` - image width. _Defaults to image orginal width_ +`height` - image height. _Defaults to image orginal height_ +`rotation` - image rotation in radians. _Default: `0`_ ### Text + ```ts { type: objectTypes.TEXT; @@ -178,14 +204,16 @@ A function that converts canvas coordinates (for example `event.offsetX` and `ev y: number; } ``` -`contextProps` - [Canvas context props](#Context-Props). *Default: `{}`* -`drawMethod` - [Draw method](#drawMethods). *Default: `drawMethods.FILL`* + +`contextProps` - [Canvas context props](#Context-Props). _Default: `{}`_ +`drawMethod` - [Draw method](#drawMethods). _Default: `drawMethods.FILL`_ `image` - [Image](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image) object `text` - text to be rendered `x` - position of the text in X axis. Text horizontal and vertical align can be adjusted by `contextProps` -`y` - position of the text in Y axis Text horizontal and vertical align can be adjusted by `contextProps` +`y` - position of the text in Y axis Text horizontal and vertical align can be adjusted by `contextProps` ### Transform + ```ts { type: objectTypes.TRANSFORM; @@ -200,17 +228,19 @@ A function that converts canvas coordinates (for example `event.offsetX` and `ev rotation?: number; } ``` -`contextProps` - [Canvas context props](#Context-Props). *Default: `{}`* + +`contextProps` - [Canvas context props](#Context-Props). _Default: `{}`_ `children` - array of graphical objects -`dx` - displacement of child objects in X axis. *Default: `0`* -`dy` - displacement of child objects in Y axis. *Default: `0`* -`scaleX` - scaling of child objects in X axis. *Default: `1`* -`scaleY` - scaling of child objects in Y axis. *Default: `1`* -`skewX` - skew transformation applied to child objects in X axis. *Default: `0`* -`skewY` - skew transformation applied to child objects in Y axis. *Default: `0`* -`rotation` - rotation in radians of child objects. *Default: `0`* +`dx` - displacement of child objects in X axis. _Default: `0`_ +`dy` - displacement of child objects in Y axis. _Default: `0`_ +`scaleX` - scaling of child objects in X axis. _Default: `1`_ +`scaleY` - scaling of child objects in Y axis. _Default: `1`_ +`skewX` - skew transformation applied to child objects in X axis. _Default: `0`_ +`skewY` - skew transformation applied to child objects in Y axis. _Default: `0`_ +`rotation` - rotation in radians of child objects. _Default: `0`_ ## Context Props + For every graphical object you can specify `contextProps` property. Before drawing graphical object, all values of `contextProps` object will be assigned to [Canvas Rendering Context](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D). @@ -218,14 +248,16 @@ Some example values that you can use: `fillStyle`, `strokeStyle`, `lineWidth`, ` After drawing the graphical object, context properties will be restored back to their orginal values. ## Custom draw handlers + If you want to expand the capabilities of `declarative-canvas` to support more object types, you can specify custom draw handlers which will be used to draw objects with specified object type. Draw handler is a function with the following signature: + ```ts (context, options, drawObject) => void ``` + To see examples of draw handlers, you can check out default draw handlers in [src/drawHandlerFunctions](./src/drawHandlerFunctions) directory. Custom handlers can be passed as a `customDrawHandlers` argument to `createDrawFunction`. `customDrawHandlers` should be an object, where keys represent object types and values represent custom handlers. - diff --git a/package.json b/package.json index 6bacd92..2d26f55 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "declarative-canvas", - "version": "1.2.0", + "version": "1.3.0", "main": "lib/index.js", "types": "lib/index.d.ts", "author": "Ɓukasz Jenczmyk", @@ -18,7 +18,11 @@ "type": "git", "url": "git+https://github.com/lukix/declarative-canvas.git" }, - "files": ["lib/", "!lib/storybook/", "!__tests__/"], + "files": [ + "lib/", + "!lib/storybook/", + "!__tests__/" + ], "scripts": { "dev": "tsc --watch", "test": "jest", diff --git a/src/createDrawFunction.ts b/src/createDrawFunction.ts index 90024cc..a93bdcd 100644 --- a/src/createDrawFunction.ts +++ b/src/createDrawFunction.ts @@ -63,6 +63,7 @@ type DrawFunctionProps< canvasWidth?: number; canvasHeight?: number; camera?: Camera; + clearCanvas?: boolean; }; function createDrawFunction>( @@ -79,8 +80,11 @@ function createDrawFunction>( zoom: 1, rotation: 0, }, + clearCanvas = true, }: DrawFunctionProps): void { - context.clearRect(0, 0, canvasWidth, canvasHeight); + if (clearCanvas) { + context.clearRect(0, 0, canvasWidth, canvasHeight); + } context.save(); setCameraTransform({ context, canvasWidth, canvasHeight, camera }); const drawObject = drawObjectFactory(context, drawHandlers);