driver.html 3.7 KB

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