Search code examples
mathmlanime.js

Anime.js and MathML


I just discovered anime.js and it feels like the right tool for what I need (animating some web tutorials in 2D). The problem is that I'm using MathML (part of the HTML5 standard), which uses "math" tags.

HTML

<math>
    <mrow>
        <msqrt>
            <mrow>
                <msup class="ml4">
                    <mi class="letter">b</mi>
                    <mn>2</mn>
                </msup>
            </mrow>
        </msqrt>   
    </mrow>
</math>

JS

<script type="text/javascript" src="anime.min.js"></script>
<script>
    anime.timeline({loop: true})
    .add({
        targets: '.ml4 .letter',
        opacity: [0, 1],
        scale: [0.2, 1],
        duration: 800
    });
</script>

When I try to simply animate letters within a math tag (opacity, scale, duration), I get:

If I use anime.min.js (2.0)

In Firefox

"TypeError: right-hand side of 'in' should be an object, got undefined" 
-> anime.min.js:9:136

In Safari

"TypeError: a.style is not an Object. (evaluating 'b in a.style')"
 -> "B" -> anime.min.js:9:145

If I use anime.js (2.0)

In Firefox

"TypeError: right-hand side of 'in' should be an object, got undefined"
-> anime.min.js:346:5

In Safari

"TypeError: a.style is not an Object. (evaluating 'b in a.style')"
-> "getCSSValue" -> anime.min.js:346

In both cases, the math formula appears just fine but the animation isn't working. I tried previous versions of anime.js with the same result.

I toyed with the code and the animation comes back + the error message goes away on Firefox and Safari if I get rid of the "math" tag. But then, of course, the math formula is a mess, which is of no help. But it seems the issue is related to this math tag alone. I also tried to style, unstyle the math tag and the inner tags but the error remains.

I could understand that this tag is unsupported by animate.js but the animation works just fine and without any error within my Coda2 (web dev software) on Mac, on its own dedicated browser. So this seems very browser dependent but so far it's the only browser that seems to consider the script as valid.

I haven't found anything on the web that is addressing both anime.js and the MathML so it's hard to say if it's a bug or an error on my part.

Thank you.

https://jsfiddle.net/bt4u23rh/1/


Solution

  • You can use a wrapper, or you can modify the function getCSSValue on the animejs library. Basically that function looks for the style property for that specific target.

    function getCSSValue(el, prop) {
      if (prop in el.style) {
        return getComputedStyle(el).getPropertyValue(stringToHyphens(prop)) || '0';
      }
    }
    

    When the code reaches the if line, your mi .letter doesn´t have that attribute and the call to the function fails and bubble up.

    Using the proposed workaround, you can create a div that contains your mathML tags:

    <div class="letterWrapper">
    <math>
      <mrow>
        <msqrt>
          <mrow>
            <msup class="ml4">
              <mi class="letter">b</mi>
              <mn>2</mn>
            </msup>
          </mrow>
        </msqrt>   
      </mrow>
    </math>
    </div>
    

    https://jsfiddle.net/bt4u23rh/2/