pseudo 3D camera turning html canvas javascript [closed]

I am trying to learn to make 3D games in JavaScript using HTML 2D canvas. I was following this post about it and I made a simple scene that you can move around in.

What I need help with is figuring out how to make the effect of the player turning their head, to look side to side and behind them.

Here is what I have:

Codepen link

Code (also on codepen)

html:

<html lang="en"> <head>     <meta charset="UTF-8">     <meta http-equiv="X-UA-Compatible" content="IE=edge">     <meta name="viewport" content="width=device-width, initial-scale=1.0">     <title>3d test</title> </head> <body>     <canvas id="canv"></canvas> </body> </html> 

javascript

//use arrow keys to move around  var canvas = document.getElementById("canv"); var c = canvas.getContext("2d");  canvas.width = canvas.height = 800;  var crateImg = new Image();  class Entity {     constructor(x, y, z, w, h) {         this.x = x;         this.y = y;         this.z = z;         this.w = w;         this.h = h;         this.rx = 0;         this.ry = 0;         this.rs = 0;     }     render() {         //c.fillStyle = 'red';         //c.fillRect(this.rx, this.ry, this.rs*this.w, this.rs*this.h);         c.drawImage(crateImg, this.rx, this.ry, this.rs*this.w, this.rs*this.h);     }     update() {         //project to 3d         this.rs = 400/(400+this.z);         this.rx = ((this.x*this.rs) + 400);         this.ry = (this.y*this.rs) + 400;           //move         this.x += camera.xSpeed;         this.y += camera.ySpeed;         this.z += camera.zSpeed;     } }  var camera = {     xSpeed: 0,     ySpeed: 0,     zSpeed: 0, }  var entities = [];  function random(min, max) {     return Math.floor(Math.random() * (max - min) + min); }  window.onload = function() {     start();     update(); }  function start() {     crateImg.src = "https://i.imgur.com/O9ForWS_d.webp?maxwidth=760&amp;fidelity=grand";     for(let i = 0; i < 100; i++) {         entities.push(new Entity(random(-800, 800), 0, i*10, 50, 50));     } }  function render() {     //fill background     c.fillStyle = 'skyblue';     c.fillRect(0, 0, 800, 800);     //draw flooor     c.fillStyle = 'green';     c.fillRect(0, 400, 800, 400);     //draw entities     for(let i = 0; i < entities.length; i++) {         if(entities[i].z > -400) {             entities[i].render();         }     } }  function update() {     //updatre entities     for(let i = 0; i < entities.length; i++) {         entities[i].update();     }     entities.sort(function(i, i2) {         return i2.z - i.z;     })     //redraw current frame     render();     requestAnimationFrame(update); }   function keyDown(e) {     switch(e.keyCode) {         case 39:             camera.xSpeed = -5;             break;         case 37:             camera.xSpeed = 5;             break;         case 38:             camera.zSpeed = -5;             break;         case 40:             camera.zSpeed = 5;             break;     } }  function keyUp(e) {     switch(e.keyCode) {         case 39:         case 37:             camera.xSpeed = 0;             break;         case 38:         case 40:             camera.zSpeed = 0;             break;     } }  document.onkeydown = keyDown; document.onkeyup = keyUp; ```