title: loading lottie-web animation issue vuejs
body: <p>so I am trying to mimic this code pen <a href="https://codepen.io/airnan/pen/ZLVJmq" rel="nofollow noreferrer">https://codepen.io/airnan/pen/ZLVJmq</a> but when I try to load the same animation in with lottie-web npm package everything works great until the last animation. Then it all gets messed up. I'm trying to figure it out but I am so confused. Any ideas as to why? The JSON file is exactly the same except for text_data variable. I just import the whole thing and access it directly. Heres the code. it's just the last frame that doesn't work. it doesn't animate the text at all instead it looks like this.
  <a href="https://i.stack.imgur.com/eMC6A.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/eMC6A.jpg" alt="image"></a> </p>
  
  <pre><code>&lt;template&gt;
    &lt;div&gt;
      &lt;button @click="render"&gt;Render&lt;/button&gt;
      &lt;h2&gt;Backgrounds&lt;/h2&gt;
      &lt;template v-for="background in backgrounds"&gt;
        &lt;img
          :src="background.poster"
          class="backgrounds"
          @click="changeBackground(background.video)"
        /&gt;
      &lt;/template&gt;
      &lt;h2&gt;Images&lt;/h2&gt;
      &lt;template v-for="image in images"&gt;
        &lt;img
          :src="image.source"
          @click="addImage(image.source, image.type || null)"
          class="images"
        /&gt;
      &lt;/template&gt;
      &lt;br /&gt;
      &lt;button @click="addText"&gt;Add Text&lt;/button&gt;
      &lt;button v-if="selectedNode" @click="removeNode"&gt;
        Remove selected {{ selectedNode.type }}
      &lt;/button&gt;
      &lt;label&gt;Font:&lt;/label&gt;
      &lt;select v-model="selectedFont"&gt;
        &lt;option value="Arial"&gt;Arial&lt;/option&gt;
        &lt;option value="Courier New"&gt;Courier New&lt;/option&gt;
        &lt;option value="Times New Roman"&gt;Times New Roman&lt;/option&gt;
        &lt;option value="Desoto"&gt;Desoto&lt;/option&gt;
        &lt;option value="Kalam"&gt;Kalam&lt;/option&gt;
      &lt;/select&gt;
      &lt;label&gt;Font Size&lt;/label&gt;
      &lt;input type="number" v-model="selectedFontSize" /&gt;
      &lt;label&gt;Font Style:&lt;/label&gt;
      &lt;select v-model="selectedFontStyle"&gt;
        &lt;option value="normal"&gt;Normal&lt;/option&gt;
        &lt;option value="bold"&gt;Bold&lt;/option&gt;
        &lt;option value="italic"&gt;Italic&lt;/option&gt;
      &lt;/select&gt;
      &lt;label&gt;Color:&lt;/label&gt;
      &lt;input type="color" v-model="selectedColor" /&gt;
      &lt;button
        v-if="selectedNode &amp;&amp; selectedNode.type === 'text'"
        @click="updateText"
      &gt;
        Update Text
      &lt;/button&gt;
      &lt;template v-if="selectedNode &amp;&amp; selectedNode.lottie"&gt;
      &lt;input type="text" v-model="text"&gt;
      &lt;button @click="updateAnim(selectedNode.lottie.imgSrc, 'anim')"&gt;
        Update Animation
      &lt;/button&gt;
      &lt;/template&gt;
      &lt;br /&gt;
      &lt;video
        id="preview"
        v-show="preview"
        :src="preview"
        :width="width"
        :height="height"
        preload="auto"
        controls
      /&gt;
      &lt;a v-if="file" :href="file" download="dopeness.mp4"&gt;download&lt;/a&gt;
      &lt;div id="container"&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/template&gt;
  &lt;script&gt;
  import lottie from "lottie-web";
  import * as animationData from "../data.json";
  animationData.layers[0].t.d.k[0].s.t = "text";
  animationData.layers[1].t.d.k[0].s.t = "text";
  animationData.layers[2].t.d.k[0].s.t = "text";
  animationData.layers[3].t.d.k[0].s.t = "text";
  animationData.layers[4].t.d.k[0].s.t = "text";
  export default {
    data() {
      return {
        source: null,
        stage: null,
        layer: null,
        video: null,
        animations: [],
        text: "",
        animationData: animationData.default,
        captures: [],
        backgrounds: [
          {
            poster: "/api/files/stock/3oref310k1uud86w/poster/poster.jpg",
            video:
              "/api/files/stock/3oref310k1uud86w/main/1080/3oref310k1uud86w_1080.mp4"
          },
          {
            poster: "/api/files/stock/3yj2e30tk5x6x0ww/poster/poster.jpg",
            video:
              "/api/files/stock/3yj2e30tk5x6x0ww/main/1080/3yj2e30tk5x6x0ww_1080.mp4"
          },
          {
            poster: "/api/files/stock/2ez931ik1mggd6j/poster/poster.jpg",
            video:
              "/api/files/stock/2ez931ik1mggd6j/main/1080/2ez931ik1mggd6j_1080.mp4"
          },
          {
            poster: "/api/files/stock/yxrt4ej4jvimyk15/poster/poster.jpg",
            video:
              "/api/files/stock/yxrt4ej4jvimyk15/main/1080/yxrt4ej4jvimyk15_1080.mp4"
          },
          {
            poster:
              "https://images.costco-static.com/ImageDelivery/imageService?profileId=12026540&amp;itemId=100424771-847&amp;recipeName=680",
            video: "/api/files/jedi/surfing.mp4"
          },
          {
            poster:
              "https://thedefensepost.com/wp-content/uploads/2018/04/us-soldiers-afghanistan-4308413-1170x610.jpg",
            video: "/api/files/jedi/soldiers.mp4"
          }
        ],
        images: [
          { source: "/api/files/jedi/solo.jpg" },
          { source: "api/files/jedi/yoda.jpg" },
          { source: "api/files/jedi/yodaChristmas.jpg" },
          { source: "api/files/jedi/darthMaul.jpg" },
          { source: "api/files/jedi/darthMaul1.jpg" },
          { source: "api/files/jedi/trump.jpg" },
          { source: "api/files/jedi/hat.png" },
          { source: "api/files/jedi/trump.png" },
          { source: "api/files/jedi/bernie.png" },
          { source: "api/files/jedi/skywalker.png" },
          { source: "api/files/jedi/vader.gif" },
          { source: "api/files/jedi/vader2.gif" },
          { source: "api/files/jedi/yoda.gif" },
          { source: "api/files/jedi/kylo.gif" },
          {
            source: "https://media3.giphy.com/media/R3IxJW14a3QNa/source.gif",
            type: "anim"
          }
        ],
        backgroundVideo: null,
        imageGroups: [],
        anim: null,
        selectedNode: null,
        selectedFont: "Arial",
        selectedColor: "black",
        selectedFontSize: 20,
        selectedFontStyle: "normal",
        width: 1920,
        height: 1080,
        texts: [],
        preview: null,
        file: null,
        canvas: null
      };
    },
    mounted: function() {
      this.initCanvas();
    },
    methods: {
      changeBackground(source) {
        this.source = source;
        this.video.src = this.source;
        this.anim.stop();
        this.anim.start();
        this.video.play();
      },
      removeNode() {
        if (this.selectedNode &amp;&amp; this.selectedNode.type === "text") {
          this.selectedNode.transformer.destroy(
            this.selectedNode.text.transformer
          );
          this.selectedNode.text.destroy(this.selectedNode.text);
          this.texts.splice(this.selectedNode.text.index - 1, 1);
          this.selectedNode = null;
          this.layer.draw();
        } else if (this.selectedNode &amp;&amp; this.selectedNode.type == "image") {
          this.selectedNode.group.destroy(this.selectedNode);
          this.imageGroups.splice(this.selectedNode.group.index - 1, 1);
          if (this.selectedNode.lottie) {
            clearTimeout(this.animations.interval);
            this.selectedNode.lottie.destroy();
            this.animations.splice(this.selectedNode.lottie.index - 1, 1);
          }
          this.selectedNode = null;
          this.layer.draw();
        }
      },
      async addImage(src, anim, isUpdate) {
        let lottieAnimation = null;
        let imageObj = null;
        const type = anim || src.slice(src.lastIndexOf("."));
        const vm = this;
        function process(img) {
          return new Promise((resolve, reject) =&gt; {
            img.onload = () =&gt; resolve({ width: img.width, height: img.height });
          });
        }
        imageObj = new Image();
        imageObj.src = src;
        imageObj.width = 200;
        imageObj.height = 200;
        await process(imageObj);
  
        if (type === ".gif") {
          const canvas = document.createElement("canvas");
          canvas.setAttribute("id", "gif");
          async function onDrawFrame(ctx, frame) {
            ctx.drawImage(frame.buffer, frame.x, frame.y);
            // redraw the layer
            vm.layer.draw();
          }
          gifler(src).frames(canvas, onDrawFrame);
  
          canvas.onload = async () =&gt; {
            canvas.parentNode.removeChild(canvas);
          };
          imageObj = canvas;
          const gif = new Image();
          gif.src = src;
          const gifImage = await process(gif);
          imageObj.width = gifImage.width;
          imageObj.height = gifImage.height;
        } else if (type === "anim") {
          if(!isUpdate){this.text = "new text";}
          const canvas = document.createElement("canvas");
          canvas.style.height = 200;
          canvas.style.width = 200;
          canvas.setAttribute("id", "animationCanvas");
          const ctx = canvas.getContext("2d");
          const div = document.createElement("div");
          div.setAttribute("id", "animationContainer");
          div.style.display = "none";
          canvas.style.display = "none";
          this.animationData.layers[0].t.d.k[0].s.t = this.text;
          this.animationData.layers[1].t.d.k[0].s.t = this.text;
          this.animationData.layers[2].t.d.k[0].s.t = this.text;
          this.animationData.layers[3].t.d.k[0].s.t = this.text;
          this.animationData.layers[4].t.d.k[0].s.t = this.text;
           lottieAnimation = lottie.loadAnimation({
            container: div, // the dom element that will contain the animation
            renderer: "svg",
            loop: true,
            autoplay: true,
            animationData: this.animationData
          });
          lottieAnimation.imgSrc = src;
          lottieAnimation.text = this.text;
          const timer = setInterval(async () =&gt; {
            const svg = await div.getElementsByTagName("svg")[0];
  
            const xml = new XMLSerializer().serializeToString(svg);
            const svg64 = window.btoa(xml);
            const b64Start = "data:image/svg+xml;base64,";
            const image64 = b64Start + svg64;
            imageObj = new Image({ width: 200, height: 200 });
            imageObj.src = image64;
            await process(imageObj);
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.drawImage(imageObj, 0, 0, canvas.width, canvas.height);
            this.layer.draw();
          }, 1000 / 30);
  
          this.animations.push({ lottie: lottieAnimation, interval: timer });
          imageObj = canvas;
          canvas.onload = async () =&gt; {
            canvas.parentNode.removeChild(canvas);
          };
        }
        const image = new Konva.Image({
          x: 50,
          y: 50,
          image: imageObj,
          width: imageObj.width,
          height: imageObj.height,
          position: (0, 0),
          strokeWidth: 10,
          stroke: "blue",
          strokeEnabled: false
        });
  
        const group = new Konva.Group({
          draggable: true
        });
        // add the shape to the layer
        addAnchor(group, 0, 0, "topLeft");
        addAnchor(group, imageObj.width, 0, "topRight");
        addAnchor(group, imageObj.width, imageObj.height, "bottomRight");
        addAnchor(group, 0, imageObj.height, "bottomLeft");
        imageObj = null;
        image.on("click", function () {
          vm.hideAllHelpers();
          vm.selectedNode = {
            type: "image",
            group,
            lottie: lottieAnimation
          };
          if(lottieAnimation &amp;&amp; lottieAnimation.text){vm.text = lottieAnimation.text}
          group.find("Circle").show();
  
          vm.layer.draw();
        });
        image.on("mouseover", function(evt) {
          if (vm.selectedNode &amp;&amp; vm.selectedNode.type === "image") {
            const index = image.getParent().index;
            const groupId = vm.selectedNode.group.index;
            if (index != groupId) {
              evt.target.strokeEnabled(true);
              vm.layer.draw();
            }
          } else {
            evt.target.strokeEnabled(true);
            vm.layer.draw();
          }
        });
        image.on("mouseout", function(evt) {
          evt.target.strokeEnabled(false);
          vm.layer.draw();
        });
        vm.hideAllHelpers();
        group.find("Circle").show();
        group.add(image);
        vm.layer.add(group);
        vm.imageGroups.push(group);
  
        vm.selectedNode = {
          type: "image",
          group,
          lottie: lottieAnimation
        };
  
        vm.layer.draw();
  
        function update(activeAnchor) {
          const group = activeAnchor.getParent();
  
          let topLeft = group.get(".topLeft")[0];
          let topRight = group.get(".topRight")[0];
          let bottomRight = group.get(".bottomRight")[0];
          let bottomLeft = group.get(".bottomLeft")[0];
          let image = group.get("Image")[0];
  
          let anchorX = activeAnchor.getX();
          let anchorY = activeAnchor.getY();
  
          // update anchor positions
          switch (activeAnchor.getName()) {
            case "topLeft":
              topRight.y(anchorY);
              bottomLeft.x(anchorX);
              break;
            case "topRight":
              topLeft.y(anchorY);
              bottomRight.x(anchorX);
              break;
            case "bottomRight":
              bottomLeft.y(anchorY);
              topRight.x(anchorX);
              break;
            case "bottomLeft":
              bottomRight.y(anchorY);
              topLeft.x(anchorX);
              break;
          }
  
          image.position(topLeft.position());
  
          let width = topRight.getX() - topLeft.getX();
          let height = bottomLeft.getY() - topLeft.getY();
          if (width &amp;&amp; height) {
            image.width(width);
            image.height(height);
          }
        }
        function addAnchor(group, x, y, name) {
          let stage = vm.stage;
          let layer = vm.layer;
  
          let anchor = new Konva.Circle({
            x: x,
            y: y,
            stroke: "#666",
            fill: "#ddd",
            strokeWidth: 2,
            radius: 8,
            name: name,
            draggable: true,
            dragOnTop: false
          });
  
          anchor.on("dragmove", function() {
            update(this);
            layer.draw();
          });
          anchor.on("mousedown touchstart", function() {
            group.draggable(false);
            this.moveToTop();
          });
          anchor.on("dragend", function() {
            group.draggable(true);
            layer.draw();
          });
          // add hover styling
          anchor.on("mouseover", function() {
            let layer = this.getLayer();
            document.body.style.cursor = "pointer";
            this.strokeWidth(4);
            layer.draw();
          });
          anchor.on("mouseout", function() {
            let layer = this.getLayer();
            document.body.style.cursor = "default";
            this.strokeWidth(2);
            layer.draw();
          });
  
          group.add(anchor);
        }
      },
      async updateAnim(src, type){
       this.addImage(src, type, true);
        this.removeNode();
  
      },
      hideAllHelpers() {
        for (let i = 0; i &lt; this.texts.length; i++) {
          this.texts[i].transformer.hide();
        }
        for (let b = 0; b &lt; this.imageGroups.length; b++) {
          this.imageGroups[b].find("Circle").hide();
        }
      },
      async startRecording(duration) {
        const chunks = []; // here we will store our recorded media chunks (Blobs)
        const stream = this.canvas.captureStream(30); // grab our canvas MediaStream
        const rec = new MediaRecorder(stream, {
          videoBitsPerSecond: 20000 * 1000
        });
        // every time the recorder has new data, we will store it in our array
        rec.ondataavailable = e =&gt; chunks.push(e.data);
        // only when the recorder stops, we construct a complete Blob from all the chunks
        rec.onstop = async e =&gt; {
          this.anim.stop();
  
          const blob = new Blob(chunks, {
            type: "video/webm"
          });
  
          this.preview = await URL.createObjectURL(blob);
          const video = window.document.getElementById("preview");
          const previewVideo = new Konva.Image({
            image: video,
            draggable: false,
            width: this.width,
            height: this.height
          });
          this.layer.add(previewVideo);
  
          console.log("video", video);
          video.addEventListener("ended", () =&gt; {
            console.log("preview ended");
            if (!this.file) {
              const vid = new Whammy.fromImageArray(this.captures, 30);
              this.file = URL.createObjectURL(vid);
            }
            previewVideo.destroy();
            this.anim.stop();
            this.anim.start();
            this.video.play();
          });
          let seekResolve;
  
          video.addEventListener("seeked", async () =&gt; {
            if (seekResolve) seekResolve();
          });
          video.addEventListener("loadeddata", async () =&gt; {
            let interval = 1 / 30;
            let currentTime = 0;
            while (currentTime &lt;= duration &amp;&amp; !this.file) {
              video.currentTime = currentTime;
              await new Promise(r =&gt; (seekResolve = r));
  
              this.layer.draw();
              let base64ImageData = this.canvas.toDataURL("image/webp");
              this.captures.push(base64ImageData);
              currentTime += interval;
              video.currentTime = currentTime;
            }
  
            this.layer.draw();
          });
        };
        rec.start();
        setTimeout(() =&gt; rec.stop(), duration);
      },
      async render() {
        this.captures = [];
        this.preview = null;
        this.file = null;
        console.log(this.captures.length);
        this.hideAllHelpers();
        this.selectedNode = null;
        this.video.currentTime = 0;
        this.video.loop = false;
        const duration = this.video.duration * 1000;
        this.startRecording(duration);
        this.layer.draw();
      },
      updateText() {
        if (this.selectedNode &amp;&amp; this.selectedNode.type === "text") {
          const text = this.selectedNode.text;
          const transformer = this.selectedNode.transformer;
          text.fontSize(this.selectedFontSize);
          text.fontFamily(this.selectedFont);
          text.fontStyle(this.selectedFontStyle);
          text.fill(this.selectedColor);
          this.layer.draw();
        }
      },
      addText() {
        const vm = this;
        const text = new Konva.Text({
          text: "new text " + (vm.texts.length + 1),
          x: 50,
          y: 80,
          fontSize: this.selectedFontSize,
          fontFamily: this.selectedFont,
          fontStyle: this.selectedFontStyle,
          fill: this.selectedColor,
          align: "center",
          width: this.width * 0.5,
          draggable: true
        });
        const transformer = new Konva.Transformer({
          node: text,
          keepRatio: true,
          enabledAnchors: ["top-left", "top-right", "bottom-left", "bottom-right"]
        });
        text.on("click", async () =&gt; {
          for (let i = 0; i &lt; this.texts.length; i++) {
            let item = this.texts[i];
            if (item.index === text.index) {
              let transformer = item.transformer;
              this.selectedNode = { type: "text", text, transformer };
              this.selectedFontSize = text.fontSize();
              this.selectedFont = text.fontFamily();
              this.selectedFontStyle = text.fontStyle();
              this.selectedColor = text.fill();
              vm.hideAllHelpers();
              transformer.show();
              transformer.moveToTop();
              text.moveToTop();
              vm.layer.draw();
              break;
            }
          }
        });
        text.on("mouseover", () =&gt; {
          transformer.show();
          this.layer.draw();
        });
        text.on("mouseout", () =&gt; {
          if (
            (this.selectedNode &amp;&amp;
              this.selectedNode.text &amp;&amp;
              this.selectedNode.text.index != text.index) ||
            (this.selectedNode &amp;&amp; this.selectedNode.type === "image") ||
            !this.selectedNode
          ) {
            transformer.hide();
            this.layer.draw();
          }
        });
        text.on("dblclick", () =&gt; {
          text.hide();
          transformer.hide();
          vm.layer.draw();
          let textPosition = text.absolutePosition();
  
          let stageBox = vm.stage.container().getBoundingClientRect();
  
          let areaPosition = {
            x: stageBox.left + textPosition.x,
            y: stageBox.top + textPosition.y
          };
  
          let textarea = document.createElement("textarea");
          window.document.body.appendChild(textarea);
          textarea.value = text.text();
          textarea.style.position = "absolute";
          textarea.style.top = areaPosition.y + "px";
          textarea.style.left = areaPosition.x + "px";
          textarea.style.width = text.width() - text.padding() * 2 + "px";
          textarea.style.height = text.height() - text.padding() * 2 + 5 + "px";
          textarea.style.fontSize = text.fontSize() + "px";
          textarea.style.border = "none";
          textarea.style.padding = "0px";
          textarea.style.margin = "0px";
          textarea.style.overflow = "hidden";
          textarea.style.background = "none";
          textarea.style.outline = "none";
          textarea.style.resize = "none";
          textarea.style.lineHeight = text.lineHeight();
          textarea.style.fontFamily = text.fontFamily();
          textarea.style.transformOrigin = "left top";
          textarea.style.textAlign = text.align();
          textarea.style.color = text.fill();
          let rotation = text.rotation();
          let transform = "";
          if (rotation) {
            transform += "rotateZ(" + rotation + "deg)";
          }
          let px = 0;
          let isFirefox =
            navigator.userAgent.toLowerCase().indexOf("firefox") &gt; -1;
          if (isFirefox) {
            px += 2 + Math.round(text.fontSize() / 20);
          }
          transform += "translateY(-" + px + "px)";
          textarea.style.transform = transform;
          textarea.style.height = "auto";
          textarea.focus();
  
          // start
          function removeTextarea() {
            textarea.parentNode.removeChild(textarea);
            window.removeEventListener("click", handleOutsideClick);
            text.show();
            transformer.show();
            transformer.forceUpdate();
            vm.layer.draw();
          }
  
          function setTextareaWidth(newWidth) {
            if (!newWidth) {
              // set width for placeholder
              newWidth = text.placeholder.length * text.fontSize();
            }
            // some extra fixes on different browsers
            let isSafari = /^((?!chrome|android).)*safari/i.test(
              navigator.userAgent
            );
            let isFirefox =
              navigator.userAgent.toLowerCase().indexOf("firefox") &gt; -1;
            if (isSafari || isFirefox) {
              newWidth = Math.ceil(newWidth);
            }
  
            let isEdge =
              document.documentMode || /Edge/.test(navigator.userAgent);
            if (isEdge) {
              newWidth += 1;
            }
            textarea.style.width = newWidth + "px";
          }
  
          textarea.addEventListener("keydown", function(e) {
            // hide on enter
            // but don't hide on shift + enter
            if (e.keyCode === 13 &amp;&amp; !e.shiftKey) {
              text.text(textarea.value);
              removeTextarea();
            }
            // on esc do not set value back to node
            if (e.keyCode === 27) {
              removeTextarea();
            }
          });
  
          textarea.addEventListener("keydown", function(e) {
            let scale = text.getAbsoluteScale().x;
            setTextareaWidth(text.width() * scale);
            textarea.style.height = "auto";
            textarea.style.height =
              textarea.scrollHeight + text.fontSize() + "px";
          });
  
          function handleOutsideClick(e) {
            if (e.target !== textarea) {
              text.text(textarea.value);
              removeTextarea();
            }
          }
          setTimeout(() =&gt; {
            window.addEventListener("click", handleOutsideClick);
          });
          // end
        });
        text.transformer = transformer;
        this.texts.push(text);
        this.layer.add(text);
        this.layer.add(transformer);
        this.hideAllHelpers();
        this.selectedNode = { type: "text", text, transformer };
        transformer.show();
        this.layer.draw();
      },
      initCanvas() {
        const vm = this;
        this.stage = new Konva.Stage({
          container: "container",
          width: vm.width,
          height: vm.height
        });
        this.layer = new Konva.Layer();
  
        this.stage.add(this.layer);
  
        let video = document.createElement("video");
        video.setAttribute("id", "video");
        video.setAttribute("ref", "video");
        if (this.source) {
          video.src = this.source;
        }
        video.preload = "auto";
        video.loop = "loop";
        video.style.display = "none";
        this.video = video;
        this.backgroundVideo = new Konva.Image({
          image: vm.video,
          draggable: false
        });
        this.video.addEventListener("loadedmetadata", function(e) {
          vm.backgroundVideo.width(vm.width);
          vm.backgroundVideo.height(vm.height);
        });
        this.video.addEventListener("ended", () =&gt; {
          console.log("the video ended");
          this.anim.stop();
          this.anim.start();
          this.video.loop = "loop";
          this.video.play();
        });
  
        this.anim = new Konva.Animation(function() {
          console.log("animation called");
          // do nothing, animation just need to update the layer
        }, vm.layer);
  
        this.layer.add(this.backgroundVideo);
        this.layer.draw();
        const canvas = document.getElementsByTagName("canvas")[0];
        canvas.style.border = "3px solid red";
        this.canvas = canvas;
      }
    }
  };
  &lt;/script&gt;
  &lt;style scoped&gt;
  body {
    margin: 0;
    padding: 0;
    background-color: #f0f0f0;
  }
  .backgrounds,
  .images {
    width: 100px;
    height: 100px;
    padding-left: 2px;
    padding-right: 2px;
  }
  &lt;/style&gt;
  </code></pre>