|
2 | 2 |
|
3 | 3 | **[Demo drawing app](https://lazybrush.dulnan.net)**
|
4 | 4 |
|
5 |
| -[Example repository](https://github.com/dulnan/lazy-brush-demo) |
| 5 | +__The demo app also uses |
| 6 | +[catenary-curve](https://github.com/dulnan/catenary-curve) to draw the little |
| 7 | +"rope" between mouse and brush.__ |
6 | 8 |
|
7 | 9 | This library provides the math required to implement a "lazy brush".
|
8 | 10 | It takes a radius and the {x,y} coordinates of a mouse/pointer and calculates
|
9 | 11 | the position of the brush.
|
| 12 | + |
10 | 13 | The brush will only move when the pointer is outside the "lazy area" of the
|
11 | 14 | brush. With this technique it's possible to freely draw smooth lines and curves
|
12 | 15 | with just a mouse or finger.
|
13 | 16 |
|
14 |
| -# How it works |
| 17 | +## How it works |
| 18 | + |
15 | 19 | When the position of the pointer is updated, the distance to the brush is
|
16 | 20 | calculated. If this distance is larger than the defined radius, the brush will
|
17 | 21 | be moved by `distance - radius` pixels in the direction where the pointer is.
|
18 | 22 |
|
19 |
| -# Usage |
| 23 | +## Usage |
| 24 | + |
20 | 25 | lazy-brush is on npm so you can install it with your favorite package manager.
|
21 | 26 |
|
22 | 27 | lazy-brush can be easily added in any canvas drawing scenario. It acts like a
|
23 | 28 | "proxy" between user input and drawing.
|
24 | 29 |
|
| 30 | +It exports a `LazyBrush` class. Create a single instance of the class: |
| 31 | + |
25 | 32 | ```javascript
|
26 | 33 | const lazy = new LazyBrush({
|
27 | 34 | radius: 30,
|
28 | 35 | enabled: true,
|
29 | 36 | initialPoint: { x: 0, y: 0 }
|
30 |
| -}) // default |
| 37 | +}) |
| 38 | +``` |
31 | 39 |
|
32 |
| -lazy.update({ x: 50, y: 0 }) |
| 40 | +You can now use the `update()` method whenever the position of the mouse (or |
| 41 | +touch) changes: |
| 42 | + |
| 43 | +```javascript |
| 44 | +// Move mouse 20 pixels to the right. |
| 45 | +lazy.update({ x: 20, y: 0 }) |
| 46 | +// Brush is not moved, because 20 is less than the radius (30). |
33 | 47 | console.log(lazy.getBrushCoordinates()) // { x: 0, y: 0 }
|
34 | 48 |
|
35 |
| -lazy.update({ x: 200, y: 50 }) |
36 |
| -console.log(lazy.getBrushCoordinates()) // { x: 100, y: 0 } |
| 49 | +// Move mouse 40 pixels to the right. |
| 50 | +lazy.update({ x: 40, y: 0 }) |
| 51 | +// Brush is now moved by 10 pixels because 40 (mouse X) - 30 (radius) = 10. |
| 52 | +console.log(lazy.getBrushCoordinates()) // { x: 10, y: 0 } |
37 | 53 | ```
|
38 | 54 |
|
39 |
| -Use the `LazyBrush.update()` function to update the pointer position. That |
40 |
| -would be when the mouse is moved. The function returns a boolean to indicate |
41 |
| -whether any of the values (brush or pointer) have changed. This can be used to |
42 |
| -prevent unneccessary canvas redrawing. |
| 55 | +The function returns a boolean to indicate whether any of the values (brush or |
| 56 | +pointer) have changed. This can be used to prevent unneccessary canvas |
| 57 | +redrawing. |
| 58 | + |
43 | 59 | If you need to know if the position of the brush was changed, you can get that
|
44 |
| -boolean via LazyBrush.brushHasMoved(). |
| 60 | +boolean via `LazyBrush.brushHasMoved()`. Use this information to decide if you |
| 61 | +need to redraw the brush on the canvas. |
45 | 62 |
|
46 |
| -To get the coordinates , use `LazyBrush.getBrushCoordinates()` or |
47 |
| -`LazyBrush.getPointerCoordinates()`. This will return an object with x and y |
48 |
| -properties. |
| 63 | +To get the current brush coordinates, use `LazyBrush.getBrushCoordinates()`. |
| 64 | +For the pointer coordinates use `LazyBrush.getPointerCoordinates()`. This will |
| 65 | +return a `Point` object with x and y properties. |
49 | 66 |
|
50 | 67 | The functions `getBrush()` and `getPointer()` will return a `LazyPoint`, which
|
51 |
| -has some functions like getDistanceTo, getAngleTo or equalsTo. |
| 68 | +has some additional functions like `getDistanceTo`, `getAngleTo` or `equalsTo`. |
| 69 | + |
| 70 | +### With Friction |
| 71 | + |
| 72 | +You can also pass a friction value (number between 0 and 1) when calling `update()`: |
| 73 | + |
| 74 | +```javascript |
| 75 | +lazy.update({ x: 40, y: 0 }, { friction: 0.5 }) |
| 76 | +``` |
| 77 | + |
| 78 | +This will reduce the speed at which the brush moves towards the pointer. A |
| 79 | +value of 0 means "no friction", which is the same as not passing a value. 1 |
| 80 | +means "inifinte friction", the brush won't move at all. |
| 81 | + |
| 82 | +You can define a constant value or make it dynamic, for example using a pressur |
| 83 | +value from a touch event. |
| 84 | + |
| 85 | +### Updating both values |
| 86 | + |
| 87 | +You can also update the pointer and the brush coordinates at the same time: |
| 88 | + |
| 89 | +```javascript |
| 90 | +lazy.update({ x: 40, y: 0 }, { both: true }) |
| 91 | +``` |
52 | 92 |
|
53 |
| -# Example |
| 93 | +This can be used when supporting touch events: On touch start you would update |
| 94 | +both the pointer and the brush so that the pointer can be "moved" away from the |
| 95 | +brush until the lazy radius is reached. This is how it's implemented in the |
| 96 | +demo page. |
54 | 97 |
|
55 |
| -## Performance |
56 |
| -For performance reasons it's best to decouple calculations and canvas rendering |
57 |
| -from mousemove/touchmove events: One way is to store the current coordinates in |
58 |
| -a variable. Then, using an animation loop (typically requestAnimationFrame), |
59 |
| -call the `LazyBrush.update()` function on every frame with the latest |
60 |
| -coordinates from the variable. |
| 98 | +## Examples |
61 | 99 |
|
62 |
| -The library will only do calculations if the pointer or brush values changed. |
| 100 | +Check out the [basic example](examples/basic.html) for a simple starting point |
| 101 | +on how to use this library. |
0 commit comments