SVGとJavascriptでキューブがバウンドするアニメーションを行う(其の2)

HTMLとJavascript

<div>
  <svg viewBox="0 0 32 64" style="width:160px;height:320px;" id="cubes">
    <defs>
      <g id="cubeg">
        <path d="M0,0.7 l1.4,0.7 l1.4,-0.7 l-1.4,-0.7 z" style="fill:#8E4;stroke:#240;stroke-width:0.1"></path>
        <path d="M0,0.7 l0,1.4 l1.4,0.7 l0,-1.4 z" style="fill:#6C2;stroke:#240;;stroke-width:0.1"></path>
        <path d="M1.4,1.4 l0,1.4 l1.4,-0.7 l0,-1.4 z" style="fill:#4A0;stroke:#240;;stroke-width:0.1"></path>
      </g>
      <g id="cuber">
        <path d="M0,0.7 l1.4,0.7 l1.4,-0.7 l-1.4,-0.7 z" style="fill:#E84;stroke:#420;stroke-width:0.1"></path>
        <path d="M0,0.7 l0,1.4 l1.4,0.7 l0,-1.4 z" style="fill:#C62;stroke:#420;;stroke-width:0.1"></path>
        <path d="M1.4,1.4 l0,1.4 l1.4,-0.7 l0,-1.4 z" style="fill:#A40;stroke:#420;;stroke-width:0.1"></path>
      </g>
    </defs>
  </svg>
</div>
<script>
  cube_elm=[],celm=null;
  // ↓Y →X ←Z
  cube_color=[
    [ //y=0
      [0,0,0,0,0,0,0],//x=0
      [0,1,1,1,1,1,0],//x=1
      [0,0,1,0,0,0,0],
      [0,0,0,1,0,0,0],
      [0,0,1,0,0,0,0],
      [0,1,1,1,1,1,0],
      [0,0,0,0,0,0,0],
    ],
    [
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,1],
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0],
      [0,1,0,0,0,1,0],
    ],
    [
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,1],
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,1],
      [0,0,0,0,0,0,0],
      [0,1,1,0,1,1,0],
    ],
    [
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,1],
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,1],
      [0,1,0,1,0,1,0],
    ],
    [
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,1],
      [0,0,0,0,0,0,1],
      [0,0,0,0,0,0,1],
      [0,0,0,0,0,0,1],
      [0,0,0,0,0,0,1],
      [0,1,0,0,0,1,0],
    ],
    [
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,1],
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,1],
      [0,1,0,0,0,1,0],
    ],
    [
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0],
    ],
  ];
  window.addEventListener("DOMContentLoaded",function(){
    celm=document.getElementById("cubes");
    for(y=6;y>=0;y--){
      cubes[y]=[];
      for(x=0;x<=6;x++){
        cubes[y][x]=[];
        for(z=0;z<=6;z++){
          let xxyy=cube_conv(x,y,z);
          let xx=xxyy[0];
          let yy=xxyy[1];
          let elm=document.createElementNS("http://www.w3.org/2000/svg","use");
          if(cube_color[y][x][z]==1){
            elm.setAttributeNS(null,"href","#cuber");
          }else{
            elm.setAttributeNS(null,"href","#cubeg");
          }
          elm.setAttributeNS(null,"x",xx);
          elm.setAttributeNS(null,"y",yy);
          celm.appendChild(elm);
          let e=[];
          e.elm=elm;
          e.xx=e.x=x;
          e.yy=e.y=y;
          e.zz=e.z=z;
          e.v=(Math.random()-0.5)*0.3;
          e.flag=0;
          cube_elm.push(e);
        }
      }
    }
    setTimeout(gogo,1000);
  });
  function gogo(){
    for(let i=0;i<cube_elm.length;i++){
      if(cube_elm[i].flag<2){
        cube_elm[i].v+=0.005;
        cube_elm[i].yy+=cube_elm[i].v;
      }
      if(cube_elm[i].yy>21&& cube_elm[i].flag==0){
        cube_elm[i].v=-cube_elm[i].v;
        cube_elm[i].yy+=cube_elm[i].v;
        cube_elm[i].flag=1;
      }else if(cube_elm[i].flag==1){
        if(Math.round(cube_elm[i].yy*100)==cube_elm[i].y*100){
          cube_elm[i].flag=2;
        }
      }
      let xxyy=cube_conv(cube_elm[i].xx,cube_elm[i].yy,cube_elm[i].zz);
      let xx=xxyy[0];
      let yy=xxyy[1];
      cube_elm[i].elm.setAttributeNS(null,"x",xx);
      cube_elm[i].elm.setAttributeNS(null,"y",yy);
    }
    let flag=true;
    for(let i=0;i<cube_elm.length;i++){
      if(cube_elm[i].flag!=2){
        flag=false;
      }
    }
    if(flag){
      cube_reset();
      setTimeout(gogo,3000);
    }else{
      setTimeout(gogo,20);
    }
  }
  function cube_reset(){
    for(let i=0;i<cube_elm.length;i++){
      cube_elm[i].xx=cube_elm[i].x;
      cube_elm[i].yy=cube_elm[i].y;
      cube_elm[i].zz=cube_elm[i].z;
      cube_elm[i].flag=0;
      cube_elm[i].v=(Math.random()-0.5)*0.3;
    }
  }
  function cube_conv(x,y,z){
    let xx=14+z*(-2) +x*2 + y*0;
    let yy=4+z*1     +x*1 + y*2;
    return [xx,yy];
  }
</script>