1cb93a386Sopenharmony_ci<!DOCTYPE html>
2cb93a386Sopenharmony_ci<html>
3cb93a386Sopenharmony_ci<head>
4cb93a386Sopenharmony_ci  <title>Lottie Filmstrip Capture</title>
5cb93a386Sopenharmony_ci  <meta charset="utf-8" />
6cb93a386Sopenharmony_ci  <meta http-equiv="X-UA-Compatible" content="IE=edge">
7cb93a386Sopenharmony_ci  <meta name="viewport" content="width=device-width, initial-scale=1.0">
8cb93a386Sopenharmony_ci  <script src="/lottie.js" type="text/javascript" charset="utf-8"></script>
9cb93a386Sopenharmony_ci  <style type="text/css" media="screen">
10cb93a386Sopenharmony_ci    body,
11cb93a386Sopenharmony_ci    main,
12cb93a386Sopenharmony_ci    .anim {
13cb93a386Sopenharmony_ci      margin: 0;
14cb93a386Sopenharmony_ci      padding: 0;
15cb93a386Sopenharmony_ci    }
16cb93a386Sopenharmony_ci
17cb93a386Sopenharmony_ci    main {
18cb93a386Sopenharmony_ci      display: flex;
19cb93a386Sopenharmony_ci      width: 1000px;
20cb93a386Sopenharmony_ci      height: 1000px;
21cb93a386Sopenharmony_ci      flex-flow: row wrap;
22cb93a386Sopenharmony_ci    }
23cb93a386Sopenharmony_ci  </style>
24cb93a386Sopenharmony_ci</head>
25cb93a386Sopenharmony_ci<body>
26cb93a386Sopenharmony_ci  <main>
27cb93a386Sopenharmony_ci    <div class=anim></div>
28cb93a386Sopenharmony_ci  </main>
29cb93a386Sopenharmony_ci  <script type="text/javascript" charset="utf-8">
30cb93a386Sopenharmony_ci    (function () {
31cb93a386Sopenharmony_ci      const TILE_COUNT = 5; // Number of tiles in x or y direction.
32cb93a386Sopenharmony_ci      const TARGET_SIZE = 1000; // Image size in pixels both x and y direction.
33cb93a386Sopenharmony_ci      const PATH = '/lottie.json';
34cb93a386Sopenharmony_ci
35cb93a386Sopenharmony_ci      let renderer = 'svg';
36cb93a386Sopenharmony_ci      let hash = window.location.hash;
37cb93a386Sopenharmony_ci      if (hash) {
38cb93a386Sopenharmony_ci        renderer = hash.slice(1);
39cb93a386Sopenharmony_ci      }
40cb93a386Sopenharmony_ci
41cb93a386Sopenharmony_ci      // This global is used by puppeteer to determine if all tiles have finished drawing.
42cb93a386Sopenharmony_ci      window._tileCount = 0;
43cb93a386Sopenharmony_ci
44cb93a386Sopenharmony_ci      // First load the animation for just a single tile
45cb93a386Sopenharmony_ci      // so we can read out some values and calculate what
46cb93a386Sopenharmony_ci      // the filmstrip should look like.
47cb93a386Sopenharmony_ci      let anim = lottie.loadAnimation({
48cb93a386Sopenharmony_ci        container: document.querySelector('.anim'),
49cb93a386Sopenharmony_ci        renderer: renderer,
50cb93a386Sopenharmony_ci        loop: false,
51cb93a386Sopenharmony_ci        autoplay: true,
52cb93a386Sopenharmony_ci        path: PATH,
53cb93a386Sopenharmony_ci        rendererSettings: {
54cb93a386Sopenharmony_ci          preserveAspectRatio:'xMidYMid meet'
55cb93a386Sopenharmony_ci        },
56cb93a386Sopenharmony_ci      });
57cb93a386Sopenharmony_ci
58cb93a386Sopenharmony_ci      anim.addEventListener('data_ready', (e) => {
59cb93a386Sopenharmony_ci        // Once the first tile is loaded, calculate what
60cb93a386Sopenharmony_ci        // the filmstrip should look like.
61cb93a386Sopenharmony_ci        let animationData = anim.animationData;
62cb93a386Sopenharmony_ci        let totalFrames = anim.totalFrames;
63cb93a386Sopenharmony_ci        // t_rate mimics DMSrcSink.cpp::SkottieSrc::draw
64cb93a386Sopenharmony_ci        let t_rate = 1.0 / (TILE_COUNT * TILE_COUNT - 1);
65cb93a386Sopenharmony_ci
66cb93a386Sopenharmony_ci        let main = document.querySelector('main');
67cb93a386Sopenharmony_ci
68cb93a386Sopenharmony_ci        // Clear out the first div now that our measurements are done.
69cb93a386Sopenharmony_ci        main.firstElementChild.remove();
70cb93a386Sopenharmony_ci
71cb93a386Sopenharmony_ci        // Add in all the tiles.
72cb93a386Sopenharmony_ci        for (let i = 0; i < TILE_COUNT*TILE_COUNT; i++) {
73cb93a386Sopenharmony_ci          let div = document.createElement('div');
74cb93a386Sopenharmony_ci          div.classList.add('anim');
75cb93a386Sopenharmony_ci          div.style.width = (TARGET_SIZE / TILE_COUNT) + 'px';
76cb93a386Sopenharmony_ci          div.style.height = (TARGET_SIZE / TILE_COUNT) + 'px';
77cb93a386Sopenharmony_ci          main.appendChild(div);
78cb93a386Sopenharmony_ci
79cb93a386Sopenharmony_ci          // create a new animation for each tile. It is tempting to try having
80cb93a386Sopenharmony_ci          // one animation and "clone" each frame, but that doesn't work
81cb93a386Sopenharmony_ci          // because of how bodymovin cleans up the URLObjects that are the path
82cb93a386Sopenharmony_ci          // data for the svgs.
83cb93a386Sopenharmony_ci          // We can re-use the animationData to avoid having to hit the
84cb93a386Sopenharmony_ci          // (local) network a bunch of times.
85cb93a386Sopenharmony_ci          let anim = lottie.loadAnimation({
86cb93a386Sopenharmony_ci            container: div,
87cb93a386Sopenharmony_ci            renderer: renderer,
88cb93a386Sopenharmony_ci            loop: false,
89cb93a386Sopenharmony_ci            autoplay: false,
90cb93a386Sopenharmony_ci            animationData: animationData,
91cb93a386Sopenharmony_ci            rendererSettings: {
92cb93a386Sopenharmony_ci              preserveAspectRatio:'xMidYMid meet'
93cb93a386Sopenharmony_ci            },
94cb93a386Sopenharmony_ci          });
95cb93a386Sopenharmony_ci
96cb93a386Sopenharmony_ci          let t = Math.max(Math.min(t_rate * i, 1.0), 0.0);
97cb93a386Sopenharmony_ci          let seekToFrame = totalFrames * t;
98cb93a386Sopenharmony_ci          if (seekToFrame >= totalFrames) {
99cb93a386Sopenharmony_ci            // bodymovin player sometimes draws blank when requesting
100cb93a386Sopenharmony_ci            // to draw the very last frame.  Subtracting a small value
101cb93a386Sopenharmony_ci            // seems to fix this and make it draw the last frame.
102cb93a386Sopenharmony_ci            seekToFrame -= .001;
103cb93a386Sopenharmony_ci          }
104cb93a386Sopenharmony_ci
105cb93a386Sopenharmony_ci          // don't need to wait for data_ready because it's instantly ready.
106cb93a386Sopenharmony_ci          console.log(`t = ${t}, go to frame ${seekToFrame}`);
107cb93a386Sopenharmony_ci          anim.goToAndStop(seekToFrame, true);
108cb93a386Sopenharmony_ci          window._tileCount += 1;
109cb93a386Sopenharmony_ci        }
110cb93a386Sopenharmony_ci      });
111cb93a386Sopenharmony_ci    })();
112cb93a386Sopenharmony_ci  </script>
113cb93a386Sopenharmony_ci</body>
114cb93a386Sopenharmony_ci</html>
115