Quellcode durchsuchen

adds pressure sensitivity

main
Steve Ruiz vor 4 Jahren
Ursprung
Commit
8623958e74

+ 1
- 1
components/canvas/defs.tsx Datei anzeigen

@@ -28,7 +28,7 @@ export default function Defs() {
28 28
 }
29 29
 
30 30
 const Def = memo(function Def({ id }: { id: string }) {
31
-  const shape = useSelector(({ data }) => getPage(data).shapes[id])
31
+  const shape = useSelector((s) => getPage(s.data).shapes[id])
32 32
   if (!shape) return null
33 33
   return getShapeUtils(shape).render(shape)
34 34
 })

+ 2
- 4
components/canvas/shape.tsx Datei anzeigen

@@ -15,7 +15,7 @@ interface ShapeProps {
15 15
 }
16 16
 
17 17
 function Shape({ id, isSelecting, parentPoint }: ShapeProps) {
18
-  const shape = useSelector(({ data }) => getPage(data).shapes[id])
18
+  const shape = useSelector((s) => getPage(s.data).shapes[id])
19 19
 
20 20
   const rGroup = useRef<SVGGElement>(null)
21 21
 
@@ -25,9 +25,7 @@ function Shape({ id, isSelecting, parentPoint }: ShapeProps) {
25 25
   // may sometimes run before the hook in the Page component, which means
26 26
   // a deleted shape will still be pulled here before the page component
27 27
   // detects the change and pulls this component.
28
-  if (!shape) {
29
-    return null
30
-  }
28
+  if (!shape) return null
31 29
 
32 30
   const isGroup = shape.type === ShapeType.Group
33 31
 

+ 28
- 11
lib/shape-utils/draw.tsx Datei anzeigen

@@ -157,18 +157,35 @@ const draw = registerShapeUtils<DrawShape>({
157 157
 
158 158
 export default draw
159 159
 
160
+const simulatePressureSettings = {
161
+  simulatePressure: true,
162
+}
163
+
164
+const realPressureSettings = {
165
+  easing: (t: number) => t * t,
166
+  simulatePressure: false,
167
+  // start: { taper: 1 },
168
+  // end: { taper: 1 },
169
+}
170
+
160 171
 function renderPath(shape: DrawShape, style: ShapeStyles) {
161 172
   const styles = getShapeStyle(style)
162 173
 
163
-  pathCache.set(
164
-    shape.points,
165
-    getSvgPathFromStroke(
166
-      getStroke(shape.points, {
167
-        size: 1 + +styles.strokeWidth * 2,
168
-        thinning: 0.85,
169
-        end: { taper: +styles.strokeWidth * 20 },
170
-        start: { taper: +styles.strokeWidth * 20 },
171
-      })
172
-    )
173
-  )
174
+  if (shape.points.length < 2) {
175
+    pathCache.set(shape.points, '')
176
+    return
177
+  }
178
+
179
+  const options =
180
+    shape.points[1][2] === 0.5 ? simulatePressureSettings : realPressureSettings
181
+
182
+  const stroke = getStroke(shape.points, {
183
+    size: 1 + +styles.strokeWidth * 2,
184
+    thinning: 0.85,
185
+    end: { taper: +styles.strokeWidth * 20 },
186
+    start: { taper: +styles.strokeWidth * 20 },
187
+    ...options,
188
+  })
189
+
190
+  pathCache.set(shape.points, getSvgPathFromStroke(stroke))
174 191
 }

+ 1
- 0
lib/shape-utils/index.tsx Datei anzeigen

@@ -8,6 +8,7 @@ import {
8 8
   ShapeBinding,
9 9
   Mutable,
10 10
   ShapeByType,
11
+  Data,
11 12
 } from 'types'
12 13
 import * as vec from 'utils/vec'
13 14
 import {

+ 11
- 5
state/inputs.tsx Datei anzeigen

@@ -19,6 +19,7 @@ class Inputs {
19 19
       pointerId: touch.identifier,
20 20
       origin: [touch.clientX, touch.clientY],
21 21
       point: [touch.clientX, touch.clientY],
22
+      pressure: 0.5,
22 23
       shiftKey,
23 24
       ctrlKey,
24 25
       metaKey: isDarwin() ? metaKey : ctrlKey,
@@ -42,6 +43,7 @@ class Inputs {
42 43
       ...prev,
43 44
       pointerId: touch.identifier,
44 45
       point: [touch.clientX, touch.clientY],
46
+      pressure: 0.5,
45 47
       shiftKey,
46 48
       ctrlKey,
47 49
       metaKey: isDarwin() ? metaKey : ctrlKey,
@@ -61,8 +63,9 @@ class Inputs {
61 63
     const info = {
62 64
       target,
63 65
       pointerId: e.pointerId,
64
-      origin: [e.clientX, e.clientY, e.pressure],
65
-      point: [e.clientX, e.clientY, e.pressure],
66
+      origin: [e.clientX, e.clientY],
67
+      point: [e.clientX, e.clientY],
68
+      pressure: e.pressure || 0.5,
66 69
       shiftKey,
67 70
       ctrlKey,
68 71
       metaKey: isDarwin() ? metaKey : ctrlKey,
@@ -81,8 +84,9 @@ class Inputs {
81 84
     const info = {
82 85
       target,
83 86
       pointerId: e.pointerId,
84
-      origin: [e.clientX, e.clientY, e.pressure],
85
-      point: [e.clientX, e.clientY, e.pressure],
87
+      origin: [e.clientX, e.clientY],
88
+      point: [e.clientX, e.clientY],
89
+      pressure: e.pressure || 0.5,
86 90
       shiftKey,
87 91
       ctrlKey,
88 92
       metaKey: isDarwin() ? metaKey : ctrlKey,
@@ -100,7 +104,8 @@ class Inputs {
100 104
     const info = {
101 105
       ...prev,
102 106
       pointerId: e.pointerId,
103
-      point: [e.clientX, e.clientY, e.pressure],
107
+      point: [e.clientX, e.clientY],
108
+      pressure: e.pressure || 0.5,
104 109
       shiftKey,
105 110
       ctrlKey,
106 111
       metaKey: isDarwin() ? metaKey : ctrlKey,
@@ -123,6 +128,7 @@ class Inputs {
123 128
       ...prev,
124 129
       origin: prev?.origin || [e.clientX, e.clientY],
125 130
       point: [e.clientX, e.clientY],
131
+      pressure: e.pressure || 0.5,
126 132
       shiftKey,
127 133
       ctrlKey,
128 134
       metaKey: isDarwin() ? metaKey : ctrlKey,

+ 15
- 6
state/sessions/draw-session.ts Datei anzeigen

@@ -11,6 +11,7 @@ let prevEndPoint: number[]
11 11
 export default class BrushSession extends BaseSession {
12 12
   origin: number[]
13 13
   previous: number[]
14
+  last: number[]
14 15
   points: number[][]
15 16
   snapshot: DrawSnapshot
16 17
   isLocked: boolean
@@ -20,6 +21,7 @@ export default class BrushSession extends BaseSession {
20 21
     super(data)
21 22
     this.origin = point
22 23
     this.previous = point
24
+    this.last = point
23 25
     this.points = []
24 26
     this.snapshot = getDrawSnapshot(data, id)
25 27
 
@@ -28,7 +30,12 @@ export default class BrushSession extends BaseSession {
28 30
     getShapeUtils(shape).translateTo(shape, point)
29 31
   }
30 32
 
31
-  update = (data: Data, point: number[], isLocked = false) => {
33
+  update = (
34
+    data: Data,
35
+    point: number[],
36
+    pressure: number,
37
+    isLocked = false
38
+  ) => {
32 39
     const { snapshot } = this
33 40
 
34 41
     const delta = vec.vec(this.origin, point)
@@ -63,14 +70,16 @@ export default class BrushSession extends BaseSession {
63 70
       }
64 71
     }
65 72
 
66
-    if (this.previous) {
67
-      point = vec.med(this.previous, point)
68
-    }
73
+    point = vec.med(this.previous, point)
74
+
75
+    const next = [...vec.sub(point, this.origin), pressure]
69 76
 
70
-    prevEndPoint = [...point]
71
-    const next = vec.sub(point, this.origin)
77
+    // Don't add duplicate points
78
+    if (vec.isEqual(this.last, next)) return
72 79
 
73 80
     this.points.push(next)
81
+
82
+    this.last = next
74 83
     this.previous = point
75 84
 
76 85
     const shape = getShape(data, snapshot.id) as DrawShape

+ 7
- 1
state/state.ts Datei anzeigen

@@ -981,11 +981,17 @@ const state = createState({
981 981
       session.update(
982 982
         data,
983 983
         screenToWorld(inputs.pointer.point, data),
984
+        payload.pressure,
984 985
         payload.shiftKey
985 986
       )
986 987
     },
987 988
     updateDrawSession(data, payload: PointerInfo) {
988
-      session.update(data, screenToWorld(payload.point, data), payload.shiftKey)
989
+      session.update(
990
+        data,
991
+        screenToWorld(payload.point, data),
992
+        payload.pressure,
993
+        payload.shiftKey
994
+      )
989 995
     },
990 996
 
991 997
     // Arrow

+ 1
- 0
types.ts Datei anzeigen

@@ -248,6 +248,7 @@ export interface PointerInfo {
248 248
   pointerId: number
249 249
   origin: number[]
250 250
   point: number[]
251
+  pressure: number
251 252
   shiftKey: boolean
252 253
   ctrlKey: boolean
253 254
   metaKey: boolean

Laden…
Abbrechen
Speichern