-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrecord-stroke.ts
83 lines (69 loc) · 2.32 KB
/
record-stroke.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import { Seed, Cell } from './loop'
import { vec2, vec4, float } from 'parcel-plugin-writable/src/struct'
import Data, { write } from './parcel-plugin-writable/src/node'
import { frameCoordsFrom } from './stage'
import { GLContext } from './contexts'
export type Sampler = (x: number, y: number) => number[]
type Props = {
node?: string
color?: Sampler
}
export default function RecordStroke(props: Props, cell?: Cell) {
if (!cell) return Seed(RecordStroke, props)
const { node } = props
const gl = cell.read(GLContext)
if (!gl) return
const { canvas } = gl
if (!canvas) return
const srcColor = cell.read<Sampler>(props.color)
return cell.effect('listen-and-write', () => {
const pos = Data(node, ['pos'], vec2)
const force = Data(node, ['force'], float)
const color = Data(node, ['color'], vec4)
color.set([1, 1, 1, 1])
canvas.addEventListener('mousedown', onMouse)
canvas.addEventListener('mousemove', onMouse)
canvas.addEventListener('mouseup', onMouse)
canvas.addEventListener('touchstart', onTouch)
canvas.addEventListener('touchmove', onTouch)
canvas.addEventListener('touchend', onTouch)
function onTouch(t: TouchEvent) {
const { touches } = t
t.preventDefault()
let i = touches.length; while (i --> 0) {
const touch = touches.item(i)
if (touch.touchType !== 'stylus') continue
const coords = frameCoordsFrom(touch)
pos.set(coords)
force.set([touch.force])
write(pos)
write(force)
if (srcColor) {
color.set(srcColor(coords[0], coords[1]))
}
write(color)
}
}
let isDrawing = false
function onMouse(ev: MouseEvent) {
if (ev.type === 'mousedown') isDrawing = true
if (!isDrawing) return
if (ev.type === 'mouseup') isDrawing = false
const coords = frameCoordsFrom(ev)
pos.set(coords)
force.set([0.5])
write(pos)
write(force)
if (srcColor) {
color.set(srcColor(coords[0], coords[1]))
}
write(color)
}
return () => {
canvas.removeEventListener('mousemove', onMouse)
canvas.removeEventListener('touchstart', onTouch)
canvas.removeEventListener('touchmove', onTouch)
canvas.removeEventListener('touchend', onTouch)
}
}, [node, canvas, srcColor])
}