Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ascorbic/react-artboard
A realistic paint component
https://github.com/ascorbic/react-artboard
paint-application painting react
Last synced: 13 days ago
JSON representation
A realistic paint component
- Host: GitHub
- URL: https://github.com/ascorbic/react-artboard
- Owner: ascorbic
- Created: 2021-01-16T12:14:29.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2022-04-09T10:07:35.000Z (over 2 years ago)
- Last Synced: 2024-04-09T14:23:25.948Z (7 months ago)
- Topics: paint-application, painting, react
- Language: TypeScript
- Homepage: https://react-artboard.netlify.app/
- Size: 2.9 MB
- Stars: 73
- Watchers: 5
- Forks: 10
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# react-artboard
A freeform sketching component for React.
[Try the demo](https://react-artboard.netlify.app/)![artboard](https://raw.githubusercontent.com/ascorbic/react-artboard/main/artboard.png)
![shading](https://raw.githubusercontent.com/ascorbic/react-artboard/main/images/shading.gif)
react-artboard includes an `Artboard` component and several tools, including a
realistic paintbrush, a marker pen and airbrush, as well as the abstract shading
tool. Tools are implemented as custom hooks, so you can add your own brushes and
other tools.[Try the demo](https://react-artboard.netlify.app/)
- [react-artboard](#react-artboard)
- [Installation](#installation)
- [Usage](#usage)
- [API](#api)
- [`Artboard`](#artboard)
- [Props](#props)
- [Paintbrush](#paintbrush)
- [Options](#options)
- [Shading](#shading)
- [Options](#options-1)
- [Watercolor](#watercolor)
- [Options](#options-2)
- [Marker pen](#marker-pen)
- [Options](#options-3)
- [Airbrush](#airbrush)
- [Options](#options-4)
- [Custom brushes](#custom-brushes)
- [History](#history)
- [Sources](#sources)## Installation
```shell
npm install react-artboard
```## Usage
For a full usage example, see
[this file](https://github.com/ascorbic/react-artboard/blob/main/example/App.tsx).
The simplest usage of the component is like this:```jsx
import React from "react";
import { useBrush, Artboard } from "react-artboard";
export function App() {
const brush = useBrush({ color: "#663399", strokeWidth: 40 });return ;
}
```You probably want to allow users to change the colors and size of the brush.
Here is an example that uses native `color` and `range` inputs:```jsx
import React, { useState } from "react";
import { useBrush, Artboard } from "react-artboard";
export function App() {
const [color, setColor] = useState("#993366");
const [strokeWidth, setStrokeWidth] = useState(40);
const brush = useBrush({ color, strokeWidth });return (
setColor(evt.currentTarget.value)}
/>
setStrokeWidth(parseInt(evt.currentTarget.value))}
/>
);
}
```You could use a custom component instead of these inputs if you want more
control over them, as long as they return a number for the brush size and a
string for the color.If you want to export your creations or clear the canvas, you can use the ref
like this:```jsx
import React, { useState } from "react";
import { useBrush, Artboard } from "react-artboard";
export function App() {
const [color, setColor] = useState("#993366");
const [strokeWidth, setStrokeWidth] = useState(40);
const brush = useBrush({ color, strokeWidth });const [artboardRef, setArtboardRef] = useState();
return (
artboardRef?.download()}>Download
artboardRef?.clear()}>Clear
setColor(evt.currentTarget.value)}
/>
setStrokeWidth(parseInt(evt.currentTarget.value))}
/>
);
}
```## API
### `Artboard`
#### Props
- **`tool`**
This is the tool returned by the `useBrush()` hook. You can also implement
your own tools and pass them in here.- **`ref`**
This accepts a callback that will be passed a ref that you can use to make the
following calls:- **`download`**: `(filename: string, type: string) => void`
Downloads the canvas as an image. You can pass in a filename (default
"image.png"), and a mimetype (default "image/png"). If you pass an
unsupported type it will fallback to PNG.- **`getImageAsDataUri`**: `(type: string) => string | undefined`
Returns the image as a data URI, which can be displayed in an `` tag
for example.- **`clear`**: `() => void`
Clears the image
- **`context`**: `CanvasRenderingContext2D | null | undefined`
Canvas rendering context
- **`onStartStroke`**: `(point: Point) => void`
Callback at the start of a stroke
- **`onContinueStroke`**: `(point: Point) => void`
Callback at the continuing of a stroke
- **`onEndStroke`**: `() => void`
Callback at the end of a stroke
### Paintbrush
`useBrush(options)`
![paint](https://raw.githubusercontent.com/ascorbic/react-artboard/main/images/paint.png)
#### Options
- **`color`** A CSS string color.
- **`strokeWidth`** The width of the brush### Shading
`useShadingBrush()`
This tools is inspired by [some blog posts](#sources), exploring the use of
"neighbour point" sketching. It gives a fun, unusual effect that is similar to
pencil shading. It is highly configurable, giving quite different effects
according to the different parameters.![shading](https://raw.githubusercontent.com/ascorbic/react-artboard/main/images/shading.png)
#### Options
- **`color`** A CSS string color. _Default: `#000000`_
- **`spreadFactor`** The length of the connecting line. A value of `1` means it
exactly joins the two points, while `0.5` only covers half the distance. A
value above `1` gives a "fur" effect as the line extends beyond the points.
_Default: 0.9_
- **`distanceThreshold`** How near the point needs to be to join, in pixels.
_Default: 50_
- **`neighbourStrokeWidth`** Width of the stroke joining the points. _Default:
1_
- **`neighbourColor`** Color of the line joining the points. _Default: `color`
value with 0.2 alpha_### Watercolor
`useWatercolor(options)`
![paint](https://raw.githubusercontent.com/ascorbic/react-artboard/main/images/watercolor.png)
#### Options
- **`color`** A CSS string color.
- **`strokeWidth`** The width of the brush### Marker pen
`useMarker(options)`
![marker](https://raw.githubusercontent.com/ascorbic/react-artboard/main/images/marker.png)
#### Options
- **`color`** A CSS string color.
- **`strokeWidth`** The width of the brush### Airbrush
`useAirbrush(options)`
![airbrush](https://raw.githubusercontent.com/ascorbic/react-artboard/main/images/airbrush.png)
#### Options
- **`color`** A CSS string color.
- **`strokeWidth`** The width of the brush## Custom brushes
See the source for `useBrush` to see how to create a brush. It must return an
object, with the following optional callbacks:- **`startStroke?`**:
`(point: Point, context: CanvasRenderingContext2D) => void`
- **`continueStroke?`**:
`(point: Point, context: CanvasRenderingContext2D) => void`
- **`endStroke?`**: `(context: CanvasRenderingContext2D) => void`
- **`cursor?`**: `string` A CSS-compatible string for the cursor to display. You
can use the `circleCursor()` helper to display a resizable circle for the
cursor## History
The `useHistory()` hook allows undo/redo functionality. Pass it a `size` value
to limit the size of the history stack. It returns and object with the
following:- **`history`**: The `History` object. Pass this to the `Artboard`.
- **`undo()`**: Reverts the image to the previous state.
- **`redo()`**: Move forward in history, if available.
- **`canUndo`**: History is available to undo
- **`canRedo`**: History is available to redo## Sources
These posts gave inspiration, particularly for the shading tool.
- [Exploring canvas drawing techniques](http://perfectionkills.com/exploring-canvas-drawing-techniques/)
- [Harmony brush adoption in Krita: Sketch](http://lukast.mediablog.sk/log/?p=347)Inspiration for the watercolor tool:
- [Generative watercolor in Processing](https://sighack.com/post/generative-watercolor-in-processing)
- [How to hack a painting](https://tylerxhobbs.com/essays/2020/how-to-hack-a-painting)© Copyright [Matt Kane](https://mk.gg)
([@ascorbic](https://github.com/ascorbic)) 2021. MIT Licence