@stroke-stabilizer/core 0.2.11 → 0.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,34 +32,79 @@ npm install @stroke-stabilizer/core
|
|
|
32
32
|
## Quick Start
|
|
33
33
|
|
|
34
34
|
```ts
|
|
35
|
-
import {
|
|
36
|
-
StabilizedPointer,
|
|
37
|
-
emaFilter,
|
|
38
|
-
oneEuroFilter,
|
|
39
|
-
} from '@stroke-stabilizer/core'
|
|
35
|
+
import { StabilizedPointer, oneEuroFilter } from '@stroke-stabilizer/core'
|
|
40
36
|
|
|
41
|
-
const pointer = new StabilizedPointer()
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
const pointer = new StabilizedPointer().addFilter(
|
|
38
|
+
oneEuroFilter({ minCutoff: 1.0, beta: 0.007 })
|
|
39
|
+
)
|
|
44
40
|
|
|
45
41
|
canvas.addEventListener('pointermove', (e) => {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
42
|
+
// IMPORTANT: Use getCoalescedEvents() for smoother input
|
|
43
|
+
const events = e.getCoalescedEvents?.() ?? [e]
|
|
44
|
+
|
|
45
|
+
for (const ce of events) {
|
|
46
|
+
const result = pointer.process({
|
|
47
|
+
x: ce.offsetX,
|
|
48
|
+
y: ce.offsetY,
|
|
49
|
+
pressure: ce.pressure,
|
|
50
|
+
timestamp: ce.timeStamp,
|
|
51
|
+
})
|
|
52
|
+
if (result) draw(result.x, result.y)
|
|
55
53
|
}
|
|
56
54
|
})
|
|
57
55
|
|
|
58
56
|
canvas.addEventListener('pointerup', () => {
|
|
59
|
-
pointer.
|
|
57
|
+
const finalPoints = pointer.finish()
|
|
58
|
+
drawStroke(finalPoints)
|
|
60
59
|
})
|
|
61
60
|
```
|
|
62
61
|
|
|
62
|
+
> **Important:** Always use `getCoalescedEvents()` to capture all pointer events between frames. Without it, browsers throttle events and you'll get choppy strokes. See [Using getCoalescedEvents()](#using-getcoalescedevents) for details.
|
|
63
|
+
|
|
64
|
+
## Using getCoalescedEvents()
|
|
65
|
+
|
|
66
|
+
**This is essential for smooth strokes.** Browsers throttle `pointermove` events to ~60fps, but pen tablets can generate 200+ events per second. `getCoalescedEvents()` captures all the intermediate points that would otherwise be lost.
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
canvas.addEventListener('pointermove', (e) => {
|
|
70
|
+
// Get all coalesced events (falls back to single event if unsupported)
|
|
71
|
+
const events = e.getCoalescedEvents?.() ?? [e]
|
|
72
|
+
|
|
73
|
+
for (const ce of events) {
|
|
74
|
+
pointer.process({
|
|
75
|
+
x: ce.offsetX,
|
|
76
|
+
y: ce.offsetY,
|
|
77
|
+
pressure: ce.pressure,
|
|
78
|
+
timestamp: ce.timeStamp,
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**React:** Access via `e.nativeEvent.getCoalescedEvents?.()`
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
const handlePointerMove = (e: React.PointerEvent) => {
|
|
88
|
+
const events = e.nativeEvent.getCoalescedEvents?.() ?? [e.nativeEvent]
|
|
89
|
+
for (const ce of events) {
|
|
90
|
+
pointer.process({ x: ce.offsetX, y: ce.offsetY, ... })
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Vue:** Access directly on the native event
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
function handlePointerMove(e: PointerEvent) {
|
|
99
|
+
const events = e.getCoalescedEvents?.() ?? [e]
|
|
100
|
+
for (const ce of events) {
|
|
101
|
+
pointer.process({ x: ce.offsetX, y: ce.offsetY, ... })
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Without `getCoalescedEvents()`, fast strokes will appear jagged regardless of filter settings.
|
|
107
|
+
|
|
63
108
|
## Filters
|
|
64
109
|
|
|
65
110
|
> **📖 [Detailed Filter Reference](../../docs/filters.md)** - Mathematical formulas, technical explanations, and usage recommendations
|