Search code examples
javascriptjqueryhtmlmathjax

Using JavaScript to animate MathJax equation


I would like to perform a seamless animation which gives the impression of substituting variables into an expression step by step. However there are a few issues that make it rather ugly.

  1. When an element fadesOut the element below moves upward one position. How can I get the element to stay where it is?

  2. Aesthetically it is a bit ugly. If anyone could guide me to resources to make it more elegant that would be great. Also if you have an idea to make it prettier using JS please give it a try!

$('#next').hide();
$('#next2').hide();
$('#next3').hide();
$('#next4').hide();
$('#next5').hide();
$('#next6').hide();
$('#next7').hide();
$('#next8').hide();

$('#next').fadeIn(1000);
$('#start').fadeOut(1000);
$('#next4').fadeIn(3000);
$('#next').fadeOut(1000);
$('#next3').fadeIn(4000);
$('#next5').fadeIn(4000);
$('#next3').fadeOut(1000);
$('#next4').fadeOut(3000);
$('#next6').fadeIn(5000);
$('#next5').fadeOut(3000);
$('#next6').fadeOut(6000);
$('#next7').fadeIn(13000);
$('#next7').fadeOut(1000);
$('#next8').fadeIn(15000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=AM_CHTML"></script>
<div id="equation">
  <h2 id="start">`KE_{rot} = \frac1 2 I \omega^2`</h2>
  <br>
  <h2 id="next">`\omega =sqrt(2\alpha \Delta degrees)`</h2>
  <br>
  <h2 id="next2">`KE_{rot} = \frac1 2 I sqrt(2\alpha \Delta degrees)`</h2>
  <br>
  <h2 id="next3">`\alpha = frac\{tau_{max}} {I}`</h2>
  <br>
  <h2 id="next4">`KE_{rot} = \frac1 2 I \sqrt{(2 (\frac{\tau_{max}} {I})   \Delta degrees)}^2`</h2>
  <br>
  <h2 id="next5">`KE_{rot} = \frac1 2 I \(2 (\frac{\tau_{max}} {I}) \Delta degrees)`</h2>
  <br>
  <h2 id="next6">`KE_{rot} = \tau_{max}\Delta degrees`</h2>
  <br>
  <h2 id="next7">`\tau_{max} = I \alpha`</h2>
  <br>
  <h2 id="next8">`KE_{rot} = I \ \alpha \  \Delta   degrees`</h2>
</div>


Solution

  • I would ditch using <h2> and <br> tags. Have a collection of <div> sets that will serve as slides. Give each one the slide class. Put which equations you want to display on each slide. Do some fancy stuff with Array.prototype.reduce and Promises to transition between slides.

    $(function() {
      // I have no idea why jQuery doesn't have a reduce function
      $.fn.reduce = Array.prototype.reduce;
    
      // Create a chain of promises
      function waterfall(arr, action) {
        arr.reduce(function(prev, next) {
          return prev.then(function() {
            return action(next);
          });
        }, Promise.resolve());
      }
    
      // Function to actual fade an element in/out and return a promise
      function fader(el) {
        return new Promise(function(resolve, reject) {
          $(el).fadeIn(2000).promise().done(function() {
            this.fadeOut(1000).promise().done(function() {
              resolve();
            });
          });
        });
      }
    
      // Bootstrap
      waterfall($(".slide"), fader);
    });
    .math-set {
      text-align: center;
    }
    .slide {
      display: none;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=AM_CHTML"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <div class="math-set">
      <div class="slide">
        <div>`KE_{rot} = \frac1 2 I \omega^2`</div>
      </div>
      <div class="slide">
        <div>`\omega =sqrt(2\alpha \Delta degrees)`</div>
        <div>`KE_{rot} = \frac1 2 I sqrt(2\alpha \Delta degrees)`</div>
      </div>
      <div class="slide">
        <div>`\alpha = frac\{tau_{max}} {I}`</div>
      </div>
      <div class="slide">
        <div>`KE_{rot} = \frac1 2 I \sqrt{(2 (\frac{\tau_{max}} {I}) \Delta degrees)}^2`</div>
        <div>`KE_{rot} = \frac1 2 I \(2 (\frac{\tau_{max}} {I}) \Delta degrees)`</div>
      </div>
      <div class="slide">
        <div>`KE_{rot} = \tau_{max}\Delta degrees`</div>
      </div>
      <div class="slide">
        <div>`\tau_{max} = I \alpha`</div>
        <div>`KE_{rot} = I \ \alpha \ \Delta degrees`</div>
      </div>
    </div>