SVGとJavascriptでボールがバウンドするアニメーションを行う

SVGとJavascriptでボールがバウンドするアニメーションを行う

SVGを使うとCanvasを使うのと同じくらい簡単にアイコン等を表示できます
更にJavascriptを組み合わせるとアニメーションすることが出来ます。
SVGでボールを表示させ、Javascriptでバウンドするアニメーションを実装します。

HTML,CSS,Javascriptコード

<svg style="width:100%;" viewBox="0 0 640 200" class="MamSVGBallAnimation"></svg>
<script>
  function TMamSVGBallAnimation(){
    'use strict';
    this.background="#fff";//背景色:"#fff" "#000" "none" 等
    this.num=100;//ボールの数
    this.r=8;   //ボールの半径
    this.svg=[];
    this.circle=[];
    this.point=[];
    this.v=[];
    this.vx=[];
    this.init=function(){
    this.svg=document.querySelectorAll('svg.MamSVGBallAnimation');
      for(let i=0;i<this.svg.length;i++){
        this.vx[i]=this.svg[i].getAttribute("viewBox").split(" ");
        if(this.vx[i].length!=4){
          this.vx[i]=[0,0,640,200];
          this.svg[i].setAttribute("viewBox",vx[i].join(" "));
        }
        for(let j=0;j<this.vx[i].length;j++){
          this.vx[i][j]=Number(this.vx[i][j]);
        }
        let rect=document.createElementNS("http://www.w3.org/2000/svg","rect");
        rect.style.fill=this.background;
        rect.style.stroke="none";
        rect.style.strokeWidth="0";
        rect.setAttributeNS(null,"x",this.vx[i][0]);
        rect.setAttributeNS(null,"y",this.vx[i][1]);
        rect.setAttributeNS(null,"width",this.vx[i][2]);
        rect.setAttributeNS(null,"height",this.vx[i][3]);
        this.svg[i].appendChild(rect);
        this.point[i]=[];
        this.v[i]=[];
        this.circle[i]=[];
        for(let j=0;j<this.num;j++){
          this.point[i][j]=[];
          this.point[i][j]["x"]=(this.vx[i][0]+this.r+Math.random()*(this.vx[i][2]-this.r*2));
          this.point[i][j]["y"]=(this.vx[i][1]+this.r+Math.random()*(this.vx[i][3]-this.r*2)*0.7+(this.vx[i][3]-this.r*2)*0.3);
          this.v[i][j]=[];
          this.v[i][j]["x"]=(Math.random()*(this.vx[i][2]-this.r*2)/100-(this.vx[i][2]-this.r*2)/200);
          this.v[i][j]["y"]=(Math.sqrt(this.vx[i][3]-this.r*2)*0.40)*Math.random()-(Math.sqrt(this.vx[i][3]-this.r*2)*0.40);
          this.circle[i][j]=document.createElementNS("http://www.w3.org/2000/svg","circle");
          this.circle[i][j].setAttributeNS(null,"cx",this.point[i][j]["x"]);
          this.circle[i][j].setAttributeNS(null,"cy",this.point[i][j]["y"]);
          this.circle[i][j].setAttributeNS(null,"r",this.r);
          //this.circle[i][j].style.fill="#EEE";
          this.circle[i][j].style.fill=
            "rgb("+
              Math.round(Math.random()*255)+","+
              Math.round(Math.random()*255)+","+
              Math.round(Math.random()*255)+
            ")";
          this.circle[i][j].stroke="none";
          this.circle[i][j].strokeWidth="0";
          this.svg[i].appendChild(this.circle[i][j]);
        }
      }
      this.interval=function(){
        for(let i=0;i<this.svg.length;i++){
          for(let j=0;j<this.num;j++){
            this.v[i][j]["y"]+=0.2;
            this.point[i][j]["x"]+=this.v[i][j]["x"];
            this.point[i][j]["y"]+=this.v[i][j]["y"];
            if(this.point[i][j]["x"]>(this.vx[i][0]+this.vx[i][2]-this.r)){
              this.v[i][j]["x"]=-this.v[i][j]["x"];
              this.point[i][j]["x"]+=this.v[i][j]["x"];
            }
            if(this.point[i][j]["x"]<(this.vx[i][0]+this.r)){
              this.v[i][j]["x"]=-this.v[i][j]["x"];
              this.point[i][j]["x"]+=this.v[i][j]["x"];
            }
            if(this.point[i][j]["y"]>(this.vx[i][1]+this.vx[i][3]-this.r)){
              this.v[i][j]["y"]=-this.v[i][j]["y"];
              this.point[i][j]["y"]+=this.v[i][j]["y"];
            }
            this.circle[i][j].setAttributeNS(null,"cx",this.point[i][j]["x"]);
            this.circle[i][j].setAttributeNS(null,"cy",this.point[i][j]["y"]);
          }
        }
      }
      setInterval(this.interval.bind(this),33);
    }
    window.addEventListener("DOMContentLoaded",this.init.bind(this));
  }
  var MamSVGBallAnimation=new TMamSVGBallAnimation;
</script>


Mam's WebSite