1// The increased timeout is especially needed with larger binaries
2// like in the debug/gpu build
3jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000;
4
5describe('CanvasKit\'s Animation', function() {
6    // Note, don't try to print the CanvasKit object - it can cause Karma/Jasmine to lock up.
7    var CanvasKit = null;
8    const LoadCanvasKit = new Promise(function(resolve, reject) {
9        if (CanvasKit) {
10            resolve();
11        } else {
12            CanvasKitInit({
13                locateFile: (file) => '/canvaskit/'+file,
14            }).ready().then((_CanvasKit) => {
15                CanvasKit = _CanvasKit;
16                resolve();
17            });
18        }
19    });
20
21    const LOTTIE_ANIMATIONS = ['lego_loader', 'drinks', 'confetti', 'onboarding'];
22
23    let container = document.createElement('div');
24    document.body.appendChild(container);
25
26
27    beforeEach(function() {
28        container.innerHTML = `
29            <canvas width=600 height=600 id=test></canvas>`;
30    });
31
32    afterEach(function() {
33        container.innerHTML = '';
34    });
35
36    function fetchAndText(url) {
37        return new Promise(function(resolve, reject) {
38            fetch(url).then((resp) => {
39                    resp.text().then((str) => {
40                        expect(str).toBeTruthy();
41                        resolve(str);
42                    });
43                }).catch(reject);
44        });
45    }
46
47    LOTTIE_ANIMATIONS.forEach((animStr) => {
48        let promises = [fetchAndText(`/assets/${animStr}.json`), LoadCanvasKit];
49
50        it(`animation loading for ${animStr}`, function(done) {
51            let jsonStr = '';
52            function setup(ctx) {
53                expect(jsonStr).toBeTruthy();
54            }
55
56            function test(ctx) {
57                const animation = CanvasKit.MakeAnimation(jsonStr);
58                animation.delete();
59            }
60
61            function teardown(ctx) {}
62
63            Promise.all(promises).then((responses) => {
64                // The result from the first promise, that is, the JSON string
65                // fetched by fetchAndText
66                jsonStr = responses[0];
67                benchmarkAndReport(`${animStr}_animation_load`, setup, test, teardown).then(() => {
68                    done();
69                }).catch(reportError(done));
70            });
71        });
72
73        it(`animation frames in order for ${animStr}`, function(done) {
74            let jsonStr = '';
75            function setup(ctx) {
76                expect(jsonStr).toBeTruthy();
77                ctx.animation = CanvasKit.MakeAnimation(jsonStr);
78                expect(ctx.animation).toBeTruthy();
79                ctx.timer = 0;
80            }
81
82            function test(ctx) {
83                ctx.animation.seek(ctx.timer);
84                ctx.timer += 0.01;
85                if (ctx.timer > 1.0) {
86                    ctx.timer = 0;
87                }
88            }
89
90            function teardown(ctx) {
91                ctx.animation.delete();
92            }
93
94            Promise.all(promises).then((responses) => {
95                // The result from the first promise, that is, the JSON string
96                // fetched by fetchAndText
97                jsonStr = responses[0];
98                benchmarkAndReport(`${animStr}_animation_in_order`, setup, test, teardown).then(() => {
99                    done();
100                }).catch(reportError(done));
101            });
102        });
103
104        it(`animation frames in random order for ${animStr}`, function(done) {
105            let jsonStr = '';
106            function setup(ctx) {
107                expect(jsonStr).toBeTruthy();
108                ctx.animation = CanvasKit.MakeAnimation(jsonStr);
109                expect(ctx.animation).toBeTruthy();
110            }
111
112            function test(ctx) {
113                ctx.animation.seek(Math.random());
114            }
115
116            function teardown(ctx) {
117                ctx.animation.delete();
118            }
119
120            Promise.all(promises).then((responses) => {
121                // The result from the first promise, that is, the JSON string
122                // fetched by fetchAndText
123                jsonStr = responses[0];
124                benchmarkAndReport(`${animStr}_animation_random_order`, setup, test, teardown).then(() => {
125                    done();
126                }).catch(reportError(done));
127            });
128        });
129
130        it(`renders to an HTML canvas ${animStr}`, function(done) {
131            let jsonStr = '';
132            function setup(ctx) {
133                expect(jsonStr).toBeTruthy();
134                ctx.animation = CanvasKit.MakeAnimation(jsonStr);
135                expect(ctx.animation).toBeTruthy();
136                ctx.animation.seek(0.5);
137                ctx.surface = CanvasKit.MakeCanvasSurface('test');
138                ctx.canvas = ctx.surface.getCanvas();
139                ctx.clear = CanvasKit.Color(255, 255, 255, 0.0); // transparent
140            }
141
142            function test(ctx) {
143                // This emulates what would need to be done do accurately
144                // draw one frame.
145                ctx.canvas.clear(ctx.clear);
146                ctx.animation.render(ctx.canvas);
147                ctx.surface.flush();
148            }
149
150            function teardown(ctx) {
151                ctx.animation.delete();
152                ctx.surface.dispose(); // ctx.canvas will also be cleaned up
153            }
154
155            Promise.all(promises).then((responses) => {
156                // The result from the first promise, that is, the JSON string
157                // fetched by fetchAndText
158                jsonStr = responses[0];
159                benchmarkAndReport(`${animStr}_animation_render_flush`, setup, test, teardown).then(() => {
160                    done();
161                }).catch(reportError(done));
162            });
163        });
164
165    });
166
167});
168