How to extract Flot animation?

47 views Asked by At

In this website, there is a nice animation of the motion of a diatomic chain:

http://lampx.tugraz.at/~hadley/ss1/phonons/1d/1d2m.php

How can I extract it? Ideally I woud like to make a gif. I can see the html script:

var c=document.getElementById("theCanvas"); var ctx=c.getContext("2d"); ctx.lineWidth = 2;
ctx.strokeStyle="black"; ctx.fillStyle="black";

var pi = Math.PI; var t = 0; var d1 = []; var d2 = []; var d3 = []; var M1 =1.1; var M2 = 1; var C = 1;

k = pi/2;
document.getElementById('ka').innerHTML=k.toPrecision(3);

dt = 0.2;

function morek(){ k+=pi/32; if (k>pi) {k=pi;} if (Math.abs(k)<pi/50) {k=0;}
document.getElementById('ka').innerHTML=k.toPrecision(3); }

function lessk(){ k-=pi/32; if (k<-pi) {k=-pi;} if (Math.abs(k)<pi/50) {k=0;}
document.getElementById('ka').innerHTML=k.toPrecision(3); }

function moreM(){ M1+=0.1;
document.getElementById('Mtext').innerHTML=M1.toPrecision(2); }

function lessM(){ M1-=0.1; if (M1<1) {M1=1;}
document.getElementById('Mtext').innerHTML=M1.toPrecision(2); }

function step() {

for (i=-300; i<301; i++) { ka = ipi/300; omgac = Math.sqrt(C(M1+M2)/(M1M2)-Math.sqrt(Math.pow((M1+M2)/(M1M2),2)-4Math.pow(Math.sin(ka/2),2)/(M1M2))); omgop = Math.sqrt(C*(M1+M2)/(M1M2)+Math.sqrt(Math.pow((M1+M2)/(M1M2),2)-4Math.pow(Math.sin(ka/2),2)/(M1M2))); d1[i+300]=[ka,omgac/Math.sqrt(2C(M1+M2)/(M1M2))];
d3[i+300]=[ka,omgop/Math.sqrt(2
C*(M1+M2)/(M1*M2))]; }

ctx.clearRect(0, 0, 600, 40);

//draw springs ctx.beginPath(); ctx.moveTo(0,10);
ctx.lineTo(600,10); ctx.stroke();

ctx.beginPath(); ctx.moveTo(0,30); ctx.lineTo(600,30);
ctx.stroke();

omg_ac = Math.sqrt(C*(M1+M2)/(M1M2)-Math.sqrt(Math.pow((M1+M2)/(M1M2),2)-4Math.pow(Math.sin(k/2),2)/(M1M2))); omg_op = Math.sqrt(C*(M1+M2)/(M1M2)+Math.sqrt(Math.pow((M1+M2)/(M1M2),2)-4Math.pow(Math.sin(k/2),2)/(M1M2))); R = 3;

ac_c = C*(1+Math.cos(k))/(2C-omg_acomg_acM2); ac_s = -CMath.sin(k)/(2C-omg_acomg_acM2); op_c = C(1+Math.cos(k))/(2C-omg_opomg_opM1); op_s = CMath.sin(k)/(2C-omg_opomg_op*M1);

R = 3*Math.sqrt(M1);

for (i=0; i<16; i++) { x_ac1 = 218.75i+4Math.cos(omg_act+ik)+9.375; x_ac2 = 218.75*(i+0.5)+ac_c4Math.cos(omg_act+ik)+ac_s4Math.sin(omg_act+ik)+9.375; x_op1 = 218.75i+op_c4Math.cos(omg_opt+ik)+op_s4Math.sin(omg_opt+ik)+9.375; x_op2 = 218.75(i+0.5)+4Math.cos(omg_opt+ik)+9.375; ctx.beginPath(); ctx.arc(x_ac1,30,R,0,2pi); ctx.fill(); ctx.beginPath(); ctx.arc(x_ac2,30,3,0,2pi); ctx.fill(); ctx.beginPath(); ctx.arc(x_op1,10,R,0,2pi); ctx.fill(); ctx.beginPath(); ctx.arc(x_op2,10,3,0,2*pi); ctx.fill(); } t = t + dt;

d2[0] = [k,omg_ac/Math.sqrt(2C(M1+M2)/(M1M2))]; d2[1] = [k,omg_op/Math.sqrt(2C*(M1+M2)/(M1*M2))]; //plot the data var data1 = [{ data: d1, color: "rgb(0, 0, 0)", shadowSize:0, lines: {show:true}},{ data: d3, color: "rgb(0, 0, 0)", shadowSize:0, lines: {show:true}},{ data: d2, color: "rgb(255, 0, 0)", shadowSize:0, points: {show:true}}]; $.plot($("#placeholder1"), data1); requestAnimationFrame(step);

}

requestAnimationFrame(step);

using the browser but how can I use it?

1

There are 1 answers

1
Mark McClure On

First off, if you simply want an animated gif of one mode of the vibration, then the easiest thing to do must be to use screen capture to record a movie and convert that result to an animated gif. Taking this approach, I used my Mac's Screenshot app to capture the animation in MOV format and then Cloud Convert to convert that to GIF. Here's the result:

enter image description here


I've also extracted the code that produces the animation, if you decide that you do want the full animation with controls. Note that the animation has nothing to do with MathJax, which is simply used to typeset the formulae on the page. The animation is generated using Javascript with jQuery and Flot.

var c=document.getElementById("theCanvas");
var ctx=c.getContext("2d");
ctx.lineWidth = 2;
ctx.strokeStyle="black";
ctx.fillStyle="black";

var pi = Math.PI;
var t = 0;
var d1 = [];
var d2 = [];
var d3 = [];
var M1 =1.1;
var M2 = 1;
var C = 1;

k = pi/2;
document.getElementById('ka').innerHTML=k.toPrecision(3);

dt = 0.2;

function morek(){
k+=pi/32;
if (k>pi) {k=pi;}
if (Math.abs(k)<pi/50) {k=0;}
document.getElementById('ka').innerHTML=k.toPrecision(3);
}

function lessk(){
k-=pi/32;
if (k<-pi) {k=-pi;}
if (Math.abs(k)<pi/50) {k=0;}
document.getElementById('ka').innerHTML=k.toPrecision(3);
}

function moreM(){
M1+=0.1;
document.getElementById('Mtext').innerHTML=M1.toPrecision(2);
}

function lessM(){
M1-=0.1;
if (M1<1) {M1=1;}
document.getElementById('Mtext').innerHTML=M1.toPrecision(2);
}

function step() {

for (i=-300; i<301; i++) {
ka = i*pi/300;
omgac = Math.sqrt(C*(M1+M2)/(M1*M2)-Math.sqrt(Math.pow((M1+M2)/(M1*M2),2)-4*Math.pow(Math.sin(ka/2),2)/(M1*M2)));
omgop = Math.sqrt(C*(M1+M2)/(M1*M2)+Math.sqrt(Math.pow((M1+M2)/(M1*M2),2)-4*Math.pow(Math.sin(ka/2),2)/(M1*M2)));
d1[i+300]=[ka,omgac/Math.sqrt(2*C*(M1+M2)/(M1*M2))];
d3[i+300]=[ka,omgop/Math.sqrt(2*C*(M1+M2)/(M1*M2))];
}

ctx.clearRect(0, 0, 600, 40);


//draw springs
ctx.beginPath();
ctx.moveTo(0,10);
ctx.lineTo(600,10);
ctx.stroke();

ctx.beginPath();
ctx.moveTo(0,30);
ctx.lineTo(600,30);
ctx.stroke();

omg_ac = Math.sqrt(C*(M1+M2)/(M1*M2)-Math.sqrt(Math.pow((M1+M2)/(M1*M2),2)-4*Math.pow(Math.sin(k/2),2)/(M1*M2)));
omg_op = Math.sqrt(C*(M1+M2)/(M1*M2)+Math.sqrt(Math.pow((M1+M2)/(M1*M2),2)-4*Math.pow(Math.sin(k/2),2)/(M1*M2)));
R = 3;

ac_c = C*(1+Math.cos(k))/(2*C-omg_ac*omg_ac*M2);
ac_s = -C*Math.sin(k)/(2*C-omg_ac*omg_ac*M2);
op_c = C*(1+Math.cos(k))/(2*C-omg_op*omg_op*M1);
op_s = C*Math.sin(k)/(2*C-omg_op*omg_op*M1);

R = 3*Math.sqrt(M1);

for (i=0; i<16; i++) {
  x_ac1 = 2*18.75*i+4*Math.cos(omg_ac*t+i*k)+9.375;
  x_ac2 = 2*18.75*(i+0.5)+ac_c*4*Math.cos(omg_ac*t+i*k)+ac_s*4*Math.sin(omg_ac*t+i*k)+9.375;
  x_op1 = 2*18.75*i+op_c*4*Math.cos(omg_op*t+i*k)+op_s*4*Math.sin(omg_op*t+i*k)+9.375;
  x_op2 = 2*18.75*(i+0.5)+4*Math.cos(omg_op*t+i*k)+9.375;
  ctx.beginPath();
  ctx.arc(x_ac1,30,R,0,2*pi);
  ctx.fill();
  ctx.beginPath();
  ctx.arc(x_ac2,30,3,0,2*pi);
  ctx.fill();
  ctx.beginPath();
  ctx.arc(x_op1,10,R,0,2*pi);
  ctx.fill();
  ctx.beginPath();
  ctx.arc(x_op2,10,3,0,2*pi);
  ctx.fill();
}
t = t + dt;

d2[0] = [k,omg_ac/Math.sqrt(2*C*(M1+M2)/(M1*M2))];
d2[1] = [k,omg_op/Math.sqrt(2*C*(M1+M2)/(M1*M2))];
//plot the data
  var data1 = [{ data: d1, color: "rgb(0, 0, 0)", shadowSize:0, lines: {show:true}},{ data: d3, color: "rgb(0, 0, 0)", shadowSize:0, lines: {show:true}},{ data: d2, color: "rgb(255, 0, 0)", shadowSize:0, points: {show:true}}];
  $.plot($("#placeholder1"), data1);
requestAnimationFrame(step);
}
requestAnimationFrame(step);
<head>
  <script language="javascript" type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js"></script>
  <script language="javascript" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.min.js"></script>

  <script type="text/x-mathjax-config">
    MathJax.Hub.Config({
      extensions: ["tex2jax.js"],
      jax: ["input/TeX","output/HTML-CSS"],
      tex2jax: {inlineMath: [["$","$"],["\\(","\\)"]]}
    });
  </script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML"></script>
</head>


<div style="display: flex">
  <div id="placeholder1" style="width:400px;height:300px;"></div>
  <div style="margin: 25px 10px">
    <div>
      $\frac{M_1}{M_2}=$<span id="Mtext">1.1</span>&emsp;
      <input type="button" value="-" onclick="lessM();">
      <input type="button" value="+" onclick="moreM();">
    </div>
    <div>
      $ka=$<span id="ka"></span>&emsp;
      <input type="button" value="-" onclick="lessk();">
      <input type="button" value="+" onclick="morek();">
    </div>
  </div>
</div>
<div>
  <canvas style="margin: 12px;" id="theCanvas" width="600" height="40"></canvas>
</div>