The HTML file:

<head>
    <script type="text/javascript" src="star.js"> </script> 
    <script type="text/javascript" src="UI.js"> </script> 
</head>
<body>
   <canvas id="canvas" width=500 height=500 style="border:2px solid"></canvas>
   <p>
   <ul>
   </ul>
   <script>
       'use strict'
 
       var canvas = document.getElementById('canvas');
       canvas.tabIndex=0;
       canvas.addEventListener("keypress", Keypress);

       var items = [];
       items.push(new Star(canvas.width/2, canvas.height/2));
       items.push(new Star(canvas.width/4, canvas.height/4));
       items.push(new Star(3*canvas.width/4, canvas.height/4));
       items.push(new Star(3*canvas.width/4, 3*canvas.height/4));
       items.push(new Star(canvas.width/4, 3*canvas.height/4));
   
       var animation = false;
       var rotation = 0;
       var doRotation = false;

       var ctx = canvas.getContext('2d');
       ctx.transform(1,0,0,-1,0,canvas.height);

       DrawScene(items);
   </script>

   <ul>
      <li> <b>b</b> toggles boing for center star
      <lI> <b>w</b> toggles whir for center star
      <lI> <b>p</b> toggles phase for center star
      <li> <b>G</b> go
      <li> <b>S</b> stop
      <lI> <b>A</b> copy center to all
      <lI> <b>R</b> reset All
      <li> <b>W</b> toggle whir for entire scene.
   </ul>

</body>

UI.js

'use strict'
function Keypress(evnt) {
    switch(event.key) {
       case 'A':
	  for (let i=1;i<items.length;i++) {
	      items[i].Copy(items[0]);
	  }
	  break;

	case 'G':
	  // don't want to start a second one if we are already animating
	  if (animation != true) {
	      animation = true;
	      setTimeout(DoAnimation, 20);
	  }
	  break;

	case 'S':
	  animation = false;
	  break;

       case 'R':
	  for (let i=0;i<items.length;i++) {
	      items[i].Reset();
	  }
	  animation = false;
	  break;
       case 'W':
          doRotation = !doRotation;
	  break;
       case 'b':
          items[0].FlipScale()
          break;

       case 'p':
          items[0].FlipPhase();
          break;

       case 'w':
          items[0].FlipSpin();
          break;
    }
    DrawScene();
}

function DoAnimation() {
     if (doRotation) {
         rotation -= 1;
         rotation %= 360;
     }

     DrawScene();

     if (animation) {
	  setTimeout(DoAnimation, 20);
     }
}

function DrawScene(){
    
     ctx.clearRect(0,0, canvas.height, canvas.width);
     ctx.save();

     ctx.translate(canvas.width/2, canvas.height/2);
     ctx.rotate(rotation*Math.PI/180);
     ctx.translate(-canvas.width/2, -canvas.height/2);

     for(let i = 0; i < items.length; i++) {
         items[i].Next();
         items[i].Display(ctx);
     }
     ctx.restore();
}

star.js

'use strict'

const SCALE_MIN = 20;
const SCALE_MAX = 100;

function MakePoints() {
   let pts = [];

   for(let i = 0; i < 5; i++) {
       let angle = i*Math.PI*2/5;
       let x = Math.cos(angle);
       let y = Math.sin(angle);
       pts.push([x,y]);
   }
   return pts;
}

class Star{
    constructor(cx = 0, cy = 0 ){
        this.points = MakePoints();
	this.orderB = [0,1,2,3,4];
	this.orderA = [3,1,4,2,0];
        this.cx = cx;
	this.cy = cy;
 
        this.Reset();
    }

    Copy (master) {
	this.scale = master.scale;
	this.scaling = master.scaling;
	this.scaleDir = master.scaleDir;

	this.rotation = master.rotation;
	this.spinning = master.spinning;
	this.spinDown = master.spinDown;

	this.phasing = master.phasing;
	this.phaseDir = master.phaseDir;
	this.phaseStep = master.phaseStep;
    }

    Reset() {
	this.scale = SCALE_MIN;
	this.scaling = false;
	this.scaleDir = 1;

	this.rotation = 0;
	this.spinning = false;
	this.spinDown = false;

	this.phasing = false;
	this.phaseDir = 1;
	this.phaseStep = 0;
    }

    FlipSpin() {
        this.spinning = !this.spinning;
	if (this.spinning == false ) {
	   this.spinDown = true;
	} else {
	   this.spinDown = false;
	}
    }

    FlipScale() {
        this.scaling = !this.scaling;
    }

    FlipPhase() {
       this.phasing = !this.phasing;
    }

    Next() {
        if (this.spinning || (this.spinDown  && this.rotation != 0)) {
	    this.rotation += 1;
	    this.rotation %= 360;
	}

	if(this.spinDown && this.rotation == 0) {
	    this.spinDown = false;
	}

	if (this.scaling) {
	    this.scale += this.scaleDir;
	    if (this.scale <= SCALE_MIN) {
	        this.scaleDir = 1;
	    } 

	    if (this.scale >= SCALE_MAX) {
	        this.scaleDir =  -1;
	    }
	}

	if (this.phasing) {
	   this.phaseStep += .01 * this.phaseDir;
	   if (this.phaseStep <= 0) {
	       this.phaseDir = 1;
	   }
	   if (this.phaseStep >= 1) {
	       this.phaseDir = -1;
	   }
	}
    }

    TruePoint(pt) {
        let idx1 = this.orderA[pt];
	let idx2 = this.orderB[pt];

	let x = this.points[idx1][0] * (1-this.phaseStep) 
	                + this.points[idx2][0]*this.phaseStep;
	let y = this.points[idx1][1] * (1-this.phaseStep) 
	                + this.points[idx2][1]*this.phaseStep;

        return [x,y];
    }

    Display(ctx) {

        let scale = this.scale;
        ctx.save();
        ctx.translate(this.cx, this.cy)
	ctx.rotate(this.rotation*Math.PI/180);

	let last = this.points.length-1;

        ctx.beginPath();

	let pt = this.TruePoint(last);

	ctx.fillStyle = "red";
	ctx.arc(pt[0]*scale,pt[1]*scale, 4, 0, Math.PI*2);
	ctx.fill();

	ctx.strokeStyle = "blue";
	ctx.moveTo(pt[0]*scale,pt[1]*scale);

	for(let i=0; i<=last; i++) {
	 
	   let pt = this.TruePoint(i);
	   ctx.lineTo(pt[0]*scale,pt[1]*scale);
	}
        ctx.stroke();
	ctx.closePath();

	ctx.restore();
    }
}