React hooks for stroke stabilization
npm install @stroke-stabilizer/react


> This is part of the stroke-stabilizer monorepo
React hooks for stroke stabilization in digital drawing applications.
``bash`
npm install @stroke-stabilizer/react @stroke-stabilizer/core
`tsx
import { useStabilizedPointer } from '@stroke-stabilizer/react'
import { oneEuroFilter } from '@stroke-stabilizer/core'
function DrawingCanvas() {
const { process, reset, pointer } = useStabilizedPointer({
level: 50,
onPoint: (point) => {
draw(point.x, point.y)
},
})
const handlePointerMove = (e: React.PointerEvent) => {
// IMPORTANT: Use getCoalescedEvents() for smoother input
const events = e.nativeEvent.getCoalescedEvents?.() ?? [e.nativeEvent]
for (const ce of events) {
process({
x: ce.offsetX,
y: ce.offsetY,
pressure: ce.pressure,
timestamp: ce.timeStamp,
})
}
}
const handlePointerUp = () => {
// Get final smoothed points with post-processing
const finalPoints = pointer.finish()
drawFinalStroke(finalPoints)
}
return (
)
}
`
> Important: Always use getCoalescedEvents() to capture all pointer events between frames. Without it, browsers throttle events and you'll get choppy strokes.
For high-frequency input devices, use the underlying StabilizedPointer's batch processing:
`tsx
import { useStabilizedPointer } from '@stroke-stabilizer/react'
import { useEffect } from 'react'
function DrawingCanvas() {
const { pointer } = useStabilizedPointer({ level: 50 })
useEffect(() => {
pointer.enableBatching({
onBatch: (points) => drawPoints(points),
})
return () => pointer.disableBatching()
}, [pointer])
const handlePointerMove = (e: React.PointerEvent) => {
// IMPORTANT: Use getCoalescedEvents() for smoother input
const events = e.nativeEvent.getCoalescedEvents?.() ?? [e.nativeEvent]
for (const ce of events) {
pointer.queue({
x: ce.offsetX,
y: ce.offsetY,
pressure: ce.pressure,
timestamp: ce.timeStamp,
})
}
}
return
}
`
A hook for managing stabilization level state.
`tsx
import { useStabilizationLevel } from '@stroke-stabilizer/react'
function StabilizationSlider() {
const { level, setLevel, isEnabled } = useStabilizationLevel({
initialLevel: 50,
})
return (
API
$3
Creates a stabilized pointer instance.
Options:
-
level - Stabilization level (0-100). Uses preset when specified
- filters - Custom filter array. Used when level is not specified
- onPoint - Callback when a point is processedReturns:
-
process(point) - Process a single point
- processAll(points) - Process multiple points
- flushBuffer() - Flush internal buffer
- finish() - Apply post-processing and return final points (auto-appends endpoint)
- reset() - Reset the pointer state
- addFilter(filter) - Add a filter dynamically
- removeFilter(type) - Remove a filter by type
- updateFilter(type, params) - Update filter parameters
- pointer - Reference to the StabilizedPointer instance$3
Manages stabilization level state.
Options:
-
initialLevel - Initial level (default: 0)
- min - Minimum level (default: 0)
- max - Maximum level (default: 100)
- onChange - Callback when level changesReturns:
-
level - Current level
- setLevel(value) - Set the level
- increase(amount?) - Increase level by amount (default: 10)
- decrease(amount?) - Decrease level by amount (default: 10)
- isEnabled` - Whether stabilization is active (level > 0)