Last active
April 5, 2025 16:05
-
-
Save GermanHoyos/677f012cffa89f849508decb2b56a96f to your computer and use it in GitHub Desktop.
Starter code for displaying a unit circle in html canvas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Written by German Adrian Hoyos | |
// Linkedin: https://www.linkedin.com/in/adrian-i-81a32615b/ | |
console.log("Base_Unit_Circle"); | |
var canvas = document.querySelector("canvas"); | |
var c = canvas.getContext('2d'); | |
canvas.width = window.innerWidth; | |
canvas.height = window.innerHeight; | |
let up = false; | |
let down = false; | |
let left = false; | |
let right = false; | |
let accelerate = false; | |
const FRICTION = 0.7; | |
const FPS = 30; | |
window.addEventListener("keydown", keyDown); //lowercase in "" | |
window.addEventListener("keyup", keyUp); //lowercase in "" | |
function keyDown(e) { //camelCase in call | |
console.log(e.keyCode); | |
if (e.keyCode == 68 || e.keyCode == 39) { | |
console.log("right"); | |
right = true; | |
} | |
if (e.keyCode == 65 || e.keyCode == 37) { | |
console.log("left"); | |
left = true; | |
} | |
if (e.keyCode == 87 || e.keyCode == 38) { | |
console.log("foward"); | |
accelerate = true; | |
} | |
if (e.keyCode == 83 || e.keyCode == 40) { | |
console.log("reverse"); | |
} | |
} | |
function keyUp(e) { //camelCase in call | |
if (e.keyCode == 68 || e.keyCode == 39) { | |
console.log("right release"); | |
right = false; | |
} | |
if (e.keyCode == 65 || e.keyCode == 37) { | |
console.log("left release"); | |
left = false; | |
} | |
if (e.keyCode == 87 || e.keyCode == 38) { | |
console.log("foward release"); | |
accelerate = false; | |
} | |
if (e.keyCode == 83 || e.keyCode == 40) { | |
console.log("reverse release"); | |
} | |
} | |
class UnitCircleClass { | |
//Class constructor to receive in params | |
constructor(x, y, radius, selectBehaviour) { | |
this.x = x; //this objects center x pos | |
this.y = y; //this objects center y pos | |
this.radius = radius; //this objetcs radius | |
this.angle = 90 / 180 * Math.PI; //this objects angle converted to degrees | |
this.accl_angle = 0 / 180 * Math.PI; //this objetcs accelleration angle converted to degrees | |
this.rotation = .017; //a single degree reference conversion | |
this.turn_speed = .5; //amount of turn of this.angle | |
this.accl_speed = 3; //amount of change for (x/y) | |
this.accelerate = false; //bool | |
this.vectorX = 0; //reference for changing this.x | |
this.vectorY = 0; //reference for changing this.y | |
this.behavior = selectBehaviour; //chose acceleration type; | |
this.UsrControlled= false; //0 | |
this.AiControlled = false; //1 | |
} | |
//behavior of movement of this object | |
selectBehaviour(){ | |
if(this.behavior == 0){ | |
this.UsrControlled = true; //console.log('Usr Controlled Object ' + this.UsrControlled); | |
} | |
if(this.behavior == 1){ | |
this.AiControlled = true; //console.log('Ai Controlled Object ' + this.AiControlled); | |
accelerate = true; | |
} | |
} | |
//calculate unit circle | |
arcRender() { | |
//console.log('arcRender called'); | |
c.beginPath(); | |
c.arc(this.x, this.y, this.radius, 0, 2 * Math.PI); | |
c.strokeStyle = 'white'; | |
c.stroke(); | |
} | |
//calculate initial/desired angle | |
calcAngle() { //green (actual force applied) | |
c.beginPath(); | |
c.moveTo(this.x, this.y); | |
c.lineTo( | |
this.x + this.radius * Math.cos(this.angle), | |
this.y - this.radius * Math.sin(this.angle) | |
); | |
c.closePath(); | |
c.stroke(); | |
} | |
//calculate accelleration angle | |
calcAccl() { //red (actual vector derived) | |
c.beginPath(); | |
c.moveTo(this.x, this.y); | |
c.lineTo( | |
this.x + this.radius * Math.cos(this.accl_angle), | |
this.y - this.radius * Math.sin(this.accl_angle) | |
); | |
c.closePath(); | |
c.stroke(); | |
} | |
aiControl(){ | |
if (this.AiControlled == true) { | |
this.angle += .017 * this.turn_speed; | |
} | |
} | |
//rotate this.angle clockwise | |
rotateRight() { | |
if (right == true && this.UsrControlled == true) { | |
this.angle -= this.rotation * this.turn_speed * 2; | |
} | |
} | |
//rotate this.angle counter clockwise | |
rotateLeft() { | |
if (left == true && this.UsrControlled == true) { | |
this.angle += this.rotation * this.turn_speed * 2; | |
} | |
} | |
//apply an accelleration force in the direction of this.angle | |
accell() { //0 | |
if (accelerate == true) { | |
this.vectorX += this.accl_speed * Math.cos(this.angle) / FPS; | |
this.vectorY -= this.accl_speed * Math.sin(this.angle) / FPS; | |
} else { | |
this.vectorX -= FRICTION * this.vectorX / FPS; | |
this.vectorY -= FRICTION * this.vectorY / FPS; | |
} | |
this.x += this.vectorX; | |
this.y += this.vectorY; | |
//visually snaps both angles together | |
if (accelerate == true) { | |
this.accl_angle = this.angle - 180 * Math.PI | |
} | |
} | |
//Render circle in canvas | |
draw() { | |
this.selectBehaviour(); | |
this.arcRender(); | |
c.restore(); | |
c.save(); | |
c.strokeStyle = 'green'; | |
this.calcAngle(); | |
c.restore(); | |
c.save(); | |
c.restore(); | |
c.save(); | |
c.strokeStyle = 'red'; | |
this.calcAccl(); | |
c.restore(); | |
c.save(); | |
this.accell(); | |
this.aiControl(); | |
this.rotateRight(); | |
this.rotateLeft(); | |
} | |
} | |
var underlay = new UnitCircleClass(innerWidth / 2, innerHeight / 2, 150, 0); | |
function drawIf() { | |
underlay.draw(); | |
} | |
function animate() { | |
requestAnimationFrame(animate); | |
c.clearRect(0, 0, innerWidth, innerHeight); | |
drawIf(); | |
} | |
animate(); // for my son - c u soon kiddo! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment