blob: 2b6dc94049c5441ca40265a86243339adcd3cf8e [file] [log] [blame]
Joe Gregorio0060c332018-03-19 14:26:58 -04001<!DOCTYPE html>
2<html>
3<head>
4 <title>Lottie Filmstrip Capture</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="/lottie.js" type="text/javascript" charset="utf-8"></script>
9 <style type="text/css" media="screen">
10 body,
11 main,
12 .anim {
13 margin: 0;
14 padding: 0;
15 }
16
17 main {
18 display: flex;
19 width: 1000px;
20 height: 1000px;
21 flex-flow: row wrap;
22 }
23 </style>
24</head>
25<body>
26 <main>
27 <div class=anim></div>
28 </main>
29 <script type="text/javascript" charset="utf-8">
30 (function () {
31 const TILE_COUNT = 5; // Number of tiles in x or y direction.
32 const TARGET_SIZE = 1000; // Image size in pixels both x and y direction.
33 const PATH = '/lottie.json';
34
Kevin Lubick82999c02018-08-28 10:52:18 -040035 let renderer = 'svg';
36 let hash = window.location.hash;
37 if (hash) {
38 renderer = hash.slice(1);
39 }
40
Joe Gregorio0060c332018-03-19 14:26:58 -040041 // This global is used by puppeteer to determine if all tiles have finished drawing.
42 window._tileCount = 0;
43
44 // First load the animation for just a single tile
45 // so we can read out some values and calculate what
46 // the filmstrip should look like.
47 let anim = lottie.loadAnimation({
48 container: document.querySelector('.anim'),
Kevin Lubick82999c02018-08-28 10:52:18 -040049 renderer: renderer,
Joe Gregorio0060c332018-03-19 14:26:58 -040050 loop: false,
51 autoplay: true,
52 path: PATH,
53 rendererSettings: {
54 preserveAspectRatio:'xMidYMid meet'
55 },
56 });
57
Joe Gregorio7e865472018-03-20 16:03:13 -040058 anim.addEventListener('data_ready', (e) => {
Joe Gregorio0060c332018-03-19 14:26:58 -040059 // Once the first tile is loaded, calculate what
60 // the filmstrip should look like.
Kevin Lubick82999c02018-08-28 10:52:18 -040061 let animationData = anim.animationData;
Kevin Lubick085e8ea2018-08-29 13:52:10 -040062 let totalFrames = anim.totalFrames;
Kevin Lubickc5fe15d2018-08-29 09:52:52 -040063 // t_rate mimics DMSrcSink.cpp::SkottieSrc::draw
64 let t_rate = 1.0 / (TILE_COUNT * TILE_COUNT - 1);
Joe Gregorio0060c332018-03-19 14:26:58 -040065
66 let main = document.querySelector('main');
67
Joe Gregorio0060c332018-03-19 14:26:58 -040068 // Clear out the first div now that our measurements are done.
69 main.firstElementChild.remove();
70
Joe Gregorio7e865472018-03-20 16:03:13 -040071 // Add in all the tiles.
72 for (let i = 0; i < TILE_COUNT*TILE_COUNT; i++) {
Joe Gregorio0060c332018-03-19 14:26:58 -040073 let div = document.createElement('div');
74 div.classList.add('anim');
Kevin Lubickc5fe15d2018-08-29 09:52:52 -040075 div.style.width = (TARGET_SIZE / TILE_COUNT) + 'px';
76 div.style.height = (TARGET_SIZE / TILE_COUNT) + 'px';
Joe Gregorio0060c332018-03-19 14:26:58 -040077 main.appendChild(div);
78
Kevin Lubick82999c02018-08-28 10:52:18 -040079 // create a new animation for each tile. It is tempting to try having
80 // one animation and "clone" each frame, but that doesn't work
81 // because of how bodymovin cleans up the URLObjects that are the path
82 // data for the svgs.
83 // We can re-use the animationData to avoid having to hit the
84 // (local) network a bunch of times.
Joe Gregorio0060c332018-03-19 14:26:58 -040085 let anim = lottie.loadAnimation({
86 container: div,
87 renderer: renderer,
88 loop: false,
Joe Gregorio7e865472018-03-20 16:03:13 -040089 autoplay: false,
Kevin Lubick82999c02018-08-28 10:52:18 -040090 animationData: animationData,
Joe Gregorio0060c332018-03-19 14:26:58 -040091 rendererSettings: {
92 preserveAspectRatio:'xMidYMid meet'
93 },
94 });
Joe Gregorio7e865472018-03-20 16:03:13 -040095
Kevin Lubickc5fe15d2018-08-29 09:52:52 -040096 let t = Math.max(Math.min(t_rate * i, 1.0), 0.0);
Kevin Lubick085e8ea2018-08-29 13:52:10 -040097 let seekToFrame = totalFrames * t;
98 if (seekToFrame >= totalFrames) {
Kevin Lubickc5fe15d2018-08-29 09:52:52 -040099 // bodymovin player sometimes draws blank when requesting
100 // to draw the very last frame. Subtracting a small value
101 // seems to fix this and make it draw the last frame.
Kevin Lubick085e8ea2018-08-29 13:52:10 -0400102 seekToFrame -= .001;
Kevin Lubickc5fe15d2018-08-29 09:52:52 -0400103 }
104
Kevin Lubick82999c02018-08-28 10:52:18 -0400105 // don't need to wait for data_ready because it's instantly ready.
Kevin Lubickc5fe15d2018-08-29 09:52:52 -0400106 console.log(`t = ${t}, go to frame ${seekToFrame}`);
107 anim.goToAndStop(seekToFrame, true);
Kevin Lubick82999c02018-08-28 10:52:18 -0400108 window._tileCount += 1;
Joe Gregorio0060c332018-03-19 14:26:58 -0400109 }
110 });
111 })();
112 </script>
113</body>
114</html>