@stroke-stabilizer/react
v0.3.1
Published
React hooks for stroke stabilization
Downloads
1,510
Maintainers
Readme
@stroke-stabilizer/react
This is part of the stroke-stabilizer monorepo
React hooks for stroke stabilization in digital drawing applications.
Installation
npm install @stroke-stabilizer/react @stroke-stabilizer/coreUsage
useStabilizedPointer
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 (
<canvas onPointerMove={handlePointerMove} onPointerUp={handlePointerUp} />
)
}Important: Always use
getCoalescedEvents()to capture all pointer events between frames. Without it, browsers throttle events and you'll get choppy strokes.
With rAF Batch Processing
For high-frequency input devices, use the underlying StabilizedPointer's batch processing:
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 <canvas onPointerMove={handlePointerMove} />
}useStabilizationLevel
A hook for managing stabilization level state.
import { useStabilizationLevel } from '@stroke-stabilizer/react'
function StabilizationSlider() {
const { level, setLevel, isEnabled } = useStabilizationLevel({
initialLevel: 50,
})
return (
<div>
<input
type="range"
min={0}
max={100}
value={level}
onChange={(e) => setLevel(Number(e.target.value))}
/>
<span>{level}%</span>
{isEnabled && <span>Stabilization enabled</span>}
</div>
)
}API
useStabilizedPointer(options?)
Creates a stabilized pointer instance.
Options:
level- Stabilization level (0-100). Uses preset when specifiedfilters- Custom filter array. Used when level is not specifiedonPoint- Callback when a point is processed
Returns:
process(point)- Process a single pointprocessAll(points)- Process multiple pointsflushBuffer()- Flush internal bufferfinish()- Apply post-processing and return final points (auto-appends endpoint)reset()- Reset the pointer stateaddFilter(filter)- Add a filter dynamicallyremoveFilter(type)- Remove a filter by typeupdateFilter(type, params)- Update filter parameterspointer- Reference to the StabilizedPointer instance
useStabilizationLevel(options?)
Manages stabilization level state.
Options:
initialLevel- Initial level (default: 0)min- Minimum level (default: 0)max- Maximum level (default: 100)onChange- Callback when level changes
Returns:
level- Current levelsetLevel(value)- Set the levelincrease(amount?)- Increase level by amount (default: 10)decrease(amount?)- Decrease level by amount (default: 10)isEnabled- Whether stabilization is active (level > 0)
