1<!DOCTYPE html> 2<html> 3<head> 4 <title>Skottie-WASM Perf</title> 5 <meta charset="utf-8" /> 6 <meta http-equiv="X-UA-Compatible" content="IE=egde,chrome=1"> 7 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 8 <script src="res/canvaskit.js" type="text/javascript" charset="utf-8"></script> 9 <style type="text/css" media="screen"> 10 body { 11 margin: 0; 12 padding: 0; 13 } 14 </style> 15</head> 16<body> 17 <main> 18 <canvas id=anim width=1000 height=1000 style="height: 1000px; width: 1000px;"></canvas> 19 </main> 20 <script type="text/javascript" charset="utf-8"> 21 (function() { 22 const PATH = '/res/lottie.json'; 23 24 let lottieJSON = null; 25 let CK = null; 26 27 CanvasKitInit({ 28 locateFile: (file) => '/res/'+file, 29 }).ready().then((CanvasKit) => { 30 CK = CanvasKit; 31 Bench(CK, lottieJSON); 32 }); 33 34 fetch(PATH).then((resp) => { 35 resp.text().then((json) => { 36 lottieJSON = json; 37 Bench(CK, lottieJSON); 38 }); 39 }); 40 })(); 41 42 const maxFrames = 25; 43 const maxLoops = 5; 44 45 function Bench(CK, json) { 46 if (!CK || !json) { 47 return; 48 } 49 50 const animation = CK.MakeManagedAnimation(json, null); 51 if (!animation) { 52 window._error = 'Could not process JSON'; 53 return 54 } 55 56 let surface = null; 57 if (window.location.hash.indexOf('gpu') !== -1) { 58 surface = CK.MakeWebGLCanvasSurface('anim'); 59 if (!surface) { 60 window._error = 'Could not make GPU surface'; 61 return; 62 } 63 let c = document.getElementById('anim'); 64 // If CanvasKit was unable to instantiate a WebGL context, it will fallback 65 // to CPU and add a ck-replaced class to the canvas element. 66 if (c.classList.contains('ck-replaced')) { 67 window._error = 'fell back to CPU'; 68 return; 69 } 70 } else { 71 surface = CK.MakeSWCanvasSurface('anim'); 72 if (!surface) { 73 window._error = 'Could not make CPU surface'; 74 return; 75 } 76 } 77 const canvas = surface.getCanvas(); 78 79 const t_rate = 1.0 / (maxFrames-1); 80 let seek = 0; 81 let frame = 0; 82 let loop = 0; 83 const drawFrame = () => { 84 if (frame >= maxFrames) { 85 // Reached the end of one loop. 86 loop++; 87 if (loop == maxLoops) { 88 // These are global variables to talk with puppeteer. 89 window._skottieDone = true; 90 return; 91 } 92 // Reset frame and seek to restart the loop. 93 frame = 0; 94 seek = 0; 95 } 96 97 let damage = animation.seek(seek); 98 if (damage.fRight > damage.fLeft && damage.fBottom > damage.fTop) { 99 animation.render(canvas, { 100 fLeft: 0, 101 fTop: 0, 102 fRight: 1000, 103 fBottom: 1000 104 }); 105 surface.flush(); 106 } 107 console.log(`Used seek: ${seek}`); 108 seek += t_rate; 109 frame++; 110 window.requestAnimationFrame(drawFrame); 111 }; 112 window.requestAnimationFrame(drawFrame); 113 } 114 </script> 115</body> 116</html> 117