2

I tried including the svg file as an img element, which didn't work - anime.js didn't recognize the svg. Then put it in an object element, which also didn't work.

So how do you set up a framework to recognize the svg and the elements within it?

Brian Burns
  • 20,575
  • 8
  • 83
  • 77

2 Answers2

1

You do need to use an object element, but you can't view the html file directly - you need to serve it from a server, e.g. with Python - at a console do

python -m http.server 8001

then view it on http://localhost:8001

Here's an example -

<html>
  <!-- note: must run this from a server for svg to load properly -->
  <!-- eg `python -m http.server 8001` -->
  <!-- see https://stackoverflow.com/questions/11434916/javascript-accessing-inner-dom-of-svg -->
  <head>
    <script src="anime.min.js"></script>
    <style>
      body {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100%;
        background: #222;
      }
      object {
        opacity: 0;
        background: black;
        border: 1px solid #aaa;
      }
    </style>
  </head>
  <body>
    <script>
      function loaded() {

        // get references to svg and subelements

        const svg = document.querySelector("#svg")
        const title = [
          svg.contentDocument.querySelector("#path30"),
          svg.contentDocument.querySelector("#path34"),
        ]
        const subtitle = [
          svg.contentDocument.querySelector("#text54"),
        ]
        const swooshes = [
          svg.contentDocument.querySelector("#path42"),
          svg.contentDocument.querySelector("#path38"),
          svg.contentDocument.querySelector("#path50"),
          svg.contentDocument.querySelector("#path46"),
        ]

        // set some initial values

        svg.style.opacity = 1
        for (const element of title) {
          element.style.opacity = 0
        }
        for (const element of subtitle) {
          element.style.opacity = 0
        }
        for (const element of swooshes) {
          element.style.opacity = 0
        }

        // animate elements

        anime({
          targets: svg,
          delay: 0,
          duration: 2000,
          background: '#ffffff',
          easing: 'linear'
        })

        anime({
          targets: title,
          opacity: 1,
          delay: 0,
          duration: 2000,
          easing: 'linear',
        })

        anime({
          targets: subtitle,
          opacity: 0.9,
          delay: 2000,
          duration: 2000,
          easing: 'linear',
        })

        let startTime = 3000
        for (let i = 0; i < 4; i++) {
          window.setTimeout(() => {
            anime({
              targets: swooshes[i],
              opacity: 1,
              duration: 2000,
              easing: 'linear',
              direction: 'alternate',
              loop: true,
            })
          }, startTime)
          startTime += 500
        }

      }
    </script>

    <!-- must put svg in an object element -->
    <!-- https://stackoverflow.com/questions/28652648/how-to-use-external-svg-in-html -->
    <object data="Emergent_Logo.svg" type="image/svg+xml" id="svg" onload="loaded()"></object>

  </body>
</html>

Brian Burns
  • 20,575
  • 8
  • 83
  • 77
0

animejs requires the raw svg code instead of accessing it via iframe/img tag.

To get the raw code, simply open the .svg file in one of the editors and copy the code from it to directly in your html file.

It should now recognize the code and animate/morph the svg however you want.