Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / demos.skia.org / demos / path_performance / main.js
1 const DEFAULT_METHOD = 'SVG';
2
3 const worker = new Worker('worker.js');
4
5 const svgObjectElement = document.getElementById('svg');
6 document.getElementById('svg').addEventListener('load', () => {
7
8     const svgElement = svgObjectElement.contentDocument;
9     const svgData = svgToPathStringAndFillColorPairs(svgElement);
10
11     // Send svgData and transfer an offscreenCanvas to the worker for Path2D and CanvasKit rendering
12     const path2dCanvas =
13         document.getElementById('Path2D-canvas').transferControlToOffscreen();
14     worker.postMessage({
15         svgData: svgData,
16         offscreenCanvas: path2dCanvas,
17         type: 'Path2D'
18     }, [path2dCanvas]);
19     const canvasKitCanvas =
20         document.getElementById('CanvasKit-canvas').transferControlToOffscreen();
21     worker.postMessage({
22         svgData: svgData,
23         offscreenCanvas: canvasKitCanvas,
24         type: 'CanvasKit'
25     }, [canvasKitCanvas]);
26
27     // The Canvas2D and CanvasKit rendering methods are executed in a web worker to avoid blocking
28     // the main thread. The SVG rendering method is executed in the main thread. SVG rendering is
29     // not in a worker because it is not possible - the DOM cannot be accessed from a web worker.
30     const svgAnimator = new Animator();
31     svgAnimator.renderer = new SVGRenderer(svgObjectElement);
32     switchRenderMethodCallback(DEFAULT_METHOD)();
33
34     // Listen to framerate reports from the worker, and update framerate text
35     worker.addEventListener('message', ({ data: {renderMethod, framesCount, totalFramesMs} }) => {
36         const fps = fpsFromFramesInfo(framesCount, totalFramesMs);
37         let textEl;
38         if (renderMethod === 'Path2D') {
39             textEl = document.getElementById('Path2D-fps');
40         }
41         if (renderMethod === 'CanvasKit') {
42             textEl = document.getElementById('CanvasKit-fps');
43         }
44         textEl.innerText = `${fps.toFixed(2)} fps over ${framesCount} frames`;
45     });
46     // Update framerate text every second
47     setInterval(() => {
48         if (svgAnimator.framesCount > 0) {
49             const fps = fpsFromFramesInfo(svgAnimator.framesCount, svgAnimator.totalFramesMs);
50             document.getElementById('SVG-fps').innerText =
51                 `${fps.toFixed(2)} fps over ${svgAnimator.framesCount} frames`;
52         }
53     }, 1000);
54
55     document.getElementById('SVG-input')
56         .addEventListener('click', switchRenderMethodCallback('SVG'));
57     document.getElementById('Path2D-input')
58         .addEventListener('click', switchRenderMethodCallback('Path2D'));
59     document.getElementById('CanvasKit-input')
60         .addEventListener('click', switchRenderMethodCallback('CanvasKit'));
61
62     function switchRenderMethodCallback(switchMethod) {
63         return () => {
64             // Hide all renderer elements and stop svgAnimator
65             document.getElementById('CanvasKit-canvas').style.visibility = 'hidden';
66             document.getElementById('Path2D-canvas').style.visibility = 'hidden';
67             for (const svgEl of svgAnimator.renderer.svgElArray) {
68                 svgEl.style.visibility = 'hidden';
69             }
70             svgAnimator.stop();
71
72             // Show only the active renderer element
73             if (switchMethod === 'SVG') {
74                 svgAnimator.start();
75                 for (const svgEl of svgAnimator.renderer.svgElArray) {
76                     svgEl.style.visibility = 'visible';
77                 }
78             }
79             if (switchMethod === 'CanvasKit') {
80                 document.getElementById('CanvasKit-canvas').style.visibility = 'visible';
81             }
82             if (switchMethod === 'Path2D') {
83                 document.getElementById('Path2D-canvas').style.visibility = 'visible';
84             }
85             worker.postMessage({ switchMethod });
86         };
87     }
88 });
89 // Add .data after the load listener so that the listener always fires an event
90 svgObjectElement.data = 'garbage.svg';
91
92 const EMPTY_SVG_PATH_STRING = 'M 0 0';
93 const COLOR_WHITE = '#000000';
94 function svgToPathStringAndFillColorPairs(svgElement) {
95     const pathElements = Array.from(svgElement.getElementsByTagName('path'));
96     return pathElements.map((path) => [
97         path.getAttribute('d') ?? EMPTY_SVG_PATH_STRING,
98         path.getAttribute('fill') ?? COLOR_WHITE
99     ]);
100 }
101
102 const MS_IN_A_SECOND = 1000;
103 function fpsFromFramesInfo(framesCount, totalFramesMs) {
104     const averageFrameTime = totalFramesMs / framesCount;
105     return (1 / averageFrameTime) * MS_IN_A_SECOND;
106 }