@px-petals/roku.motion-web 0.0.0-stage → 1.1.0

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.
Files changed (99) hide show
  1. package/LICENSE +201 -0
  2. package/audio/audio.cues.js +27 -0
  3. package/audio/audio.js +259 -0
  4. package/bands/bands.js +392 -0
  5. package/bundle/bundle.fonts.js +55 -0
  6. package/bundle/bundle.js +131 -0
  7. package/focus/focus.direction.js +46 -0
  8. package/focus/focus.dom.js +158 -0
  9. package/focus/focus.js +277 -0
  10. package/focus/focus.tree.js +146 -0
  11. package/hit/hit.geometry.js +113 -0
  12. package/hit/hit.js +129 -0
  13. package/list/list.flex.js +181 -0
  14. package/list/list.items.js +80 -0
  15. package/list/list.js +518 -0
  16. package/lottie/lottie.js +124 -0
  17. package/lottie/lottie.layers.js +416 -0
  18. package/lottie/lottie.paint.js +238 -0
  19. package/lottie/lottie.paths.js +474 -0
  20. package/lottie/lottie.props.js +265 -0
  21. package/lottie/lottie.shapes.js +259 -0
  22. package/mixer/mixer.js +307 -0
  23. package/mixer/mixer.mix.js +107 -0
  24. package/mixer/mixer.stage.js +431 -0
  25. package/motion/motion.convert.js +404 -0
  26. package/motion/motion.flow.js +421 -0
  27. package/motion/motion.keys.js +150 -0
  28. package/motion/motion.machine.js +382 -0
  29. package/motion/motion.nested.js +345 -0
  30. package/motion/motion.values.js +368 -0
  31. package/motion.js +1155 -0
  32. package/package.json +47 -4
  33. package/player/overlay/overlay.js +325 -0
  34. package/player/overlay/overlay.layout.js +208 -0
  35. package/player/player.fit.js +101 -0
  36. package/player/player.js +421 -0
  37. package/player/player.raster.js +127 -0
  38. package/pointer/pointer.js +292 -0
  39. package/readme.md +345 -0
  40. package/script/luau/lib/base/base.js +202 -0
  41. package/script/luau/lib/base/base.table.js +189 -0
  42. package/script/luau/lib/lib.args.js +152 -0
  43. package/script/luau/lib/lib.js +23 -0
  44. package/script/luau/lib/math/math.bit32.js +144 -0
  45. package/script/luau/lib/math/math.js +288 -0
  46. package/script/luau/lib/math/math.vector.js +125 -0
  47. package/script/luau/lib/string/string.format.js +143 -0
  48. package/script/luau/lib/string/string.js +160 -0
  49. package/script/luau/lib/string/string.pattern.js +505 -0
  50. package/script/luau/load/load.js +362 -0
  51. package/script/luau/load/load.ops.js +79 -0
  52. package/script/luau/luau.convert.js +259 -0
  53. package/script/luau/luau.js +132 -0
  54. package/script/luau/luau.md +111 -0
  55. package/script/luau/vm/vm.js +167 -0
  56. package/script/luau/vm/vm.meta.js +401 -0
  57. package/script/luau/vm/vm.num.js +236 -0
  58. package/script/luau/vm/vm.run.js +842 -0
  59. package/script/luau/vm/vm.value.js +406 -0
  60. package/script/play/play.js +199 -0
  61. package/script/play/play.objects.js +295 -0
  62. package/script/play/play.scope.js +91 -0
  63. package/script/rive/api/api.statics.js +31 -0
  64. package/script/rive/api/api.type.js +188 -0
  65. package/script/rive/api/artboard/artboard.js +89 -0
  66. package/script/rive/api/assets/assets.js +72 -0
  67. package/script/rive/api/data/data.value.js +99 -0
  68. package/script/rive/api/draw/draw.contours.js +163 -0
  69. package/script/rive/api/draw/draw.measure.js +196 -0
  70. package/script/rive/api/draw/draw.paint.js +235 -0
  71. package/script/rive/api/draw/draw.path.js +153 -0
  72. package/script/rive/api/draw/draw.renderer.js +117 -0
  73. package/script/rive/api/math/math.color.js +96 -0
  74. package/script/rive/api/math/math.mat2d.js +180 -0
  75. package/script/rive/api/math/math.vector.js +121 -0
  76. package/script/rive/api/media/media.audio.js +113 -0
  77. package/script/rive/api/media/media.draw.js +73 -0
  78. package/script/rive/api/media/media.image.js +61 -0
  79. package/script/rive/api/media/media.mesh.js +50 -0
  80. package/script/rive/api/pointer/pointer.event.js +64 -0
  81. package/script/rive/api/pointer/pointer.route.js +69 -0
  82. package/script/rive/api/text/text.font.js +129 -0
  83. package/script/rive/api/text/text.js +278 -0
  84. package/script/rive/api/text/text.layout.js +259 -0
  85. package/script/rive/context/context.js +76 -0
  86. package/script/rive/context/context.memory.js +196 -0
  87. package/script/rive/context/context.viewmodel.js +302 -0
  88. package/script/rive/context/lists/lists.js +160 -0
  89. package/script/rive/context/lists/lists.values.js +281 -0
  90. package/script/rive/host/host.globals.js +44 -0
  91. package/script/rive/host/host.js +533 -0
  92. package/script/rive/host/host.node.js +45 -0
  93. package/script/rive/rive.js +23 -0
  94. package/script/rive/rive.md +180 -0
  95. package/script/script.js +11 -0
  96. package/skin/skin.deform.js +514 -0
  97. package/skin/skin.ik.js +260 -0
  98. package/skin/skin.js +297 -0
  99. package/README.md +0 -3
@@ -0,0 +1,292 @@
1
+ /**
2
+ * The pointer on the canvas: mouse, touch and pen events become the pointer
3
+ * interactions a bundle's listeners answer (down, up, enter, exit, move,
4
+ * click), each hit-tested against the shape or group the listener targets.
5
+ *
6
+ * - A target is hovered while the pointer is inside its geometry in the last
7
+ * drawn frame (`hit/`), so enter and exit follow a moving shape as well as
8
+ * a moving pointer.
9
+ * - A listener with no target watches the whole canvas: it enters when the
10
+ * pointer comes onto the canvas and exits when it leaves.
11
+ * - A click is a down and an up on the same target. Clicks on the canvas
12
+ * itself (the `click` event) belong to the listeners with no target, which
13
+ * motion.js forwards.
14
+ *
15
+ * Events: `pointer*` where the browser has them (they cover mouse, touch and
16
+ * pen); otherwise `mouse*` and `touch*`, ignoring the mouse events a touch
17
+ * makes up afterwards.
18
+ */
19
+
20
+ /** @import { Hits } from '../hit/hit.js' */
21
+
22
+ /** A mouse event this soon after a touch is the browser's own imitation of it */
23
+ const TOUCH_MOUSE_MS = 800
24
+
25
+ /**
26
+ * @typedef {object} PointerOptions
27
+ * @property {() => Hits | null} hits the geometry the last frame drew; null while it is not vector
28
+ * @property {(type: string, target: string) => void} fire runs a pointer interaction; target "" for the listeners without one
29
+ * @property {boolean} clicks whether a click fires Click interactions
30
+ */
31
+
32
+ /**
33
+ * @param {HTMLCanvasElement} canvas
34
+ * @param {PointerOptions} options
35
+ */
36
+ export function createPointer(canvas, options) {
37
+ /** @type {Record<string, string[]>} target → interaction types, as the machine lists them */
38
+ let targets = {}
39
+ /** @type {Record<string, boolean>} */
40
+ let inside = {}
41
+ /** @type {Record<string, boolean>} */
42
+ let pressed = {}
43
+ let lastTouch = 0
44
+ let isBound = false
45
+ /** @type {{ name: string, listener: (event: any) => void }[]} */
46
+ const bound = []
47
+
48
+ /**
49
+ * @param {string} target
50
+ * @param {string} type
51
+ * @returns {boolean}
52
+ */
53
+ const listensTo = (target, type) => !!targets[target] && targets[target].indexOf(type) >= 0
54
+
55
+ /**
56
+ * @param {string[]} types
57
+ * @returns {boolean} whether any target listens to one of these
58
+ */
59
+ const hasAny = (types) => {
60
+ for (const target in targets) for (let n = 0; n < types.length; n++) if (listensTo(target, types[n])) return true
61
+ return false
62
+ }
63
+
64
+ /**
65
+ * @param {string} target
66
+ * @param {number} x
67
+ * @param {number} y
68
+ * @returns {boolean} whether the pointer is on the target
69
+ */
70
+ function isOn(target, x, y) {
71
+ if (target === '') return true
72
+ const hits = options.hits()
73
+ return !!hits && hits.test(target, x, y)
74
+ }
75
+
76
+ /**
77
+ * Takes the interactions each target listens to and starts watching for the pointer, or stops.
78
+ *
79
+ * @param {Record<string, string[]>} next the machine's `pointerTargets`
80
+ */
81
+ function listen(next) {
82
+ // what is watched again keeps where the pointer is on it: rows that come and go do not end a press on the others
83
+ /** @type {Record<string, boolean>} */
84
+ const keptInside = {}
85
+ /** @type {Record<string, boolean>} */
86
+ const keptPressed = {}
87
+ for (const name in next) {
88
+ if (!targets[name]) continue
89
+ keptInside[name] = inside[name]
90
+ keptPressed[name] = pressed[name]
91
+ }
92
+ targets = next
93
+ inside = keptInside
94
+ pressed = keptPressed
95
+ const wanted = hasAny([ 'PointerDown', 'PointerUp', 'PointerEnter', 'PointerExit', 'PointerMove' ]) || (options.clicks && hasAnyTargeted('Click'))
96
+ if (wanted && !isBound) bind()
97
+ else if (!wanted && isBound) unbind()
98
+ }
99
+
100
+ /**
101
+ * @param {string} type
102
+ * @returns {boolean} whether a listener on a target (not the whole artboard) has it
103
+ */
104
+ function hasAnyTargeted(type) {
105
+ for (const target in targets) if (target !== '' && listensTo(target, type)) return true
106
+ return false
107
+ }
108
+
109
+ /** @returns {string[]} the targets that have a pointer interaction */
110
+ function names() {
111
+ const list = []
112
+ for (const target in targets) list.push(target)
113
+ return list
114
+ }
115
+
116
+ /**
117
+ * The pointer is at a canvas pixel: targets it entered or left fire, and
118
+ * every one it is on fires a move.
119
+ *
120
+ * @param {number} x
121
+ * @param {number} y
122
+ */
123
+ function moved(x, y) {
124
+ const list = names()
125
+ for (let n = 0; n < list.length; n++) {
126
+ const target = list[n]
127
+ const isNow = isOn(target, x, y)
128
+ if (isNow && !inside[target]) {
129
+ inside[target] = true
130
+ if (listensTo(target, 'PointerEnter')) options.fire('PointerEnter', target)
131
+ } else if (!isNow && inside[target]) {
132
+ inside[target] = false
133
+ pressed[target] = false
134
+ if (listensTo(target, 'PointerExit')) options.fire('PointerExit', target)
135
+ }
136
+ if (isNow && listensTo(target, 'PointerMove')) options.fire('PointerMove', target)
137
+ }
138
+ }
139
+
140
+ /**
141
+ * @param {number} x
142
+ * @param {number} y
143
+ */
144
+ function pressedAt(x, y) {
145
+ moved(x, y)
146
+ const list = names()
147
+ for (let n = 0; n < list.length; n++) {
148
+ const target = list[n]
149
+ if (!isOn(target, x, y)) continue
150
+ pressed[target] = true
151
+ if (listensTo(target, 'PointerDown')) options.fire('PointerDown', target)
152
+ }
153
+ }
154
+
155
+ /**
156
+ * @param {number} x
157
+ * @param {number} y
158
+ */
159
+ function releasedAt(x, y) {
160
+ const list = names()
161
+ for (let n = 0; n < list.length; n++) {
162
+ const target = list[n]
163
+ const wasPressed = pressed[target]
164
+ pressed[target] = false
165
+ if (!isOn(target, x, y)) continue
166
+ if (listensTo(target, 'PointerUp')) options.fire('PointerUp', target)
167
+ // a click on the whole canvas is the canvas's own `click` event
168
+ if (wasPressed && target !== '' && options.clicks && listensTo(target, 'Click')) options.fire('Click', target)
169
+ }
170
+ }
171
+
172
+ /** The pointer left the canvas, or its touch ended: every target it was on is exited. */
173
+ function left() {
174
+ const list = names()
175
+ for (let n = 0; n < list.length; n++) {
176
+ const target = list[n]
177
+ pressed[target] = false
178
+ if (!inside[target]) continue
179
+ inside[target] = false
180
+ if (listensTo(target, 'PointerExit')) options.fire('PointerExit', target)
181
+ }
182
+ }
183
+
184
+ /**
185
+ * A client position as canvas pixels, which the hit geometry is in.
186
+ *
187
+ * @param {{ clientX: number, clientY: number }} point
188
+ * @returns {{ x: number, y: number } | null} null while the canvas has no size
189
+ */
190
+ function place(point) {
191
+ const box = canvas.getBoundingClientRect()
192
+ if (!box.width || !box.height) return null
193
+ return { x: ((point.clientX - box.left) * canvas.width) / box.width, y: ((point.clientY - box.top) * canvas.height) / box.height }
194
+ }
195
+
196
+ /**
197
+ * @param {(x: number, y: number) => void} then
198
+ * @param {{ clientX: number, clientY: number } | undefined} point
199
+ */
200
+ function at(then, point) {
201
+ const where = point ? place(point) : null
202
+ if (where) then(where.x, where.y)
203
+ }
204
+
205
+ /** @param {any} event */
206
+ const isMouseAfterTouch = (event) => event.type.indexOf('mouse') === 0 && Date.now() - lastTouch < TOUCH_MOUSE_MS
207
+
208
+ /** @param {any} event */
209
+ const firstTouch = (event) => (event.changedTouches && event.changedTouches[0]) || (event.touches && event.touches[0])
210
+
211
+ /** @type {Record<string, (event: any) => void>} */
212
+ const handlers = {
213
+ // pen, touch and mouse together
214
+ pointerdown: (event) => {
215
+ if (event.button) return
216
+ at(pressedAt, event)
217
+ },
218
+ pointermove: (event) => at(moved, event),
219
+ pointerup: (event) => {
220
+ if (event.button) return
221
+ at(releasedAt, event)
222
+ // a finger has no hover: lifting it leaves
223
+ if (event.pointerType && event.pointerType !== 'mouse') left()
224
+ },
225
+ pointercancel: () => left(),
226
+ pointerleave: () => left(),
227
+
228
+ // the browsers before pointer events
229
+ mousedown: (event) => {
230
+ if (isMouseAfterTouch(event) || event.button) return
231
+ at(pressedAt, event)
232
+ },
233
+ mousemove: (event) => {
234
+ if (!isMouseAfterTouch(event)) at(moved, event)
235
+ },
236
+ mouseup: (event) => {
237
+ if (isMouseAfterTouch(event) || event.button) return
238
+ at(releasedAt, event)
239
+ },
240
+ mouseleave: (event) => {
241
+ if (!isMouseAfterTouch(event)) left()
242
+ },
243
+ touchstart: (event) => {
244
+ lastTouch = Date.now()
245
+ at(pressedAt, firstTouch(event))
246
+ },
247
+ touchmove: (event) => {
248
+ lastTouch = Date.now()
249
+ at(moved, firstTouch(event))
250
+ },
251
+ touchend: (event) => {
252
+ lastTouch = Date.now()
253
+ at(releasedAt, firstTouch(event))
254
+ left()
255
+ },
256
+ touchcancel: () => {
257
+ lastTouch = Date.now()
258
+ left()
259
+ },
260
+ }
261
+
262
+ function bind() {
263
+ const events = window.PointerEvent
264
+ ? [ 'pointerdown', 'pointermove', 'pointerup', 'pointercancel', 'pointerleave' ]
265
+ : [ 'mousedown', 'mousemove', 'mouseup', 'mouseleave', 'touchstart', 'touchmove', 'touchend', 'touchcancel' ]
266
+ for (let n = 0; n < events.length; n++) {
267
+ bound.push({ name: events[n], listener: handlers[events[n]] })
268
+ canvas.addEventListener(events[n], handlers[events[n]], false)
269
+ }
270
+ isBound = true
271
+ }
272
+
273
+ function unbind() {
274
+ for (let n = 0; n < bound.length; n++) canvas.removeEventListener(bound[n].name, bound[n].listener, false)
275
+ bound.length = 0
276
+ isBound = false
277
+ }
278
+
279
+ return {
280
+ listen,
281
+ destroy() {
282
+ unbind()
283
+ targets = {}
284
+ },
285
+ /** The targets the pointer is on now, for tests and hosts */
286
+ get hovering() {
287
+ const list = []
288
+ for (const target in inside) if (inside[target] && target !== '') list.push(target)
289
+ return list
290
+ },
291
+ }
292
+ }