@revideo/2d 0.4.9-alpha.1038 → 0.4.9-test.1044

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.
@@ -0,0 +1,156 @@
1
+ import {
2
+ BBox,
3
+ SignalValue,
4
+ SimpleSignal,
5
+ useThread,
6
+ viaProxy,
7
+ } from '@revideo/core';
8
+ import RiveInitializer, {
9
+ Artboard,
10
+ File,
11
+ LinearAnimationInstance,
12
+ Renderer,
13
+ RiveCanvas,
14
+ } from '@rive-app/canvas-advanced';
15
+ import {computed, initial, nodeName, signal} from '../decorators';
16
+ import {Asset} from './Asset';
17
+ import {RectProps} from './Rect';
18
+
19
+ export interface RiveProps extends RectProps {
20
+ src?: SignalValue<string>;
21
+ artboardId?: SignalValue<string | number>;
22
+ animationId?: SignalValue<string | number>;
23
+ }
24
+
25
+ interface RiveInstance {
26
+ rive: RiveCanvas;
27
+ renderer: Renderer;
28
+ artboard: Artboard;
29
+ animation: LinearAnimationInstance;
30
+ canvas: HTMLCanvasElement;
31
+ }
32
+
33
+ @nodeName('Rive')
34
+ export class Rive extends Asset {
35
+ @initial(0)
36
+ @signal()
37
+ public declare readonly artboardId: SimpleSignal<number | string, this>;
38
+
39
+ @initial(0)
40
+ @signal()
41
+ public declare readonly animationId: SimpleSignal<number | string, this>;
42
+
43
+ @initial(0)
44
+ @signal()
45
+ protected declare readonly time: SimpleSignal<number, this>;
46
+
47
+ protected currentTime: number = 0;
48
+ protected lastTime: number = 0;
49
+
50
+ public constructor(props: RiveProps) {
51
+ super(props);
52
+
53
+ const time = useThread().time;
54
+ const start = time();
55
+ this.time(() => time() - start);
56
+ }
57
+
58
+ @computed()
59
+ private async rive(): Promise<RiveInstance> {
60
+ const src = viaProxy(this.fullSource());
61
+ const rive = await RiveInitializer({
62
+ locateFile: () => {
63
+ return '/@rive-wasm';
64
+ },
65
+ });
66
+ const canvas = document.createElement('canvas');
67
+ canvas.width = this.width();
68
+ canvas.height = this.height();
69
+
70
+ const renderer = rive.makeRenderer(canvas);
71
+ const bytes = await (await fetch(new Request(src))).arrayBuffer();
72
+ const file = (await rive.load(new Uint8Array(bytes))) as File;
73
+
74
+ const artboardId = this.artboardId();
75
+ const artboard = this.getArtboard(artboardId, file);
76
+
77
+ const animationId = this.animationId();
78
+ const animation = this.getAnimation(animationId, artboard, rive);
79
+
80
+ return {rive, renderer, artboard, animation, canvas};
81
+ }
82
+
83
+ protected override async draw(context: CanvasRenderingContext2D) {
84
+ this.drawShape(context);
85
+ const {rive, renderer, canvas, artboard, animation} = await this.rive();
86
+ const box = BBox.fromSizeCentered(this.computedSize());
87
+
88
+ this.currentTime = this.time();
89
+ const timeToAdvance = this.currentTime - this.lastTime;
90
+ this.lastTime = this.currentTime;
91
+
92
+ const renderPromise = new Promise<void>(resolve => {
93
+ function renderLoop() {
94
+ renderer.clear();
95
+ animation.advance(timeToAdvance);
96
+ animation.apply(1);
97
+
98
+ artboard.advance(timeToAdvance);
99
+
100
+ renderer.save();
101
+ renderer.align(
102
+ rive.Fit.fill,
103
+ rive.Alignment.center,
104
+ {
105
+ minX: 0,
106
+ minY: 0,
107
+ maxX: canvas.width,
108
+ maxY: canvas.height,
109
+ },
110
+ artboard.bounds,
111
+ );
112
+
113
+ artboard.draw(renderer);
114
+ renderer.restore();
115
+ resolve();
116
+ }
117
+
118
+ rive.requestAnimationFrame(renderLoop);
119
+ });
120
+
121
+ await renderPromise;
122
+
123
+ context.drawImage(canvas, box.x, box.y, box.width, box.height);
124
+ if (this.clip()) {
125
+ context.clip(this.getPath());
126
+ }
127
+
128
+ await this.drawChildren(context);
129
+ }
130
+
131
+ private getArtboard(artboardId: string | number, file: File): Artboard {
132
+ if (typeof artboardId === 'string') {
133
+ return file.artboardByName(artboardId);
134
+ }
135
+ if (typeof artboardId === 'number') {
136
+ return file.artboardByIndex(artboardId);
137
+ }
138
+ return file.defaultArtboard();
139
+ }
140
+
141
+ private getAnimation(
142
+ animationId: string | number,
143
+ artboard: Artboard,
144
+ rive: RiveCanvas,
145
+ ): LinearAnimationInstance {
146
+ let animation;
147
+ if (typeof animationId === 'number') {
148
+ animation = artboard.animationByIndex(animationId);
149
+ } else if (typeof animationId === 'string') {
150
+ animation = artboard.animationByName(animationId);
151
+ } else {
152
+ animation = artboard.animationByIndex(0);
153
+ }
154
+ return new rive.LinearAnimationInstance(animation, artboard);
155
+ }
156
+ }
@@ -18,6 +18,7 @@ export * from './Polygon';
18
18
  export * from './QuadBezier';
19
19
  export * from './Ray';
20
20
  export * from './Rect';
21
+ export * from './Rive';
21
22
  export * from './SVG';
22
23
  export * from './Shape';
23
24
  export * from './Spline';