@rafaelaugusto/jolt 0.1.0-beta.12 → 0.1.0-beta.14
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 +9 -6
- package/dist/animate.d.ts +6 -4
- package/dist/animate.d.ts.map +1 -1
- package/dist/animate.js +3 -1
- package/dist/animate.js.map +1 -1
- package/dist/drag.js +3 -3
- package/dist/drag.js.map +1 -1
- package/dist/driver/android-gradient.d.ts.map +1 -1
- package/dist/driver/android-gradient.js +11 -1
- package/dist/driver/android-gradient.js.map +1 -1
- package/dist/driver/android-particles.d.ts +6 -0
- package/dist/driver/android-particles.d.ts.map +1 -0
- package/dist/driver/android-particles.js +93 -0
- package/dist/driver/android-particles.js.map +1 -0
- package/dist/driver/android.d.ts.map +1 -1
- package/dist/driver/android.js +2 -0
- package/dist/driver/android.js.map +1 -1
- package/dist/driver/frame.d.ts +3 -0
- package/dist/driver/frame.d.ts.map +1 -0
- package/dist/driver/frame.js +7 -0
- package/dist/driver/frame.js.map +1 -0
- package/dist/driver/index.d.ts +2 -0
- package/dist/driver/index.d.ts.map +1 -1
- package/dist/driver/index.js.map +1 -1
- package/dist/driver/ios-gradient.d.ts.map +1 -1
- package/dist/driver/ios-gradient.js +24 -2
- package/dist/driver/ios-gradient.js.map +1 -1
- package/dist/driver/ios.d.ts.map +1 -1
- package/dist/driver/ios.js +2 -0
- package/dist/driver/ios.js.map +1 -1
- package/dist/engine.d.ts +2 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +32 -5
- package/dist/engine.js.map +1 -1
- package/dist/gradient-binding.d.ts +38 -0
- package/dist/gradient-binding.d.ts.map +1 -0
- package/dist/gradient-binding.js +128 -0
- package/dist/gradient-binding.js.map +1 -0
- package/dist/gradient.d.ts +19 -4
- package/dist/gradient.d.ts.map +1 -1
- package/dist/gradient.js +331 -70
- package/dist/gradient.js.map +1 -1
- package/dist/haptics.d.ts.map +1 -1
- package/dist/haptics.js +101 -28
- package/dist/haptics.js.map +1 -1
- package/dist/image-effect.d.ts +1 -0
- package/dist/image-effect.d.ts.map +1 -1
- package/dist/image-effect.js +10 -2
- package/dist/image-effect.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/motion-scope.d.ts +3 -2
- package/dist/motion-scope.d.ts.map +1 -1
- package/dist/motion-scope.js +12 -2
- package/dist/motion-scope.js.map +1 -1
- package/dist/motion-value.d.ts +62 -8
- package/dist/motion-value.d.ts.map +1 -1
- package/dist/motion-value.js +327 -91
- package/dist/motion-value.js.map +1 -1
- package/dist/native/index.d.ts +7 -0
- package/dist/native/index.d.ts.map +1 -0
- package/dist/native/index.js +4 -0
- package/dist/native/index.js.map +1 -0
- package/dist/native-properties.d.ts +28 -0
- package/dist/native-properties.d.ts.map +1 -0
- package/dist/native-properties.js +154 -0
- package/dist/native-properties.js.map +1 -0
- package/dist/native-property-driver.d.ts +19 -0
- package/dist/native-property-driver.d.ts.map +1 -0
- package/dist/native-property-driver.js +69 -0
- package/dist/native-property-driver.js.map +1 -0
- package/dist/native-property.d.ts +35 -0
- package/dist/native-property.d.ts.map +1 -0
- package/dist/native-property.js +277 -0
- package/dist/native-property.js.map +1 -0
- package/dist/particles.d.ts +5 -2
- package/dist/particles.d.ts.map +1 -1
- package/dist/particles.js +16 -10
- package/dist/particles.js.map +1 -1
- package/dist/playback-group.d.ts.map +1 -1
- package/dist/playback-group.js +17 -1
- package/dist/playback-group.js.map +1 -1
- package/dist/playback.d.ts +15 -0
- package/dist/playback.d.ts.map +1 -1
- package/dist/playback.js +23 -0
- package/dist/playback.js.map +1 -1
- package/dist/scene-appearance.d.ts +14 -0
- package/dist/scene-appearance.d.ts.map +1 -0
- package/dist/scene-appearance.js +68 -0
- package/dist/scene-appearance.js.map +1 -0
- package/dist/sequence.d.ts +24 -0
- package/dist/sequence.d.ts.map +1 -1
- package/dist/sequence.js +181 -19
- package/dist/sequence.js.map +1 -1
- package/dist/timed-animation.d.ts +38 -0
- package/dist/timed-animation.d.ts.map +1 -0
- package/dist/timed-animation.js +177 -0
- package/dist/timed-animation.js.map +1 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/value-observers.d.ts +19 -0
- package/dist/value-observers.d.ts.map +1 -0
- package/dist/value-observers.js +111 -0
- package/dist/value-observers.js.map +1 -0
- package/dist/value-track.d.ts +13 -0
- package/dist/value-track.d.ts.map +1 -0
- package/dist/value-track.js +59 -0
- package/dist/value-track.js.map +1 -0
- package/dist/vue/index.d.ts.map +1 -1
- package/dist/vue/index.js +28 -5
- package/dist/vue/index.js.map +1 -1
- package/package.json +6 -2
- package/platforms/android/java/org/rafaelaugusto/jolt/GradientLayer.java +30 -1
- package/platforms/android/java/org/rafaelaugusto/jolt/ParticleEmitter.java +192 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/ParticleSimulation.java +114 -0
- package/platforms/android/proguard-rules.pro +2 -0
- package/src/android-plugin.d.ts +93 -0
- package/src/animate.ts +13 -7
- package/src/drag.ts +3 -3
- package/src/driver/android-gradient.ts +8 -1
- package/src/driver/android-particles.ts +118 -0
- package/src/driver/android.ts +2 -0
- package/src/driver/frame.ts +10 -0
- package/src/driver/index.ts +2 -0
- package/src/driver/ios-gradient.ts +24 -2
- package/src/driver/ios.ts +2 -0
- package/src/engine.ts +33 -6
- package/src/gradient-binding.ts +158 -0
- package/src/gradient.ts +376 -91
- package/src/haptics.ts +106 -28
- package/src/image-effect.ts +10 -2
- package/src/index.ts +6 -0
- package/src/ios-plugin.d.ts +40 -0
- package/src/motion-scope.ts +14 -3
- package/src/motion-value.ts +374 -99
- package/src/native/index.ts +23 -0
- package/src/native-properties.ts +188 -0
- package/src/native-property-driver.ts +123 -0
- package/src/native-property.ts +353 -0
- package/src/particles.ts +18 -17
- package/src/playback-group.ts +17 -1
- package/src/playback.ts +41 -0
- package/src/scene-appearance.ts +92 -0
- package/src/sequence.ts +209 -20
- package/src/timed-animation.ts +192 -0
- package/src/types.ts +1 -1
- package/src/value-observers.ts +133 -0
- package/src/value-track.ts +71 -0
- package/src/vue/index.ts +29 -5
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { parseColor, type ColorValue } from './color.js'
|
|
2
|
+
import { reducedMotion } from './config.js'
|
|
3
|
+
import {
|
|
4
|
+
isDerived,
|
|
5
|
+
valueSource,
|
|
6
|
+
type DerivedValue,
|
|
7
|
+
type DerivedColor,
|
|
8
|
+
} from './motion-value.js'
|
|
9
|
+
import type { GradientFrame } from './gradient.js'
|
|
10
|
+
|
|
11
|
+
export interface GradientBindings {
|
|
12
|
+
colors?: readonly (ColorValue | DerivedColor)[]
|
|
13
|
+
stops?: readonly (number | DerivedValue)[]
|
|
14
|
+
angle?: number | DerivedValue
|
|
15
|
+
center?: { readonly x?: number | DerivedValue; readonly y?: number | DerivedValue }
|
|
16
|
+
radius?: number | DerivedValue
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type GradientComponent =
|
|
20
|
+
'angle' | 'x' | 'y' | 'radius' | `color:${number}` | `stop:${number}`
|
|
21
|
+
export type GradientSource = ReturnType<typeof valueSource>
|
|
22
|
+
export type GradientComponentValue = number | GradientSource
|
|
23
|
+
export type GradientPatch = Map<GradientComponent, GradientComponentValue>
|
|
24
|
+
|
|
25
|
+
export function cloneFrame(frame: GradientFrame): GradientFrame {
|
|
26
|
+
return { ...frame, colors: [...frame.colors], stops: [...frame.stops] }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function put(frame: GradientFrame, key: GradientComponent, value: number) {
|
|
30
|
+
if (key.startsWith('color:')) frame.colors[Number(key.slice(6))] = value
|
|
31
|
+
else if (key.startsWith('stop:')) frame.stops[Number(key.slice(5))] = value
|
|
32
|
+
else frame[key as 'angle' | 'x' | 'y' | 'radius'] = value
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function take(frame: GradientFrame, key: GradientComponent) {
|
|
36
|
+
if (key.startsWith('color:')) return frame.colors[Number(key.slice(6))]!
|
|
37
|
+
if (key.startsWith('stop:')) return frame.stops[Number(key.slice(5))]!
|
|
38
|
+
return frame[key as 'angle' | 'x' | 'y' | 'radius']
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Validate structural/static inputs before touching any existing owner. */
|
|
42
|
+
export function gradientPatch(values: GradientBindings, count: number): GradientPatch {
|
|
43
|
+
if (!values || typeof values !== 'object' || Array.isArray(values))
|
|
44
|
+
throw new TypeError('Gradient values must be an object.')
|
|
45
|
+
const patch: GradientPatch = new Map()
|
|
46
|
+
const add = (key: GradientComponent, value: unknown, color = false) => {
|
|
47
|
+
if (value === undefined) return
|
|
48
|
+
if (isDerived(value)) patch.set(key, valueSource(value, color))
|
|
49
|
+
else if (color) patch.set(key, parseColor(value as ColorValue))
|
|
50
|
+
else {
|
|
51
|
+
if (typeof value !== 'number' || !Number.isFinite(value))
|
|
52
|
+
throw new RangeError(`Invalid gradient ${key}: ${String(value)}.`)
|
|
53
|
+
if (key === 'radius' && value < 0)
|
|
54
|
+
throw new RangeError('Gradient radius must not be negative.')
|
|
55
|
+
if (key.startsWith('stop:') && (value < 0 || value > 1))
|
|
56
|
+
throw new RangeError('Gradient stops must be from 0 to 1.')
|
|
57
|
+
patch.set(key, value)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (values.colors !== undefined) {
|
|
61
|
+
if (
|
|
62
|
+
!Array.isArray(values.colors) ||
|
|
63
|
+
values.colors.length < 2 ||
|
|
64
|
+
values.colors.length > 8
|
|
65
|
+
)
|
|
66
|
+
throw new RangeError('A gradient needs between two and eight colors.')
|
|
67
|
+
count = values.colors.length
|
|
68
|
+
Array.from(values.colors).forEach((value, i) => {
|
|
69
|
+
if (value === undefined) throw new TypeError('Gradient colors cannot be empty.')
|
|
70
|
+
add(`color:${i}`, value, true)
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
if (values.stops !== undefined) {
|
|
74
|
+
if (!Array.isArray(values.stops) || values.stops.length !== count)
|
|
75
|
+
throw new RangeError('Gradient stops need one value per color.')
|
|
76
|
+
Array.from(values.stops).forEach((value, i) => {
|
|
77
|
+
if (value === undefined) throw new TypeError('Gradient stops cannot be empty.')
|
|
78
|
+
add(`stop:${i}`, value)
|
|
79
|
+
})
|
|
80
|
+
if (
|
|
81
|
+
values.stops.every((value) => typeof value === 'number') &&
|
|
82
|
+
values.stops.some((value, i) => i > 0 && value < (values.stops![i - 1] as number))
|
|
83
|
+
)
|
|
84
|
+
throw new RangeError('Gradient stops must be ordered without going back.')
|
|
85
|
+
} else if (values.colors !== undefined) {
|
|
86
|
+
// Preserve the concrete API's rule: replacing colors resets unspecified stops.
|
|
87
|
+
values.colors.forEach((_, i) => patch.set(`stop:${i}`, i / (count - 1)))
|
|
88
|
+
}
|
|
89
|
+
add('angle', values.angle)
|
|
90
|
+
if (
|
|
91
|
+
values.center !== undefined &&
|
|
92
|
+
(!values.center || typeof values.center !== 'object')
|
|
93
|
+
)
|
|
94
|
+
throw new TypeError('Gradient center needs x/y components.')
|
|
95
|
+
add('x', values.center?.x)
|
|
96
|
+
add('y', values.center?.y)
|
|
97
|
+
add('radius', values.radius)
|
|
98
|
+
return patch
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface GradientBase {
|
|
102
|
+
at(delta: number): GradientFrame
|
|
103
|
+
remaining: number
|
|
104
|
+
elapsed(): number
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Native windows share a source clock. Only setup/commands/window boundaries enter JS. */
|
|
108
|
+
export function gradientProgram(base: GradientBase, bindings: GradientPatch) {
|
|
109
|
+
const roots = new Map<object, ReturnType<GradientSource['snapshot']>>()
|
|
110
|
+
for (const value of bindings.values())
|
|
111
|
+
if (typeof value !== 'number' && !roots.has(value.identity))
|
|
112
|
+
roots.set(value.identity, value.snapshot())
|
|
113
|
+
const moving = [...roots.values()].filter((state) => state.running)
|
|
114
|
+
const remaining = Math.max(
|
|
115
|
+
base.remaining,
|
|
116
|
+
...moving.map((state) => state.track.end - state.elapsed),
|
|
117
|
+
0,
|
|
118
|
+
)
|
|
119
|
+
const duration = Math.min(4000, remaining)
|
|
120
|
+
const anchor = moving[0]
|
|
121
|
+
const elapsed = anchor
|
|
122
|
+
? () => Math.max(0, anchor.time() - anchor.elapsed)
|
|
123
|
+
: base.elapsed
|
|
124
|
+
const reduced = reducedMotion()
|
|
125
|
+
const at = (delta: number) => {
|
|
126
|
+
const frame = cloneFrame(base.at(delta))
|
|
127
|
+
for (const [key, source] of bindings) {
|
|
128
|
+
if (typeof source === 'number') {
|
|
129
|
+
put(frame, key, source)
|
|
130
|
+
continue
|
|
131
|
+
}
|
|
132
|
+
const state = roots.get(source.identity)!
|
|
133
|
+
const geometry = key === 'angle' || key === 'x' || key === 'y' || key === 'radius'
|
|
134
|
+
const input =
|
|
135
|
+
reduced && geometry && state.running
|
|
136
|
+
? state.track.to
|
|
137
|
+
: state.running
|
|
138
|
+
? state.track.valueAt(state.elapsed + delta)
|
|
139
|
+
: state.value
|
|
140
|
+
const value = source.read(input)
|
|
141
|
+
if (!Number.isFinite(value))
|
|
142
|
+
throw new RangeError(`Nonfinite gradient binding: ${key}.`)
|
|
143
|
+
put(frame, key, value)
|
|
144
|
+
}
|
|
145
|
+
// Project the complete vector without sorting colors. Spring overshoot may
|
|
146
|
+
// merge adjacent stops; their identity and order are retained.
|
|
147
|
+
frame.radius = Math.max(0, frame.radius)
|
|
148
|
+
frame.stops = frame.stops.map((stop) => Math.min(1, Math.max(0, stop)))
|
|
149
|
+
for (let i = 1; i < frame.stops.length; i++)
|
|
150
|
+
frame.stops[i] = Math.max(frame.stops[i - 1]!, frame.stops[i]!)
|
|
151
|
+
return frame
|
|
152
|
+
}
|
|
153
|
+
const current = at(0)
|
|
154
|
+
const steps = Math.max(1, Math.ceil((duration * 60) / 1000))
|
|
155
|
+
const times = Array.from({ length: steps + 1 }, (_, i) => i / steps)
|
|
156
|
+
const frames = times.map((time) => at(time * duration))
|
|
157
|
+
return { current, frames, times, duration, remaining, elapsed, at }
|
|
158
|
+
}
|