Search code examples
javascriptanimationsvgpreloadpreloader

lazy line painter as a pre-loader


I have an animated SVG using lazy line painter that I would like to use as a pre-loader. How can I review the page content (with a transition or a simple fade-in) after the line animation is completed?

So the concept is this: on landing LOAD SVG animation when COMPLETE transition into page content.

    <!-- Include lazylinepainter -->
        <script src="https://cdn.jsdelivr.net/npm/ lazy-line-painter@1.9.4/lib/lazy-line-painter-1.9.4.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/d3js/5.15.0/d3.min.js"></script>

        <script type="text/javascript">

          (function(){

            document.onreadystatechange = () => {

              if (document.readyState === 'complete') {


                let el = document.querySelector('#markin2');
                let myAnimation = new LazyLinePainter(el, {"ease":"easeLinear","strokeWidth":2.2,"strokeOpacity":1,"strokeColor":"#fff"});
                myAnimation.paint();
              }
            }

          })();

        </script>

  <svg version="1.1" id="markin2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="314.094px" height="314.765px" viewBox="0 0 314.094 314.765" enable-background="new 0 0 314.094 314.765" xml:space="preserve" data-llp-composed="true" class="lazy-line-painter">
<circle fill="none" stroke-miterlimit="10" cx="157.828" cy="157.404" r="150.813" data-llp-id="markin2-0" data-llp-duration="2920" data-llp-delay="0" fill-opacity="1"  data-llp-stroke-join="" data-llp-stroke-cap=""/>
<path id="#markin2" class=".markin2" fill="none" values="#000" stroke-miterlimit="10" d="M18.482,132.273
    c1.019-4.147,1.774-8.38,3.099-12.427c7.988-24.405,24.611-39.774,49.798-44.317c26.582-4.795,47.878,5.064,64.031,26.525
    c2.094,2.782,2.112,4.714-0.499,7.183c-3.496,3.306-6.592,7.035-10.095,10.837c-2.364-3.506-4.425-7.039-6.94-10.211
    C104.843,93.427,81.91,88.297,62.884,97.426c-18.967,9.102-29.097,30.539-24.289,51.399c4.649,20.172,22.977,34.573,43.973,34.571
    c13.572-0.002,24.751-5.104,33.906-15.18c22.505-24.771,44.815-49.735,67.885-73.971c17.361-18.239,39.164-24.295,63.441-17.369
    c24.221,6.91,39.282,23.516,45.102,48.006c3.184,13.398,1.887,26.967-2.008,39.987c-1.322,4.422-5.715,7.985-8.899,11.78
    c-10.94,13.035-24.349,21.988-41.47,24.67c-19.018,2.979-35.86-2.006-50.829-13.86c-1.162-0.92-2.304-1.863-4.361-3.533
    c0,2.48-0.004,4.178,0,5.873c0.045,22.324,0.009,44.646,0.213,66.967c0.037,3.956-0.771,7.102-3.877,9.674
    c-1.653,1.37-3.243,2.961-4.409,4.748c-2.552,3.912-5.974,4.865-10.668,3.637c0-6.688,0.01-13.473-0.003-20.258
    c-0.041-22.488,0.024-44.979-0.227-67.465c-0.056-4.814,1.073-8.443,4.622-11.914c6.039-5.908,11.509-12.398,17.593-19.056
    c4.06,8.205,9.36,14.85,16.678,19.736c15.507,10.355,35.698,10.172,51.128-0.49c15.202-10.506,22.338-29.406,18.086-47.903
    c-3.979-17.298-19.188-31.573-37.106-33.975c-15.415-2.066-29.11,2.093-39.841,13.781c-21.17,23.057-42.371,46.092-63.192,69.461
    c-14.497,16.271-31.743,25.988-53.992,25.404c-30.517-0.799-56.945-24.744-60.94-55.143c-0.123-0.934-0.602-1.821-0.915-2.73
    C18.482,140.272,18.482,136.272,18.482,132.273z" data-llp-id="markin2-1" data-llp-duration="2920" data-llp-delay="0" fill-opacity="1" data-llp-stroke-join="" data-llp-stroke-cap=""/>
</svg>

CSS

body, html {
            background: #000;
            position: absolute;
            width: 100%;
            height: 100%;
            top:0;
            left:0;
            margin: 0;
            display: flex;
            align-items: center;
            justify-content: center;
          }

            #markin2 {
              width: 40vw;
              height: 40vh;
              position: relative;
              overflow: visible;
            }

            .markin2 {
  animation: stroke_fill 4s linear forwards, changeColor 2s, forwards;
  stroke-dasharray: 1538.2169189453125px;
  stroke-dashoffset: 0;
}
@keyframes stroke_fill {

  0% {
    fill: white;
  }
  50% {
    fill: white;
    stroke-dashoffset: 0;
  }
  100% {
    fill: black;
    stroke-dashoffset: 0;
  }
}
@keyframes changeColor {
        from{ fill: rgba(0,0,0,0);}
        to{ fill: rgba(0,0,0,1)}
      }

Here is the SVG animation example:

https://codepen.io/cpawl/pen/zYvEqYq


Solution

  • The Lazy Line Painter library has some custom events built in to which you can listen. Such as the complete event whenever you animation has been completed. Whenever that event is called, hide the SVG.

    In the example below I've added this event listener but also wrapped your animation in a Promise. This way you can wait for it to finish and then do something. And also another Promise which listens for the load event on the document. So that this is an actual page loader and the SVG would not disappear before the page would be loaded.

    In your HTML first load the SVG and then the JS you see below here. Inside the then callback function either delete your SVG, or set a class to the body which hides the class. Anyway you see fit.

    body,
    html {
      background: #000;
      position: absolute;
      width: 100%;
      height: 100%;
      top: 0;
      left: 0;
      margin: 0;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    #markin2 {
      width: 20vw;
      height: 20vh;
      position: relative;
      overflow: visible;
    }
    
    .markin2 {
      animation: stroke_fill 4s linear forwards, changeColor 2s, forwards;
      stroke-dasharray: 1538.2169189453125px;
      stroke-dashoffset: 0;
    }
    
    @keyframes stroke_fill {
      0% {
        fill: white;
      }
      50% {
        fill: white;
        stroke-dashoffset: 0;
      }
      100% {
        fill: black;
        stroke-dashoffset: 0;
      }
    }
    
    @keyframes changeColor {
      from {
        fill: rgba(0, 0, 0, 0);
      }
      to {
        fill: rgba(0, 0, 0, 1);
      }
    }
    
    .hsvg {
      display: flex;
      align-items: center;
      justify-content: center;
      position: fixed;
      width: 100%;
      height: 100%;
      background: #000000;
      z-index: 999;
      transition: 2000ms ease-in-out;
      transition-property: opacity, visibility;
    }
    
    body.is-loaded .hsvg {
      opacity: 0;
      visibility: hidden;
    }
    
    .main-content {
      color: #fff;
    }
    <script src="https://cdn.jsdelivr.net/npm/lazy-line-painter@1.9.6/lib/lazy-line-painter-1.9.6.min.js"></script>
    
    <!-- Include lazylinepainter -->
    <div class="hsvg">
      <svg version="1.1" id="markin2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="314.094px" height="314.765px" viewBox="0 0 314.094 314.765" enable-background="new 0 0 314.094 314.765" xml:space="preserve"
        data-llp-composed="true" class="lazy-line-painter">
    <circle fill="none" stroke-miterlimit="10" cx="157.828" cy="157.404" r="150.813" data-llp-id="markin2-0" data-llp-duration="2920" data-llp-delay="0" fill-opacity="1"  data-llp-stroke-join="" data-llp-stroke-cap=""/>
    <path id="#markin2" class=".markin2" fill="none" values="#000" stroke-miterlimit="10" d="M18.482,132.273
        c1.019-4.147,1.774-8.38,3.099-12.427c7.988-24.405,24.611-39.774,49.798-44.317c26.582-4.795,47.878,5.064,64.031,26.525
        c2.094,2.782,2.112,4.714-0.499,7.183c-3.496,3.306-6.592,7.035-10.095,10.837c-2.364-3.506-4.425-7.039-6.94-10.211
        C104.843,93.427,81.91,88.297,62.884,97.426c-18.967,9.102-29.097,30.539-24.289,51.399c4.649,20.172,22.977,34.573,43.973,34.571
        c13.572-0.002,24.751-5.104,33.906-15.18c22.505-24.771,44.815-49.735,67.885-73.971c17.361-18.239,39.164-24.295,63.441-17.369
        c24.221,6.91,39.282,23.516,45.102,48.006c3.184,13.398,1.887,26.967-2.008,39.987c-1.322,4.422-5.715,7.985-8.899,11.78
        c-10.94,13.035-24.349,21.988-41.47,24.67c-19.018,2.979-35.86-2.006-50.829-13.86c-1.162-0.92-2.304-1.863-4.361-3.533
        c0,2.48-0.004,4.178,0,5.873c0.045,22.324,0.009,44.646,0.213,66.967c0.037,3.956-0.771,7.102-3.877,9.674
        c-1.653,1.37-3.243,2.961-4.409,4.748c-2.552,3.912-5.974,4.865-10.668,3.637c0-6.688,0.01-13.473-0.003-20.258
        c-0.041-22.488,0.024-44.979-0.227-67.465c-0.056-4.814,1.073-8.443,4.622-11.914c6.039-5.908,11.509-12.398,17.593-19.056
        c4.06,8.205,9.36,14.85,16.678,19.736c15.507,10.355,35.698,10.172,51.128-0.49c15.202-10.506,22.338-29.406,18.086-47.903
        c-3.979-17.298-19.188-31.573-37.106-33.975c-15.415-2.066-29.11,2.093-39.841,13.781c-21.17,23.057-42.371,46.092-63.192,69.461
        c-14.497,16.271-31.743,25.988-53.992,25.404c-30.517-0.799-56.945-24.744-60.94-55.143c-0.123-0.934-0.602-1.821-0.915-2.73
        C18.482,140.272,18.482,136.272,18.482,132.273z" data-llp-id="markin2-1" data-llp-duration="2920" data-llp-delay="0" fill-opacity="1" data-llp-stroke-join="" data-llp-stroke-cap=""/>
    </svg>
    </div>
    
    <script>
      const pageLoad = new Promise(resolve => {
        window.addEventListener('load', resolve);
      });
    
      const animationLoad = new Promise(resolve => {
        let el = document.querySelector('#markin2');
        let myAnimation = new LazyLinePainter(el, {
          "ease": "easeLinear",
          "strokeWidth": 2.2,
          "strokeOpacity": 1,
          "strokeColor": "#fff"
        });
        myAnimation.paint();
        myAnimation.on('complete', resolve);
      });
    
      Promise.all([pageLoad, animationLoad]).then(function() {
        document.body.classList.add('is-loaded');
        console.log('Load event fired and animation done');
      });
    </script>
    
    <div class="main-content">
      <h1>IS THIS THING ON?</h1>
    </div>