@stroke-stabilizer/react 0.1.3
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 +155 -0
- package/dist/index.cjs +127 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +127 -0
- package/dist/index.js.map +1 -0
- package/dist/useStabilizationLevel.d.ts +51 -0
- package/dist/useStabilizationLevel.d.ts.map +1 -0
- package/dist/useStabilizedPointer.d.ts +60 -0
- package/dist/useStabilizedPointer.d.ts.map +1 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# @stroke-stabilizer/react
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@stroke-stabilizer/react)
|
|
4
|
+
|
|
5
|
+
[日本語](./docs/README.ja.md)
|
|
6
|
+
|
|
7
|
+
> This is part of the [stroke-stabilizer](https://github.com/usapopopooon/stroke-stabilizer) monorepo
|
|
8
|
+
|
|
9
|
+
React hooks for stroke stabilization in digital drawing applications.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @stroke-stabilizer/react @stroke-stabilizer/core
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### useStabilizedPointer
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { useStabilizedPointer } from '@stroke-stabilizer/react'
|
|
23
|
+
import { oneEuroFilter } from '@stroke-stabilizer/core'
|
|
24
|
+
|
|
25
|
+
function DrawingCanvas() {
|
|
26
|
+
const { process, reset, pointer } = useStabilizedPointer({
|
|
27
|
+
level: 50,
|
|
28
|
+
onPoint: (point) => {
|
|
29
|
+
draw(point.x, point.y)
|
|
30
|
+
},
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const handlePointerMove = (e: React.PointerEvent) => {
|
|
34
|
+
process({
|
|
35
|
+
x: e.clientX,
|
|
36
|
+
y: e.clientY,
|
|
37
|
+
pressure: e.pressure,
|
|
38
|
+
timestamp: e.timeStamp,
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const handlePointerUp = () => {
|
|
43
|
+
reset()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<canvas onPointerMove={handlePointerMove} onPointerUp={handlePointerUp} />
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### With rAF Batch Processing
|
|
53
|
+
|
|
54
|
+
For high-frequency input devices, use the underlying `StabilizedPointer`'s batch processing:
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import { useStabilizedPointer } from '@stroke-stabilizer/react'
|
|
58
|
+
import { useEffect } from 'react'
|
|
59
|
+
|
|
60
|
+
function DrawingCanvas() {
|
|
61
|
+
const { pointer } = useStabilizedPointer({ level: 50 })
|
|
62
|
+
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
pointer.enableBatching({
|
|
65
|
+
onBatch: (points) => drawPoints(points),
|
|
66
|
+
})
|
|
67
|
+
return () => pointer.disableBatching()
|
|
68
|
+
}, [pointer])
|
|
69
|
+
|
|
70
|
+
const handlePointerMove = (e: React.PointerEvent) => {
|
|
71
|
+
pointer.queue({
|
|
72
|
+
x: e.clientX,
|
|
73
|
+
y: e.clientY,
|
|
74
|
+
pressure: e.pressure,
|
|
75
|
+
timestamp: e.timeStamp,
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return <canvas onPointerMove={handlePointerMove} />
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### useStabilizationLevel
|
|
84
|
+
|
|
85
|
+
A hook for managing stabilization level state.
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
import { useStabilizationLevel } from '@stroke-stabilizer/react'
|
|
89
|
+
|
|
90
|
+
function StabilizationSlider() {
|
|
91
|
+
const { level, setLevel, isEnabled } = useStabilizationLevel({
|
|
92
|
+
initialLevel: 50,
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<div>
|
|
97
|
+
<input
|
|
98
|
+
type="range"
|
|
99
|
+
min={0}
|
|
100
|
+
max={100}
|
|
101
|
+
value={level}
|
|
102
|
+
onChange={(e) => setLevel(Number(e.target.value))}
|
|
103
|
+
/>
|
|
104
|
+
<span>{level}%</span>
|
|
105
|
+
{isEnabled && <span>Stabilization enabled</span>}
|
|
106
|
+
</div>
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## API
|
|
112
|
+
|
|
113
|
+
### useStabilizedPointer(options?)
|
|
114
|
+
|
|
115
|
+
Creates a stabilized pointer instance.
|
|
116
|
+
|
|
117
|
+
**Options:**
|
|
118
|
+
|
|
119
|
+
- `level` - Stabilization level (0-100). Uses preset when specified
|
|
120
|
+
- `filters` - Custom filter array. Used when level is not specified
|
|
121
|
+
- `onPoint` - Callback when a point is processed
|
|
122
|
+
|
|
123
|
+
**Returns:**
|
|
124
|
+
|
|
125
|
+
- `process(point)` - Process a single point
|
|
126
|
+
- `processAll(points)` - Process multiple points
|
|
127
|
+
- `flushBuffer()` - Flush internal buffer
|
|
128
|
+
- `reset()` - Reset the pointer state
|
|
129
|
+
- `addFilter(filter)` - Add a filter dynamically
|
|
130
|
+
- `removeFilter(type)` - Remove a filter by type
|
|
131
|
+
- `updateFilter(type, params)` - Update filter parameters
|
|
132
|
+
- `pointer` - Reference to the StabilizedPointer instance
|
|
133
|
+
|
|
134
|
+
### useStabilizationLevel(options?)
|
|
135
|
+
|
|
136
|
+
Manages stabilization level state.
|
|
137
|
+
|
|
138
|
+
**Options:**
|
|
139
|
+
|
|
140
|
+
- `initialLevel` - Initial level (default: 0)
|
|
141
|
+
- `min` - Minimum level (default: 0)
|
|
142
|
+
- `max` - Maximum level (default: 100)
|
|
143
|
+
- `onChange` - Callback when level changes
|
|
144
|
+
|
|
145
|
+
**Returns:**
|
|
146
|
+
|
|
147
|
+
- `level` - Current level
|
|
148
|
+
- `setLevel(value)` - Set the level
|
|
149
|
+
- `increase(amount?)` - Increase level by amount (default: 10)
|
|
150
|
+
- `decrease(amount?)` - Decrease level by amount (default: 10)
|
|
151
|
+
- `isEnabled` - Whether stabilization is active (level > 0)
|
|
152
|
+
|
|
153
|
+
## License
|
|
154
|
+
|
|
155
|
+
[MIT](../../LICENSE)
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const react = require("react");
|
|
4
|
+
const core = require("@stroke-stabilizer/core");
|
|
5
|
+
function useStabilizedPointer(options = {}) {
|
|
6
|
+
const { level, filters, onPoint } = options;
|
|
7
|
+
const pointerRef = react.useRef(null);
|
|
8
|
+
const getPointer = react.useCallback(() => {
|
|
9
|
+
if (!pointerRef.current) {
|
|
10
|
+
if (level !== void 0) {
|
|
11
|
+
pointerRef.current = core.createStabilizedPointer(level);
|
|
12
|
+
} else {
|
|
13
|
+
pointerRef.current = new core.StabilizedPointer();
|
|
14
|
+
if (filters) {
|
|
15
|
+
for (const filter of filters) {
|
|
16
|
+
pointerRef.current.addFilter(filter);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return pointerRef.current;
|
|
22
|
+
}, [level, filters]);
|
|
23
|
+
const process = react.useCallback(
|
|
24
|
+
(point) => {
|
|
25
|
+
const result = getPointer().process(point);
|
|
26
|
+
if (result && onPoint) {
|
|
27
|
+
onPoint(result);
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
},
|
|
31
|
+
[getPointer, onPoint]
|
|
32
|
+
);
|
|
33
|
+
const processAll = react.useCallback(
|
|
34
|
+
(points) => {
|
|
35
|
+
const results = getPointer().processAll(points);
|
|
36
|
+
if (onPoint) {
|
|
37
|
+
for (const point of results) {
|
|
38
|
+
onPoint(point);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return results;
|
|
42
|
+
},
|
|
43
|
+
[getPointer, onPoint]
|
|
44
|
+
);
|
|
45
|
+
const flushBuffer = react.useCallback(() => {
|
|
46
|
+
return getPointer().flushBuffer();
|
|
47
|
+
}, [getPointer]);
|
|
48
|
+
const reset = react.useCallback(() => {
|
|
49
|
+
getPointer().reset();
|
|
50
|
+
}, [getPointer]);
|
|
51
|
+
const addFilter = react.useCallback(
|
|
52
|
+
(filter) => {
|
|
53
|
+
getPointer().addFilter(filter);
|
|
54
|
+
},
|
|
55
|
+
[getPointer]
|
|
56
|
+
);
|
|
57
|
+
const removeFilter = react.useCallback(
|
|
58
|
+
(type) => {
|
|
59
|
+
return getPointer().removeFilter(type);
|
|
60
|
+
},
|
|
61
|
+
[getPointer]
|
|
62
|
+
);
|
|
63
|
+
const updateFilter = react.useCallback(
|
|
64
|
+
(type, params) => {
|
|
65
|
+
return getPointer().updateFilter(type, params);
|
|
66
|
+
},
|
|
67
|
+
[getPointer]
|
|
68
|
+
);
|
|
69
|
+
return react.useMemo(
|
|
70
|
+
() => ({
|
|
71
|
+
process,
|
|
72
|
+
processAll,
|
|
73
|
+
flushBuffer,
|
|
74
|
+
reset,
|
|
75
|
+
addFilter,
|
|
76
|
+
removeFilter,
|
|
77
|
+
updateFilter,
|
|
78
|
+
pointer: getPointer()
|
|
79
|
+
}),
|
|
80
|
+
[
|
|
81
|
+
process,
|
|
82
|
+
processAll,
|
|
83
|
+
flushBuffer,
|
|
84
|
+
reset,
|
|
85
|
+
addFilter,
|
|
86
|
+
removeFilter,
|
|
87
|
+
updateFilter,
|
|
88
|
+
getPointer
|
|
89
|
+
]
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
function useStabilizationLevel(options = {}) {
|
|
93
|
+
const { initialLevel = 0, min = 0, max = 100, onChange } = options;
|
|
94
|
+
const [level, setLevelState] = react.useState(
|
|
95
|
+
() => Math.max(min, Math.min(max, initialLevel))
|
|
96
|
+
);
|
|
97
|
+
const setLevel = react.useCallback(
|
|
98
|
+
(newLevel) => {
|
|
99
|
+
const clamped = Math.max(min, Math.min(max, newLevel));
|
|
100
|
+
setLevelState(clamped);
|
|
101
|
+
onChange == null ? void 0 : onChange(clamped);
|
|
102
|
+
},
|
|
103
|
+
[min, max, onChange]
|
|
104
|
+
);
|
|
105
|
+
const increase = react.useCallback(
|
|
106
|
+
(amount = 10) => {
|
|
107
|
+
setLevel(level + amount);
|
|
108
|
+
},
|
|
109
|
+
[level, setLevel]
|
|
110
|
+
);
|
|
111
|
+
const decrease = react.useCallback(
|
|
112
|
+
(amount = 10) => {
|
|
113
|
+
setLevel(level - amount);
|
|
114
|
+
},
|
|
115
|
+
[level, setLevel]
|
|
116
|
+
);
|
|
117
|
+
return {
|
|
118
|
+
level,
|
|
119
|
+
setLevel,
|
|
120
|
+
increase,
|
|
121
|
+
decrease,
|
|
122
|
+
isEnabled: level > 0
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
exports.useStabilizationLevel = useStabilizationLevel;
|
|
126
|
+
exports.useStabilizedPointer = useStabilizedPointer;
|
|
127
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/useStabilizedPointer.ts","../src/useStabilizationLevel.ts"],"sourcesContent":["import { useCallback, useRef, useMemo } from 'react'\nimport {\n StabilizedPointer,\n createStabilizedPointer,\n type PointerPoint,\n type Filter,\n} from '@stroke-stabilizer/core'\n\nexport interface UseStabilizedPointerOptions {\n /** Stabilization level (0-100). Uses preset when specified */\n level?: number\n /** Custom filters. Used when level is not specified */\n filters?: Filter[]\n /** Callback when a point is processed */\n onPoint?: (point: PointerPoint) => void\n}\n\nexport interface UseStabilizedPointerReturn {\n /** Process a point */\n process: (point: PointerPoint) => PointerPoint | null\n /** Process multiple points at once */\n processAll: (points: PointerPoint[]) => PointerPoint[]\n /** Flush buffer */\n flushBuffer: () => PointerPoint[]\n /** Reset */\n reset: () => void\n /** Add a filter */\n addFilter: (filter: Filter) => void\n /** Remove a filter */\n removeFilter: (type: string) => boolean\n /** Update filter parameters */\n updateFilter: <T>(type: string, params: Partial<T>) => boolean\n /** Reference to StabilizedPointer instance */\n pointer: StabilizedPointer\n}\n\n/**\n * React Hook for stroke stabilization\n *\n * @example\n * ```tsx\n * function DrawingCanvas() {\n * const { process, reset } = useStabilizedPointer({\n * level: 50,\n * onPoint: (point) => {\n * // Draw with stabilized point\n * drawPoint(point)\n * }\n * })\n *\n * const handlePointerMove = (e: React.PointerEvent) => {\n * process({\n * x: e.clientX,\n * y: e.clientY,\n * pressure: e.pressure,\n * timestamp: e.timeStamp\n * })\n * }\n *\n * const handlePointerUp = () => {\n * reset()\n * }\n *\n * return <canvas onPointerMove={handlePointerMove} onPointerUp={handlePointerUp} />\n * }\n * ```\n */\nexport function useStabilizedPointer(\n options: UseStabilizedPointerOptions = {}\n): UseStabilizedPointerReturn {\n const { level, filters, onPoint } = options\n\n const pointerRef = useRef<StabilizedPointer | null>(null)\n\n // Lazy initialization\n const getPointer = useCallback(() => {\n if (!pointerRef.current) {\n if (level !== undefined) {\n pointerRef.current = createStabilizedPointer(level)\n } else {\n pointerRef.current = new StabilizedPointer()\n if (filters) {\n for (const filter of filters) {\n pointerRef.current.addFilter(filter)\n }\n }\n }\n }\n return pointerRef.current\n }, [level, filters])\n\n const process = useCallback(\n (point: PointerPoint): PointerPoint | null => {\n const result = getPointer().process(point)\n if (result && onPoint) {\n onPoint(result)\n }\n return result\n },\n [getPointer, onPoint]\n )\n\n const processAll = useCallback(\n (points: PointerPoint[]): PointerPoint[] => {\n const results = getPointer().processAll(points)\n if (onPoint) {\n for (const point of results) {\n onPoint(point)\n }\n }\n return results\n },\n [getPointer, onPoint]\n )\n\n const flushBuffer = useCallback(() => {\n return getPointer().flushBuffer()\n }, [getPointer])\n\n const reset = useCallback(() => {\n getPointer().reset()\n }, [getPointer])\n\n const addFilter = useCallback(\n (filter: Filter) => {\n getPointer().addFilter(filter)\n },\n [getPointer]\n )\n\n const removeFilter = useCallback(\n (type: string) => {\n return getPointer().removeFilter(type)\n },\n [getPointer]\n )\n\n const updateFilter = useCallback(\n <T>(type: string, params: Partial<T>) => {\n return getPointer().updateFilter(type, params)\n },\n [getPointer]\n )\n\n return useMemo(\n () => ({\n process,\n processAll,\n flushBuffer,\n reset,\n addFilter,\n removeFilter,\n updateFilter,\n pointer: getPointer(),\n }),\n [\n process,\n processAll,\n flushBuffer,\n reset,\n addFilter,\n removeFilter,\n updateFilter,\n getPointer,\n ]\n )\n}\n","import { useState, useCallback } from 'react'\n\nexport interface UseStabilizationLevelOptions {\n /** Initial value (default: 0) */\n initialLevel?: number\n /** Minimum value (default: 0) */\n min?: number\n /** Maximum value (default: 100) */\n max?: number\n /** Callback when level changes */\n onChange?: (level: number) => void\n}\n\nexport interface UseStabilizationLevelReturn {\n /** Current stabilization level */\n level: number\n /** Set level */\n setLevel: (level: number) => void\n /** Increase level */\n increase: (amount?: number) => void\n /** Decrease level */\n decrease: (amount?: number) => void\n /** Whether stabilization is enabled */\n isEnabled: boolean\n}\n\n/**\n * React Hook for managing stabilization level\n *\n * @example\n * ```tsx\n * function StabilizationControl() {\n * const { level, setLevel, isEnabled } = useStabilizationLevel({\n * initialLevel: 50,\n * onChange: (newLevel) => console.log('Level changed:', newLevel)\n * })\n *\n * return (\n * <div>\n * <input\n * type=\"range\"\n * min={0}\n * max={100}\n * value={level}\n * onChange={(e) => setLevel(Number(e.target.value))}\n * />\n * <span>{level}%</span>\n * {isEnabled && <span>Stabilization enabled</span>}\n * </div>\n * )\n * }\n * ```\n */\nexport function useStabilizationLevel(\n options: UseStabilizationLevelOptions = {}\n): UseStabilizationLevelReturn {\n const { initialLevel = 0, min = 0, max = 100, onChange } = options\n\n const [level, setLevelState] = useState(() =>\n Math.max(min, Math.min(max, initialLevel))\n )\n\n const setLevel = useCallback(\n (newLevel: number) => {\n const clamped = Math.max(min, Math.min(max, newLevel))\n setLevelState(clamped)\n onChange?.(clamped)\n },\n [min, max, onChange]\n )\n\n const increase = useCallback(\n (amount = 10) => {\n setLevel(level + amount)\n },\n [level, setLevel]\n )\n\n const decrease = useCallback(\n (amount = 10) => {\n setLevel(level - amount)\n },\n [level, setLevel]\n )\n\n return {\n level,\n setLevel,\n increase,\n decrease,\n isEnabled: level > 0,\n }\n}\n"],"names":["useRef","useCallback","createStabilizedPointer","StabilizedPointer","useMemo","useState"],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { useStabilizedPointer } from './useStabilizedPointer';
|
|
2
|
+
export type { UseStabilizedPointerOptions, UseStabilizedPointerReturn, } from './useStabilizedPointer';
|
|
3
|
+
export { useStabilizationLevel } from './useStabilizationLevel';
|
|
4
|
+
export type { UseStabilizationLevelOptions, UseStabilizationLevelReturn, } from './useStabilizationLevel';
|
|
5
|
+
export type { Point, PointerPoint, Filter } from '@stroke-stabilizer/core';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAC7D,YAAY,EACV,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAC/D,YAAY,EACV,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,yBAAyB,CAAA;AAGhC,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { useRef, useCallback, useMemo, useState } from "react";
|
|
2
|
+
import { createStabilizedPointer, StabilizedPointer } from "@stroke-stabilizer/core";
|
|
3
|
+
function useStabilizedPointer(options = {}) {
|
|
4
|
+
const { level, filters, onPoint } = options;
|
|
5
|
+
const pointerRef = useRef(null);
|
|
6
|
+
const getPointer = useCallback(() => {
|
|
7
|
+
if (!pointerRef.current) {
|
|
8
|
+
if (level !== void 0) {
|
|
9
|
+
pointerRef.current = createStabilizedPointer(level);
|
|
10
|
+
} else {
|
|
11
|
+
pointerRef.current = new StabilizedPointer();
|
|
12
|
+
if (filters) {
|
|
13
|
+
for (const filter of filters) {
|
|
14
|
+
pointerRef.current.addFilter(filter);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return pointerRef.current;
|
|
20
|
+
}, [level, filters]);
|
|
21
|
+
const process = useCallback(
|
|
22
|
+
(point) => {
|
|
23
|
+
const result = getPointer().process(point);
|
|
24
|
+
if (result && onPoint) {
|
|
25
|
+
onPoint(result);
|
|
26
|
+
}
|
|
27
|
+
return result;
|
|
28
|
+
},
|
|
29
|
+
[getPointer, onPoint]
|
|
30
|
+
);
|
|
31
|
+
const processAll = useCallback(
|
|
32
|
+
(points) => {
|
|
33
|
+
const results = getPointer().processAll(points);
|
|
34
|
+
if (onPoint) {
|
|
35
|
+
for (const point of results) {
|
|
36
|
+
onPoint(point);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return results;
|
|
40
|
+
},
|
|
41
|
+
[getPointer, onPoint]
|
|
42
|
+
);
|
|
43
|
+
const flushBuffer = useCallback(() => {
|
|
44
|
+
return getPointer().flushBuffer();
|
|
45
|
+
}, [getPointer]);
|
|
46
|
+
const reset = useCallback(() => {
|
|
47
|
+
getPointer().reset();
|
|
48
|
+
}, [getPointer]);
|
|
49
|
+
const addFilter = useCallback(
|
|
50
|
+
(filter) => {
|
|
51
|
+
getPointer().addFilter(filter);
|
|
52
|
+
},
|
|
53
|
+
[getPointer]
|
|
54
|
+
);
|
|
55
|
+
const removeFilter = useCallback(
|
|
56
|
+
(type) => {
|
|
57
|
+
return getPointer().removeFilter(type);
|
|
58
|
+
},
|
|
59
|
+
[getPointer]
|
|
60
|
+
);
|
|
61
|
+
const updateFilter = useCallback(
|
|
62
|
+
(type, params) => {
|
|
63
|
+
return getPointer().updateFilter(type, params);
|
|
64
|
+
},
|
|
65
|
+
[getPointer]
|
|
66
|
+
);
|
|
67
|
+
return useMemo(
|
|
68
|
+
() => ({
|
|
69
|
+
process,
|
|
70
|
+
processAll,
|
|
71
|
+
flushBuffer,
|
|
72
|
+
reset,
|
|
73
|
+
addFilter,
|
|
74
|
+
removeFilter,
|
|
75
|
+
updateFilter,
|
|
76
|
+
pointer: getPointer()
|
|
77
|
+
}),
|
|
78
|
+
[
|
|
79
|
+
process,
|
|
80
|
+
processAll,
|
|
81
|
+
flushBuffer,
|
|
82
|
+
reset,
|
|
83
|
+
addFilter,
|
|
84
|
+
removeFilter,
|
|
85
|
+
updateFilter,
|
|
86
|
+
getPointer
|
|
87
|
+
]
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
function useStabilizationLevel(options = {}) {
|
|
91
|
+
const { initialLevel = 0, min = 0, max = 100, onChange } = options;
|
|
92
|
+
const [level, setLevelState] = useState(
|
|
93
|
+
() => Math.max(min, Math.min(max, initialLevel))
|
|
94
|
+
);
|
|
95
|
+
const setLevel = useCallback(
|
|
96
|
+
(newLevel) => {
|
|
97
|
+
const clamped = Math.max(min, Math.min(max, newLevel));
|
|
98
|
+
setLevelState(clamped);
|
|
99
|
+
onChange == null ? void 0 : onChange(clamped);
|
|
100
|
+
},
|
|
101
|
+
[min, max, onChange]
|
|
102
|
+
);
|
|
103
|
+
const increase = useCallback(
|
|
104
|
+
(amount = 10) => {
|
|
105
|
+
setLevel(level + amount);
|
|
106
|
+
},
|
|
107
|
+
[level, setLevel]
|
|
108
|
+
);
|
|
109
|
+
const decrease = useCallback(
|
|
110
|
+
(amount = 10) => {
|
|
111
|
+
setLevel(level - amount);
|
|
112
|
+
},
|
|
113
|
+
[level, setLevel]
|
|
114
|
+
);
|
|
115
|
+
return {
|
|
116
|
+
level,
|
|
117
|
+
setLevel,
|
|
118
|
+
increase,
|
|
119
|
+
decrease,
|
|
120
|
+
isEnabled: level > 0
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
export {
|
|
124
|
+
useStabilizationLevel,
|
|
125
|
+
useStabilizedPointer
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/useStabilizedPointer.ts","../src/useStabilizationLevel.ts"],"sourcesContent":["import { useCallback, useRef, useMemo } from 'react'\nimport {\n StabilizedPointer,\n createStabilizedPointer,\n type PointerPoint,\n type Filter,\n} from '@stroke-stabilizer/core'\n\nexport interface UseStabilizedPointerOptions {\n /** Stabilization level (0-100). Uses preset when specified */\n level?: number\n /** Custom filters. Used when level is not specified */\n filters?: Filter[]\n /** Callback when a point is processed */\n onPoint?: (point: PointerPoint) => void\n}\n\nexport interface UseStabilizedPointerReturn {\n /** Process a point */\n process: (point: PointerPoint) => PointerPoint | null\n /** Process multiple points at once */\n processAll: (points: PointerPoint[]) => PointerPoint[]\n /** Flush buffer */\n flushBuffer: () => PointerPoint[]\n /** Reset */\n reset: () => void\n /** Add a filter */\n addFilter: (filter: Filter) => void\n /** Remove a filter */\n removeFilter: (type: string) => boolean\n /** Update filter parameters */\n updateFilter: <T>(type: string, params: Partial<T>) => boolean\n /** Reference to StabilizedPointer instance */\n pointer: StabilizedPointer\n}\n\n/**\n * React Hook for stroke stabilization\n *\n * @example\n * ```tsx\n * function DrawingCanvas() {\n * const { process, reset } = useStabilizedPointer({\n * level: 50,\n * onPoint: (point) => {\n * // Draw with stabilized point\n * drawPoint(point)\n * }\n * })\n *\n * const handlePointerMove = (e: React.PointerEvent) => {\n * process({\n * x: e.clientX,\n * y: e.clientY,\n * pressure: e.pressure,\n * timestamp: e.timeStamp\n * })\n * }\n *\n * const handlePointerUp = () => {\n * reset()\n * }\n *\n * return <canvas onPointerMove={handlePointerMove} onPointerUp={handlePointerUp} />\n * }\n * ```\n */\nexport function useStabilizedPointer(\n options: UseStabilizedPointerOptions = {}\n): UseStabilizedPointerReturn {\n const { level, filters, onPoint } = options\n\n const pointerRef = useRef<StabilizedPointer | null>(null)\n\n // Lazy initialization\n const getPointer = useCallback(() => {\n if (!pointerRef.current) {\n if (level !== undefined) {\n pointerRef.current = createStabilizedPointer(level)\n } else {\n pointerRef.current = new StabilizedPointer()\n if (filters) {\n for (const filter of filters) {\n pointerRef.current.addFilter(filter)\n }\n }\n }\n }\n return pointerRef.current\n }, [level, filters])\n\n const process = useCallback(\n (point: PointerPoint): PointerPoint | null => {\n const result = getPointer().process(point)\n if (result && onPoint) {\n onPoint(result)\n }\n return result\n },\n [getPointer, onPoint]\n )\n\n const processAll = useCallback(\n (points: PointerPoint[]): PointerPoint[] => {\n const results = getPointer().processAll(points)\n if (onPoint) {\n for (const point of results) {\n onPoint(point)\n }\n }\n return results\n },\n [getPointer, onPoint]\n )\n\n const flushBuffer = useCallback(() => {\n return getPointer().flushBuffer()\n }, [getPointer])\n\n const reset = useCallback(() => {\n getPointer().reset()\n }, [getPointer])\n\n const addFilter = useCallback(\n (filter: Filter) => {\n getPointer().addFilter(filter)\n },\n [getPointer]\n )\n\n const removeFilter = useCallback(\n (type: string) => {\n return getPointer().removeFilter(type)\n },\n [getPointer]\n )\n\n const updateFilter = useCallback(\n <T>(type: string, params: Partial<T>) => {\n return getPointer().updateFilter(type, params)\n },\n [getPointer]\n )\n\n return useMemo(\n () => ({\n process,\n processAll,\n flushBuffer,\n reset,\n addFilter,\n removeFilter,\n updateFilter,\n pointer: getPointer(),\n }),\n [\n process,\n processAll,\n flushBuffer,\n reset,\n addFilter,\n removeFilter,\n updateFilter,\n getPointer,\n ]\n )\n}\n","import { useState, useCallback } from 'react'\n\nexport interface UseStabilizationLevelOptions {\n /** Initial value (default: 0) */\n initialLevel?: number\n /** Minimum value (default: 0) */\n min?: number\n /** Maximum value (default: 100) */\n max?: number\n /** Callback when level changes */\n onChange?: (level: number) => void\n}\n\nexport interface UseStabilizationLevelReturn {\n /** Current stabilization level */\n level: number\n /** Set level */\n setLevel: (level: number) => void\n /** Increase level */\n increase: (amount?: number) => void\n /** Decrease level */\n decrease: (amount?: number) => void\n /** Whether stabilization is enabled */\n isEnabled: boolean\n}\n\n/**\n * React Hook for managing stabilization level\n *\n * @example\n * ```tsx\n * function StabilizationControl() {\n * const { level, setLevel, isEnabled } = useStabilizationLevel({\n * initialLevel: 50,\n * onChange: (newLevel) => console.log('Level changed:', newLevel)\n * })\n *\n * return (\n * <div>\n * <input\n * type=\"range\"\n * min={0}\n * max={100}\n * value={level}\n * onChange={(e) => setLevel(Number(e.target.value))}\n * />\n * <span>{level}%</span>\n * {isEnabled && <span>Stabilization enabled</span>}\n * </div>\n * )\n * }\n * ```\n */\nexport function useStabilizationLevel(\n options: UseStabilizationLevelOptions = {}\n): UseStabilizationLevelReturn {\n const { initialLevel = 0, min = 0, max = 100, onChange } = options\n\n const [level, setLevelState] = useState(() =>\n Math.max(min, Math.min(max, initialLevel))\n )\n\n const setLevel = useCallback(\n (newLevel: number) => {\n const clamped = Math.max(min, Math.min(max, newLevel))\n setLevelState(clamped)\n onChange?.(clamped)\n },\n [min, max, onChange]\n )\n\n const increase = useCallback(\n (amount = 10) => {\n setLevel(level + amount)\n },\n [level, setLevel]\n )\n\n const decrease = useCallback(\n (amount = 10) => {\n setLevel(level - amount)\n },\n [level, setLevel]\n )\n\n return {\n level,\n setLevel,\n increase,\n decrease,\n isEnabled: level > 0,\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export interface UseStabilizationLevelOptions {
|
|
2
|
+
/** Initial value (default: 0) */
|
|
3
|
+
initialLevel?: number;
|
|
4
|
+
/** Minimum value (default: 0) */
|
|
5
|
+
min?: number;
|
|
6
|
+
/** Maximum value (default: 100) */
|
|
7
|
+
max?: number;
|
|
8
|
+
/** Callback when level changes */
|
|
9
|
+
onChange?: (level: number) => void;
|
|
10
|
+
}
|
|
11
|
+
export interface UseStabilizationLevelReturn {
|
|
12
|
+
/** Current stabilization level */
|
|
13
|
+
level: number;
|
|
14
|
+
/** Set level */
|
|
15
|
+
setLevel: (level: number) => void;
|
|
16
|
+
/** Increase level */
|
|
17
|
+
increase: (amount?: number) => void;
|
|
18
|
+
/** Decrease level */
|
|
19
|
+
decrease: (amount?: number) => void;
|
|
20
|
+
/** Whether stabilization is enabled */
|
|
21
|
+
isEnabled: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* React Hook for managing stabilization level
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```tsx
|
|
28
|
+
* function StabilizationControl() {
|
|
29
|
+
* const { level, setLevel, isEnabled } = useStabilizationLevel({
|
|
30
|
+
* initialLevel: 50,
|
|
31
|
+
* onChange: (newLevel) => console.log('Level changed:', newLevel)
|
|
32
|
+
* })
|
|
33
|
+
*
|
|
34
|
+
* return (
|
|
35
|
+
* <div>
|
|
36
|
+
* <input
|
|
37
|
+
* type="range"
|
|
38
|
+
* min={0}
|
|
39
|
+
* max={100}
|
|
40
|
+
* value={level}
|
|
41
|
+
* onChange={(e) => setLevel(Number(e.target.value))}
|
|
42
|
+
* />
|
|
43
|
+
* <span>{level}%</span>
|
|
44
|
+
* {isEnabled && <span>Stabilization enabled</span>}
|
|
45
|
+
* </div>
|
|
46
|
+
* )
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function useStabilizationLevel(options?: UseStabilizationLevelOptions): UseStabilizationLevelReturn;
|
|
51
|
+
//# sourceMappingURL=useStabilizationLevel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStabilizationLevel.d.ts","sourceRoot":"","sources":["../src/useStabilizationLevel.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,4BAA4B;IAC3C,iCAAiC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,mCAAmC;IACnC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,kCAAkC;IAClC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACnC;AAED,MAAM,WAAW,2BAA2B;IAC1C,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,gBAAgB;IAChB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,qBAAqB;IACrB,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,qBAAqB;IACrB,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,uCAAuC;IACvC,SAAS,EAAE,OAAO,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,GAAE,4BAAiC,GACzC,2BAA2B,CAqC7B"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { StabilizedPointer, type PointerPoint, type Filter } from '@stroke-stabilizer/core';
|
|
2
|
+
export interface UseStabilizedPointerOptions {
|
|
3
|
+
/** Stabilization level (0-100). Uses preset when specified */
|
|
4
|
+
level?: number;
|
|
5
|
+
/** Custom filters. Used when level is not specified */
|
|
6
|
+
filters?: Filter[];
|
|
7
|
+
/** Callback when a point is processed */
|
|
8
|
+
onPoint?: (point: PointerPoint) => void;
|
|
9
|
+
}
|
|
10
|
+
export interface UseStabilizedPointerReturn {
|
|
11
|
+
/** Process a point */
|
|
12
|
+
process: (point: PointerPoint) => PointerPoint | null;
|
|
13
|
+
/** Process multiple points at once */
|
|
14
|
+
processAll: (points: PointerPoint[]) => PointerPoint[];
|
|
15
|
+
/** Flush buffer */
|
|
16
|
+
flushBuffer: () => PointerPoint[];
|
|
17
|
+
/** Reset */
|
|
18
|
+
reset: () => void;
|
|
19
|
+
/** Add a filter */
|
|
20
|
+
addFilter: (filter: Filter) => void;
|
|
21
|
+
/** Remove a filter */
|
|
22
|
+
removeFilter: (type: string) => boolean;
|
|
23
|
+
/** Update filter parameters */
|
|
24
|
+
updateFilter: <T>(type: string, params: Partial<T>) => boolean;
|
|
25
|
+
/** Reference to StabilizedPointer instance */
|
|
26
|
+
pointer: StabilizedPointer;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* React Hook for stroke stabilization
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* function DrawingCanvas() {
|
|
34
|
+
* const { process, reset } = useStabilizedPointer({
|
|
35
|
+
* level: 50,
|
|
36
|
+
* onPoint: (point) => {
|
|
37
|
+
* // Draw with stabilized point
|
|
38
|
+
* drawPoint(point)
|
|
39
|
+
* }
|
|
40
|
+
* })
|
|
41
|
+
*
|
|
42
|
+
* const handlePointerMove = (e: React.PointerEvent) => {
|
|
43
|
+
* process({
|
|
44
|
+
* x: e.clientX,
|
|
45
|
+
* y: e.clientY,
|
|
46
|
+
* pressure: e.pressure,
|
|
47
|
+
* timestamp: e.timeStamp
|
|
48
|
+
* })
|
|
49
|
+
* }
|
|
50
|
+
*
|
|
51
|
+
* const handlePointerUp = () => {
|
|
52
|
+
* reset()
|
|
53
|
+
* }
|
|
54
|
+
*
|
|
55
|
+
* return <canvas onPointerMove={handlePointerMove} onPointerUp={handlePointerUp} />
|
|
56
|
+
* }
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare function useStabilizedPointer(options?: UseStabilizedPointerOptions): UseStabilizedPointerReturn;
|
|
60
|
+
//# sourceMappingURL=useStabilizedPointer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStabilizedPointer.d.ts","sourceRoot":"","sources":["../src/useStabilizedPointer.ts"],"names":[],"mappings":"AACA,OAAO,EACL,iBAAiB,EAEjB,KAAK,YAAY,EACjB,KAAK,MAAM,EACZ,MAAM,yBAAyB,CAAA;AAEhC,MAAM,WAAW,2BAA2B;IAC1C,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,yCAAyC;IACzC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;CACxC;AAED,MAAM,WAAW,0BAA0B;IACzC,sBAAsB;IACtB,OAAO,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,YAAY,GAAG,IAAI,CAAA;IACrD,sCAAsC;IACtC,UAAU,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,CAAA;IACtD,mBAAmB;IACnB,WAAW,EAAE,MAAM,YAAY,EAAE,CAAA;IACjC,YAAY;IACZ,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,mBAAmB;IACnB,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,sBAAsB;IACtB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAA;IACvC,+BAA+B;IAC/B,YAAY,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAA;IAC9D,8CAA8C;IAC9C,OAAO,EAAE,iBAAiB,CAAA;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,2BAAgC,GACxC,0BAA0B,CAiG5B"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stroke-stabilizer/react",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "React hooks for stroke stabilization",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.cjs",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"dev": "vite build --watch",
|
|
21
|
+
"build": "vite build && tsc --emitDeclarationOnly",
|
|
22
|
+
"typecheck": "tsc --noEmit"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@stroke-stabilizer/core": "workspace:*"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"react": ">=17.0.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/react": "^18.2.0",
|
|
32
|
+
"react": "^18.2.0",
|
|
33
|
+
"vite": "^5.4.0",
|
|
34
|
+
"vite-plugin-dts": "^4.0.0"
|
|
35
|
+
},
|
|
36
|
+
"keywords": [
|
|
37
|
+
"react",
|
|
38
|
+
"hook",
|
|
39
|
+
"stroke",
|
|
40
|
+
"stabilization",
|
|
41
|
+
"drawing",
|
|
42
|
+
"canvas"
|
|
43
|
+
],
|
|
44
|
+
"author": "usapopopooon <usapopopooon@gmail.com>",
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "https://github.com/usapopopooon/stroke-stabilizer"
|
|
49
|
+
},
|
|
50
|
+
"homepage": "https://github.com/usapopopooon/stroke-stabilizer",
|
|
51
|
+
"sideEffects": false
|
|
52
|
+
}
|