Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add clearCanvas option #20

Merged
merged 1 commit into from
Jul 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 58 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -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:
Expand All @@ -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',
Expand All @@ -68,17 +82,20 @@ A function returned from this factory has the following signature:
```

### drawMethods

```js
{
FILL: 'FILL',
STROKE: 'STROKE',
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,
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -200,32 +228,36 @@ 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).
Some example values that you can use: `fillStyle`, `strokeStyle`, `lineWidth`, `filter` and so on.
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.

8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand All @@ -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",
Expand Down
6 changes: 5 additions & 1 deletion src/createDrawFunction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ type DrawFunctionProps<
canvasWidth?: number;
canvasHeight?: number;
camera?: Camera;
clearCanvas?: boolean;
};

function createDrawFunction<CH extends DrawHandlersDictionary<keyof CH>>(
Expand All @@ -79,8 +80,11 @@ function createDrawFunction<CH extends DrawHandlersDictionary<keyof CH>>(
zoom: 1,
rotation: 0,
},
clearCanvas = true,
}: DrawFunctionProps<typeof defaultDrawHandlers & CH>): 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);
Expand Down