• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!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
35      let renderer = 'svg';
36      let hash = window.location.hash;
37      if (hash) {
38        renderer = hash.slice(1);
39      }
40
41      // 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'),
49        renderer: renderer,
50        loop: false,
51        autoplay: true,
52        path: PATH,
53        rendererSettings: {
54          preserveAspectRatio:'xMidYMid meet'
55        },
56      });
57
58      anim.addEventListener('data_ready', (e) => {
59        // Once the first tile is loaded, calculate what
60        // the filmstrip should look like.
61        let animationData = anim.animationData;
62        let totalFrames = anim.totalFrames;
63        // t_rate mimics DMSrcSink.cpp::SkottieSrc::draw
64        let t_rate = 1.0 / (TILE_COUNT * TILE_COUNT - 1);
65
66        let main = document.querySelector('main');
67
68        // Clear out the first div now that our measurements are done.
69        main.firstElementChild.remove();
70
71        // Add in all the tiles.
72        for (let i = 0; i < TILE_COUNT*TILE_COUNT; i++) {
73          let div = document.createElement('div');
74          div.classList.add('anim');
75          div.style.width = (TARGET_SIZE / TILE_COUNT) + 'px';
76          div.style.height = (TARGET_SIZE / TILE_COUNT) + 'px';
77          main.appendChild(div);
78
79          // 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.
85          let anim = lottie.loadAnimation({
86            container: div,
87            renderer: renderer,
88            loop: false,
89            autoplay: false,
90            animationData: animationData,
91            rendererSettings: {
92              preserveAspectRatio:'xMidYMid meet'
93            },
94          });
95
96          let t = Math.max(Math.min(t_rate * i, 1.0), 0.0);
97          let seekToFrame = totalFrames * t;
98          if (seekToFrame >= totalFrames) {
99            // 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.
102            seekToFrame -= .001;
103          }
104
105          // don't need to wait for data_ready because it's instantly ready.
106          console.log(`t = ${t}, go to frame ${seekToFrame}`);
107          anim.goToAndStop(seekToFrame, true);
108          window._tileCount += 1;
109        }
110      });
111    })();
112  </script>
113</body>
114</html>
115