The HTML file:

<head>
 <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
  <script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML"> </script>
 <script type="text/x-mathjax-config">
  MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});
</script>

 <link rel="stylesheet" href="http://mirkwood.cs.edinboro.edu/~bennett/style/hw.css">
</head>

<body>
<p>
<canvas id="canvas" width="400" height="400" style="border:1px solid #000000;"></canvas>
<p>

<ul>
   <li> wasd or hjkl to move
   <li> m,n to rotate
   <li> +,- to scale
   <li> r to reset
   <li> x to toggle animation
</ul>

<script type="text/javascript" src="move.js"></script>
<script type="text/javascript" src="moveUI.js"></script>

<script type="text/javascript">
'use strict'

let canvas = document.getElementById("canvas");
let ctx = canvas.getContext('2d'); 
let width = canvas.width;
let height = canvas.height;

canvas.tabIndex = 0;
canvas.addEventListener("keydown", MyHandler);

let blueStarTheta;
let redStarTheta;
let starScale;
let worldTx;
let worldTy;
let worldScale;
let worldRotate;
let wordRotate;

Reset();

function Reset() {
      blueStarTheta = 20;
      redStarTheta = 20;
      starScale = 10;
      worldTx = 0;
      worldTy = 0;
      worldScale = 1;
      worldRotate = 0;
      wordRotate = 0;
}


StartTicks();
</script>

</body>
</html>

moveUI.js

"use strict"
let timer=null;
let redStarDelta = 1;
let starDelta = 1;

function MyHandler(evnt){
    let key = evnt.key;
    let stopMove = true;

    switch(key) {
       case 'x':
          if (timer == null) {
             StartTicks();
          } else {
             StopTicks();
          }
          stopMove = false;
          break;
       case 'd':
       case 'l':
          worldTx ++;
          break;
       case 'a':
       case 'h':
          worldTx --;
          break;
       case 'w':
       case 'k':
          worldTy++;
          break;
       case 's':
       case 'j':
          worldTy--;
          break;
       case '+':
          worldScale+= 0.1;
          break;
       case '-':
          worldScale-= 0.1;
          break;
       case 'n':
          worldRotate++;
          break;
       case 'm':
          worldRotate--;
          break;
       case 'r':
          Reset();
          break;
    }
    if (stopMove && timer==null ) {
       DrawScene();
    }
}

function Tick() {
    blueStarTheta = (blueStarTheta + 1) %360;
    wordRotate = (wordRotate - 1) %360;

    if (redStarTheta >= 160) {
       redStarDelta = -1;
        
    }  else if (redStarTheta <= 20) {
       redStarDelta = 1;
    }
    redStarTheta += redStarDelta;
    
    if (starScale > 10) {
       starDelta = -1;
    } else if (starScale < 2) {
       starDelta = 1;
    }

    starScale += starDelta;

    DrawScene();
}

function StartTicks() {
    timer = setInterval(Tick, 200);    
}

function StopTicks() {
    if (timer != null) {
       clearInterval(timer);
       timer = null
    }
}

move.js

"use strict"

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

    Axis(ctx,width,height);

    // filp the axis
    ctx.setTransform(1, 0, 0, -1, 0, height);
    // center the origin
    ctx.translate(width/2, height/2);

    // user movement
    ctx.scale(worldScale, worldScale);
    ctx.rotate(worldRotate*Math.PI/180);
    ctx.translate(worldTx, worldTy);

    Scene(ctx, width, height);

    ctx.restore();
}

function Axis(ctx, w, h) {

    ctx.strokeStyle = "black";
    ctx.beginPath();

    ctx.moveTo(0, h/2);
    ctx.lineTo(w,h/2);

    ctx.moveTo(w/2,0);
    ctx.lineTo(w/2,h);
    ctx.stroke();
}

function Greeting(ctx,w,h){
    ctx.save();

    ctx.scale(1,-1);

    ctx.beginPath();

    ctx.font = "60pt sans";
    ctx.strokeStyle = "black";

    // remember y will move the "wrong" way because we have things flipped.
    ctx.translate(-110,20);
    ctx.strokeText("Hello", 0 , 0);

    ctx.stroke();
    
    ctx.restore();
}

function Star(ctx, color = "black", r = 10) {
   let i, x, y, t;
   
   let b = Math.PI/2;
   let a = 2*Math.PI/5;

   let sides=[0,2,4,1,3];

   t = 0;

   ctx.beginPath();

   ctx.strokeStyle = color;

   // compute the right place to start and move to it.
   let sx = r*Math.cos(b);
   let sy = r*Math.sin(b);
   ctx.moveTo(sx,sy);

   for(i = 1; i<=5;i++) {
      let s = sides[i];
      x = r*Math.cos(s*a + b);
      y = r*Math.sin(s*a + b);

      ctx.lineTo(x,y);
   }

   // go back to the start
   ctx.lineTo(sx,sy);

   ctx.stroke();

   return;
}

function BlueStar(ctx, w,h){

    ctx.save();

    ctx.translate(w/4, h/4);
    ctx.rotate(blueStarTheta * Math.PI/180);
    Star(ctx, "blue", 20);

    ctx.restore();
}

function MagentaStar(ctx, w,h){

    ctx.save();

    ctx.rotate(blueStarTheta * Math.PI/180);
    ctx.translate(w/4, h/4);
    Star(ctx, "Magenta", 20);

    ctx.restore();
}

function RedStar(ctx, w,h){

    ctx.save();

    ctx.rotate(redStarTheta * Math.PI/180);
    ctx.translate(w/4, 0);
    Star(ctx, "red", 20);

    ctx.restore();
}

function GreenStar(ctx, w,h){

    ctx.save();

    ctx.translate(-w/3, -h/3);
    ctx.scale(starScale,starScale);
    ctx.lineWidth = 1/starScale;
    Star(ctx, "green", 3);

    ctx.restore();
}

function CyanStar(ctx, w,h){

    ctx.save();

    ctx.scale(starScale,starScale);
    ctx.translate(10, -10);
    ctx.lineWidth = 1/starScale;
    Star(ctx, "cyan", 3);

    ctx.restore();
}


function Scene(ctx, w, h) {


    BlueStar(ctx,w,h);
    MagentaStar(ctx,w,h);

    RedStar(ctx,w,h);

    GreenStar(ctx,w,h);
    CyanStar(ctx,w,h);

    ctx.save();
    ctx.rotate(wordRotate * Math.PI/180);
    Star(ctx);
    Greeting(ctx,w,h);
    ctx.restore();
}