How to make Javascript font responsive? - javascript

I'm trying to rework this codepen: https://codepen.io/christhuong/pen/XxzNWK
const data = {
font: {
family: 'Oswald',
size: 70,
weight: 'bold'
},
colors: ['rgb(248, 225, 0)', 'rgb(232, 0, 137)', 'rgb(0, 170, 234)'],
text: `INTERACTIVE * DEVELOPER`,
textlength: 0
}
const canvas = {
elem: document.querySelector('canvas'),
init() {
return this.elem.getContext('2d')
},
resize() {
canvas.elem.width = innerWidth;
canvas.elem.height = innerHeight;
}
}
canvas.resize();
const ctx = canvas.init();
const pointer = {
x: innerWidth/2, y: innerHeight/2,
r: 220
}
class CHAR {
constructor(char, x, y, color, layer) {
this.char = char;
this.cx = x;
this.cy = y;
this.color = color;
this.layer = layer;
this.r = 0;
this.alpha = 0;
this.dx = this.cx;
this.dy = this.cy;
}
static measuretext(text) {
return ctx.measureText(text).width;
}
static dist(x1, y1, x2, y2) {
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
}
static getAngle(x1, y1, x2, y2) {
return Math.atan2(y2 - y1, x2 - x1);
}
static init(text, x, y) {
ctx.font = `${data.font.weight} ${data.font.size}px ${data.font.family}`;
ctx.textBaseline = 'middle';
ctx.globalCompositeOperation = 'darken';
for (let color = 0; color < data.colors.length; color++) {
let layer = 1;
switch (color) {
case 0:
layer = 0.5;
break;
case 1:
layer = 0.7;
break;
case 2:
layer = 1;
break;
}
const strs = text.split(' * ');
const textlength = strs.map(str => this.measuretext(str));
data.textlength = Math.max(...textlength);
const textheight = this.measuretext('M') * 1.5;
for (let i = 0; i < strs.length; i++) {
let ww = 0;
for (let j = 0; j < strs[i].length; j++) {
const xx = x - textlength[i] / 2 + ww;
const yy = i == 0 ? y - textheight / 2 : y + textheight / 2;
chars.push(new CHAR(strs[i][j], Math.round(xx), Math.round(yy), data.colors[color], layer));
ww += this.measuretext(strs[i][j]);
}
}
}
}
static draw() {
for (let i = 0; i < data.colors.length; i++) {
ctx.fillStyle = data.colors[i];
for (let j = 0; j < chars.length; j++) {
if (chars[j].color == data.colors[i]) {
ctx.fillText(chars[j].char, chars[j].dx, chars[j].dy);
}
}
}
}
render() {
this.dx += (this.cx - this.dx) * 0.2;
this.dy += (this.cy - this.dy) * 0.2;
}
update() {
const dis = CHAR.dist(pointer.x, pointer.y, this.cx, this.cy);
if (dis < pointer.r) {
this.alpha = CHAR.getAngle(pointer.x, pointer.y, this.cx, this.cy) + Math.PI;
this.r = this.layer * dis * (pointer.r - dis) / pointer.r;
this.dx += (this.cx + this.r * Math.cos(this.alpha) - this.dx) * 0.2;
this.dy += (this.cy + this.r * Math.sin(this.alpha) - this.dy) * 0.2;
} else {
this.render()
}
}
}
let chars = [];
CHAR.init(data.text, innerWidth / 2, innerHeight / 2);
setTimeout(() => {
chars = [];
CHAR.init(data.text, innerWidth / 2, innerHeight / 2);
}, 10);
window.addEventListener('mousemove', e => {
pointer.x = e.clientX; pointer.y = e.clientY;
})
window.addEventListener('touchmove', e => {
e.preventDefault();
pointer.x = e.targetTouches[0].clientX;
pointer.y = e.targetTouches[0].clientY;
})
window.addEventListener('resize', () => {
canvas.resize();
chars = [];
CHAR.init(data.text, innerWidth / 2, innerHeight / 2);
})
const run = () => {
requestAnimationFrame(run);
ctx.clearRect(innerWidth / 2 - data.textlength, innerHeight / 2 - 0.7 * data.textlength, 2 * data.textlength, 1.4 * data.textlength);
if (Math.abs(pointer.x - innerWidth / 2) < data.textlength &&
Math.abs(pointer.y - innerHeight / 2) < 0.7 * data.textlength) {
chars.forEach(e => e.update())
} else { chars.forEach(e => e.render()) }
CHAR.draw();
}
setTimeout(run, 50);
#import url('https://fonts.googleapis.com/css?family=Oswald')
*
margin: 0
padding: 0
font-family: 'Oswald', sans-serif
body
overflow: hidden
canvas
filter: blur(1px)
<canvas>
I'm struggling to make whole text responsive, there is const size, It's not reacting to any css styling, so I guess there is need to adapt responsivness in script, but I don't know how adapt any ready solutions like for example this one: http://jsfiddle.net/xVB3t/2/ please help!

Something like this ?
function magicFunctionToGetSize() {
return parseInt(window.innerWidth/10);
}
const data = {
font: {
family: 'Oswald',
size: 70,
weight: 'bold'
},
colors: ['rgb(248, 225, 0)', 'rgb(232, 0, 137)', 'rgb(0, 170, 234)'],
text: `INTERACTIVE * DEVELOPER`,
textlength: 0
}
const canvas = {
elem: document.querySelector('canvas'),
init() {
return this.elem.getContext('2d')
},
resize() {
canvas.elem.width = innerWidth;
canvas.elem.height = innerHeight;
}
}
canvas.resize();
let ctx = canvas.init();
const pointer = {
x: innerWidth/2, y: innerHeight/2,
r: 220
}
class CHAR {
constructor(char, x, y, color, layer) {
this.char = char;
this.cx = x;
this.cy = y;
this.color = color;
this.layer = layer;
this.r = 0;
this.alpha = 0;
this.dx = this.cx;
this.dy = this.cy;
}
static measuretext(text) {
return ctx.measureText(text).width;
}
static dist(x1, y1, x2, y2) {
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
}
static getAngle(x1, y1, x2, y2) {
return Math.atan2(y2 - y1, x2 - x1);
}
static init(text, x, y) {
const fontSize = magicFunctionToGetSize();
ctx.font = `${data.font.weight} ${fontSize}px ${data.font.family}`;
ctx.textBaseline = 'middle';
ctx.globalCompositeOperation = 'darken';
for (let color = 0; color < data.colors.length; color++) {
let layer = 1;
switch (color) {
case 0:
layer = 0.5;
break;
case 1:
layer = 0.7;
break;
case 2:
layer = 1;
break;
}
const strs = text.split(' * ');
const textlength = strs.map(str => this.measuretext(str));
data.textlength = Math.max(...textlength);
const textheight = this.measuretext('M') * 1.5;
for (let i = 0; i < strs.length; i++) {
let ww = 0;
for (let j = 0; j < strs[i].length; j++) {
const xx = x - textlength[i] / 2 + ww;
const yy = i == 0 ? y - textheight / 2 : y + textheight / 2;
chars.push(new CHAR(strs[i][j], Math.round(xx), Math.round(yy), data.colors[color], layer));
ww += this.measuretext(strs[i][j]);
}
}
}
}
static draw() {
for (let i = 0; i < data.colors.length; i++) {
ctx.fillStyle = data.colors[i];
for (let j = 0; j < chars.length; j++) {
if (chars[j].color == data.colors[i]) {
ctx.fillText(chars[j].char, chars[j].dx, chars[j].dy);
}
}
}
}
render() {
this.dx += (this.cx - this.dx) * 0.2;
this.dy += (this.cy - this.dy) * 0.2;
}
update() {
const dis = CHAR.dist(pointer.x, pointer.y, this.cx, this.cy);
if (dis < pointer.r) {
this.alpha = CHAR.getAngle(pointer.x, pointer.y, this.cx, this.cy) + Math.PI;
this.r = this.layer * dis * (pointer.r - dis) / pointer.r;
this.dx += (this.cx + this.r * Math.cos(this.alpha) - this.dx) * 0.2;
this.dy += (this.cy + this.r * Math.sin(this.alpha) - this.dy) * 0.2;
} else {
this.render()
}
}
}
let chars = [];
CHAR.init(data.text, innerWidth / 2, innerHeight / 2);
setTimeout(() => {
chars = [];
CHAR.init(data.text, innerWidth / 2, innerHeight / 2);
}, 10);
window.addEventListener('mousemove', e => {
pointer.x = e.clientX; pointer.y = e.clientY;
})
window.addEventListener('touchmove', e => {
e.preventDefault();
pointer.x = e.targetTouches[0].clientX;
pointer.y = e.targetTouches[0].clientY;
})
window.addEventListener('resize', () => {
canvas.resize();
chars = [];
ctx = canvas.init();
CHAR.init(data.text, innerWidth / 2, innerHeight / 2);
})
const run = () => {
requestAnimationFrame(run);
ctx.clearRect(innerWidth / 2 - data.textlength, innerHeight / 2 - 0.7 * data.textlength, 2 * data.textlength, 1.4 * data.textlength);
if (Math.abs(pointer.x - innerWidth / 2) < data.textlength &&
Math.abs(pointer.y - innerHeight / 2) < 0.7 * data.textlength) {
chars.forEach(e => e.update())
} else { chars.forEach(e => e.render()) }
CHAR.draw();
}
setTimeout(run, 50);
#import url('https://fonts.googleapis.com/css?family=Oswald')
*
margin: 0
padding: 0
font-family: 'Oswald', sans-serif
body
overflow: hidden
canvas
filter: blur(1px)
<canvas>

Related

Javascript particles are clipping over the edges

I have this small particle script that I adjusted to my liking, but I have one problem.
Once the particles come to the edge, they get clipped a bit (maybe 10 - 15px), is there any padding attribute for canvas that I could use to give them a bit of space?
I've created snippet bellow to show what's the problem if anyone is interested to help out?
let resizeReset = function() {
w = canvasBody.width = 800;
h = canvasBody.height = 460;
}
const opts = {
particleColor: "rgb(200,200,200)",
lineColor: "rgb(200,200,200)",
particleAmount: 8,
defaultSpeed: 0.05,
variantSpeed: 1,
defaultRadius: 5,
variantRadius: 10,
linkRadius: 500,
};
window.addEventListener("resize", function(){
deBouncer();
});
let deBouncer = function() {
clearTimeout(tid);
tid = setTimeout(function() {
resizeReset();
}, delay);
};
let checkDistance = function(x1, y1, x2, y2){
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
};
let linkPoints = function(point1, hubs){
for (let i = 0; i < hubs.length; i++) {
let distance = checkDistance(point1.x, point1.y, hubs[i].x, hubs[i].y);
let opacity = 1 - distance / opts.linkRadius;
if (opacity > 0) {
drawArea.lineWidth = 0.5;
drawArea.strokeStyle = `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, ${opacity})`;
drawArea.beginPath();
drawArea.moveTo(point1.x, point1.y);
drawArea.lineTo(hubs[i].x, hubs[i].y);
drawArea.closePath();
drawArea.stroke();
}
}
}
Particle = function(xPos, yPos){
this.x = Math.random() * w;
this.y = Math.random() * h;
this.speed = opts.defaultSpeed + Math.random() * opts.variantSpeed;
this.directionAngle = Math.floor(Math.random() * 360);
this.color = opts.particleColor;
this.radius = opts.defaultRadius + Math.random() * opts. variantRadius;
this.vector = {
x: Math.cos(this.directionAngle) * this.speed,
y: Math.sin(this.directionAngle) * this.speed
};
this.update = function(){
this.border();
this.x += this.vector.x;
this.y += this.vector.y;
};
this.border = function(){
if (this.x >= w || this.x <= 0) {
this.vector.x *= -1;
}
if (this.y >= h || this.y <= 0) {
this.vector.y *= -1;
}
if (this.x > w) this.x = w;
if (this.y > h) this.y = h;
if (this.x < 0) this.x = 0;
if (this.y < 0) this.y = 0;
};
this.draw = function(){
drawArea.beginPath();
drawArea.arc(this.x, this.y, this.radius, 0, Math.PI*2);
drawArea.closePath();
drawArea.fillStyle = this.color;
drawArea.fill();
};
};
function setup(){
particles = [];
resizeReset();
for (let i = 0; i < opts.particleAmount; i++){
particles.push( new Particle() );
}
window.requestAnimationFrame(loop);
}
function loop(){
window.requestAnimationFrame(loop);
drawArea.clearRect(0,0,w,h);
for (let i = 0; i < particles.length; i++){
particles[i].update();
particles[i].draw();
}
for (let i = 0; i < particles.length; i++){
linkPoints(particles[i], particles);
}
}
const canvasBody = document.getElementById("canvas"),
drawArea = canvasBody.getContext("2d");
let delay = 200, tid,
rgb = opts.lineColor.match(/\d+/g);
resizeReset();
setup();
body {
background: #222;
margin: 0rem;
padding: 20px;
font-family: Futura, sans-serif;
display: flex;
justify-content: center;
}
#canvas {
// position: absolute;
display: block;
// top: 0;
// left: 0;
z-index: -1;
width: 80%;
}
<canvas id="canvas"></canvas>
Add the radius to the position on the edge detection
However I found a problem : if a circle start in an edge, it don't seems to move.
let resizeReset = function() {
w = canvasBody.width = 800;
h = canvasBody.height = 460;
}
const opts = {
particleColor: "rgb(200,200,200)",
lineColor: "rgb(200,200,200)",
particleAmount: 8,
defaultSpeed: 0.05,
variantSpeed: 1,
defaultRadius: 5,
variantRadius: 10,
linkRadius: 500,
};
window.addEventListener("resize", function(){
deBouncer();
});
let deBouncer = function() {
clearTimeout(tid);
tid = setTimeout(function() {
resizeReset();
}, delay);
};
let checkDistance = function(x1, y1, x2, y2){
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
};
let linkPoints = function(point1, hubs){
for (let i = 0; i < hubs.length; i++) {
let distance = checkDistance(point1.x, point1.y, hubs[i].x, hubs[i].y);
let opacity = 1 - distance / opts.linkRadius;
if (opacity > 0) {
drawArea.lineWidth = 0.5;
drawArea.strokeStyle = `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, ${opacity})`;
drawArea.beginPath();
drawArea.moveTo(point1.x, point1.y);
drawArea.lineTo(hubs[i].x, hubs[i].y);
drawArea.closePath();
drawArea.stroke();
}
}
}
Particle = function(xPos, yPos){
this.x = Math.random() * w;
this.y = Math.random() * h;
this.speed = opts.defaultSpeed + Math.random() * opts.variantSpeed;
this.directionAngle = Math.floor(Math.random() * 360);
this.color = opts.particleColor;
this.radius = opts.defaultRadius + Math.random() * opts. variantRadius;
this.vector = {
x: Math.cos(this.directionAngle) * this.speed,
y: Math.sin(this.directionAngle) * this.speed
};
this.update = function(){
this.border();
this.x += this.vector.x;
this.y += this.vector.y;
};
this.border = function(){
if (this.x + this.radius >= w || this.x - this.radius<= 0) { // Changes here
this.vector.x *= -1;
}
if (this.y + this.radius >= h || this.y - this.radius <= 0) { // And here
this.vector.y *= -1;
}
if (this.x > w) this.x = w;
if (this.y > h) this.y = h;
if (this.x < 0) this.x = 0;
if (this.y < 0) this.y = 0;
};
this.draw = function(){
drawArea.beginPath();
drawArea.arc(this.x, this.y, this.radius, 0, Math.PI*2);
drawArea.closePath();
drawArea.fillStyle = this.color;
drawArea.fill();
};
};
function setup(){
particles = [];
resizeReset();
for (let i = 0; i < opts.particleAmount; i++){
particles.push( new Particle() );
}
window.requestAnimationFrame(loop);
}
function loop(){
window.requestAnimationFrame(loop);
drawArea.clearRect(0,0,w,h);
for (let i = 0; i < particles.length; i++){
particles[i].update();
particles[i].draw();
}
for (let i = 0; i < particles.length; i++){
linkPoints(particles[i], particles);
}
}
const canvasBody = document.getElementById("canvas"),
drawArea = canvasBody.getContext("2d");
let delay = 200, tid,
rgb = opts.lineColor.match(/\d+/g);
resizeReset();
setup();
body {
background: #222;
margin: 0rem;
padding: 20px;
font-family: Futura, sans-serif;
display: flex;
justify-content: center;
}
#canvas {
// position: absolute;
display: block;
// top: 0;
// left: 0;
z-index: -1;
width: 80%;
background-color:white;
}
<canvas id="canvas"></canvas>

JS chart > data to outer space

I am using this chart, with the data in the original var oData it works fantastic. But when I add my values the cart is drawn anywhere but not is the chart it self. The strange thing is, when I change this original data the chart is updated correctly! Any suggestions?
Original data with no issues:
var oData = {
"2008": 10,
"2009": 39.9,
"2010": 17,
"2011": 30.0,
"2012": 5.3,
"2013": 38.4,
"2014": 15.7,
"2015": 9.0
};
When I change this data to there are no issues:
var oData = {
"2008": 100,
"2009": 390.9,
"2010": 170,
"2011": 300.0,
"2012": 50.3,
"2013": 380.4,
"2014": 150.7,
"2015": 90.0
};
My data:
var oData = {
"1220": 262,
"1120": 338,
"1020": 244,
"0920": 314,
"0820": 311,
"0720": 302,
"0620": 300,
"0520": 269,
"0420": 232,
"0320": 347
};
var label = document.querySelector(".label");
var c = document.getElementById("c");
var ctx = c.getContext("2d");
var cw = c.width = 700;
var ch = c.height = 350;
var cx = cw / 2,
cy = ch / 2;
var rad = Math.PI / 180;
var frames = 0;
ctx.lineWidth = 1;
ctx.strokeStyle = "#999";
ctx.fillStyle = "#ccc";
ctx.font = "14px monospace";
var grd = ctx.createLinearGradient(0, 0, 0, cy);
grd.addColorStop(0, "hsla(167,72%,60%,1)");
grd.addColorStop(1, "hsla(167,72%,60%,0)");
var oData = {
"2008": 10,
"2009": 39.9,
"2010": 17,
"2011": 30.0,
"2012": 5.3,
"2013": 38.4,
"2014": 15.7,
"2015": 9.0
};
var valuesRy = [];
var propsRy = [];
for (var prop in oData) {
valuesRy.push(oData[prop]);
propsRy.push(prop);
}
var vData = 4;
var hData = valuesRy.length;
var offset = 50.5; //offset chart axis
var chartHeight = ch - 2 * offset;
var chartWidth = cw - 2 * offset;
var t = 1 / 7; // curvature : 0 = no curvature
var speed = 2; // for the animation
var A = {
x: offset,
y: offset
}
var B = {
x: offset,
y: offset + chartHeight
}
var C = {
x: offset + chartWidth,
y: offset + chartHeight
}
/*
A ^
| |
+ 25
|
|
|
+ 25
|__|_________________________________ C
B
*/
// CHART AXIS -------------------------
ctx.beginPath();
ctx.moveTo(A.x, A.y);
ctx.lineTo(B.x, B.y);
ctx.lineTo(C.x, C.y);
ctx.stroke();
// vertical ( A - B )
var aStep = (chartHeight - 50) / (vData);
var Max = Math.ceil(arrayMax(valuesRy) / 10) * 10;
var Min = Math.floor(arrayMin(valuesRy) / 10) * 10;
var aStepValue = (Max - Min) / (vData);
console.log("aStepValue: " + aStepValue); //8 units
var verticalUnit = aStep / aStepValue;
var a = [];
ctx.textAlign = "right";
ctx.textBaseline = "middle";
for (var i = 0; i <= vData; i++) {
if (i == 0) {
a[i] = {
x: A.x,
y: A.y + 25,
val: Max
}
} else {
a[i] = {}
a[i].x = a[i - 1].x;
a[i].y = a[i - 1].y + aStep;
a[i].val = a[i - 1].val - aStepValue;
}
drawCoords(a[i], 3, 0);
}
//horizontal ( B - C )
var b = [];
ctx.textAlign = "center";
ctx.textBaseline = "hanging";
var bStep = chartWidth / (hData + 1);
for (var i = 0; i < hData; i++) {
if (i == 0) {
b[i] = {
x: B.x + bStep,
y: B.y,
val: propsRy[0]
};
} else {
b[i] = {}
b[i].x = b[i - 1].x + bStep;
b[i].y = b[i - 1].y;
b[i].val = propsRy[i]
}
drawCoords(b[i], 0, 3)
}
function drawCoords(o, offX, offY) {
ctx.beginPath();
ctx.moveTo(o.x - offX, o.y - offY);
ctx.lineTo(o.x + offX, o.y + offY);
ctx.stroke();
ctx.fillText(o.val, o.x - 2 * offX, o.y + 2 * offY);
}
//----------------------------------------------------------
// DATA
var oDots = [];
var oFlat = [];
var i = 0;
for (var prop in oData) {
oDots[i] = {}
oFlat[i] = {}
oDots[i].x = b[i].x;
oFlat[i].x = b[i].x;
oDots[i].y = b[i].y - oData[prop] * verticalUnit - 25;
oFlat[i].y = b[i].y - 25;
oDots[i].val = oData[b[i].val];
i++
}
///// Animation Chart ///////////////////////////
//var speed = 3;
function animateChart() {
requestId = window.requestAnimationFrame(animateChart);
frames += speed; //console.log(frames)
ctx.clearRect(60, 0, cw, ch - 60);
for (var i = 0; i < oFlat.length; i++) {
if (oFlat[i].y > oDots[i].y) {
oFlat[i].y -= speed;
}
}
drawCurve(oFlat);
for (var i = 0; i < oFlat.length; i++) {
ctx.fillText(oDots[i].val, oFlat[i].x, oFlat[i].y - 25);
ctx.beginPath();
ctx.arc(oFlat[i].x, oFlat[i].y, 3, 0, 2 * Math.PI);
ctx.fill();
}
if (frames >= Max * verticalUnit) {
window.cancelAnimationFrame(requestId);
}
}
requestId = window.requestAnimationFrame(animateChart);
/////// EVENTS //////////////////////
c.addEventListener("mousemove", function(e) {
label.innerHTML = "";
label.style.display = "none";
this.style.cursor = "default";
var m = oMousePos(this, e);
for (var i = 0; i < oDots.length; i++) {
output(m, i);
}
}, false);
function output(m, i) {
ctx.beginPath();
ctx.arc(oDots[i].x, oDots[i].y, 20, 0, 2 * Math.PI);
if (ctx.isPointInPath(m.x, m.y)) {
//console.log(i);
label.style.display = "block";
label.style.top = (m.y + 10) + "px";
label.style.left = (m.x + 10) + "px";
label.innerHTML = "<strong>" + propsRy[i] + "</strong>: " + valuesRy[i] + "%";
c.style.cursor = "pointer";
}
}
// CURVATURE
function controlPoints(p) {
// given the points array p calculate the control points
var pc = [];
for (var i = 1; i < p.length - 1; i++) {
var dx = p[i - 1].x - p[i + 1].x; // difference x
var dy = p[i - 1].y - p[i + 1].y; // difference y
// the first control point
var x1 = p[i].x - dx * t;
var y1 = p[i].y - dy * t;
var o1 = {
x: x1,
y: y1
};
// the second control point
var x2 = p[i].x + dx * t;
var y2 = p[i].y + dy * t;
var o2 = {
x: x2,
y: y2
};
// building the control points array
pc[i] = [];
pc[i].push(o1);
pc[i].push(o2);
}
return pc;
}
function drawCurve(p) {
var pc = controlPoints(p); // the control points array
ctx.beginPath();
//ctx.moveTo(p[0].x, B.y- 25);
ctx.lineTo(p[0].x, p[0].y);
// the first & the last curve are quadratic Bezier
// because I'm using push(), pc[i][1] comes before pc[i][0]
ctx.quadraticCurveTo(pc[1][1].x, pc[1][1].y, p[1].x, p[1].y);
if (p.length > 2) {
// central curves are cubic Bezier
for (var i = 1; i < p.length - 2; i++) {
ctx.bezierCurveTo(pc[i][0].x, pc[i][0].y, pc[i + 1][1].x, pc[i + 1][1].y, p[i + 1].x, p[i + 1].y);
}
// the first & the last curve are quadratic Bezier
var n = p.length - 1;
ctx.quadraticCurveTo(pc[n - 1][0].x, pc[n - 1][0].y, p[n].x, p[n].y);
}
//ctx.lineTo(p[p.length-1].x, B.y- 25);
ctx.stroke();
ctx.save();
ctx.fillStyle = grd;
ctx.fill();
ctx.restore();
}
function arrayMax(array) {
return Math.max.apply(Math, array);
};
function arrayMin(array) {
return Math.min.apply(Math, array);
};
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return { //objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}
body {
margin: 0;
overflow: hidden;
background: #152B39;
font-family: Courier, monospace;
font-size: 14px;
color:#ccc;
}
.wrapper {
display: block;
margin: 5em auto;
border: 1px solid #555;
width: 700px;
height: 350px;
position: relative;
}
p{text-align:center;}
.label {
height: 1em;
padding: .3em;
background: rgba(255, 255, 255, .8);
position: absolute;
display: none;
color:#333;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<canvas id='c'></canvas>
<div class="label">text</div>
</div>
<p>Please mouse over the dots</p>
var label = document.querySelector(".label");
var c = document.getElementById("c");
var ctx = c.getContext("2d");
var cw = c.width = 700;
var ch = c.height = 350;
var cx = cw / 2,
cy = ch / 2;
var rad = Math.PI / 180;
var frames = 0;
ctx.lineWidth = 1;
ctx.strokeStyle = "#999";
ctx.fillStyle = "#ccc";
ctx.font = "14px monospace";
var grd = ctx.createLinearGradient(0, 0, 0, cy);
grd.addColorStop(0, "hsla(167,72%,60%,1)");
grd.addColorStop(1, "hsla(167,72%,60%,0)");
var oData = {
"2008": 100,
"2009": 390.9,
"2010": 170,
"2011": 300.0,
"2012": 50.3,
"2013": 380.4,
"2014": 150.7,
"2015": 90.0
};
var valuesRy = [];
var propsRy = [];
for (var prop in oData) {
valuesRy.push(oData[prop]);
propsRy.push(prop);
}
var vData = 4;
var hData = valuesRy.length;
var offset = 50.5; //offset chart axis
var chartHeight = ch - 2 * offset;
var chartWidth = cw - 2 * offset;
var t = 1 / 7; // curvature : 0 = no curvature
var speed = 2; // for the animation
var A = {
x: offset,
y: offset
}
var B = {
x: offset,
y: offset + chartHeight
}
var C = {
x: offset + chartWidth,
y: offset + chartHeight
}
/*
A ^
| |
+ 25
|
|
|
+ 25
|__|_________________________________ C
B
*/
// CHART AXIS -------------------------
ctx.beginPath();
ctx.moveTo(A.x, A.y);
ctx.lineTo(B.x, B.y);
ctx.lineTo(C.x, C.y);
ctx.stroke();
// vertical ( A - B )
var aStep = (chartHeight - 50) / (vData);
var Max = Math.ceil(arrayMax(valuesRy) / 10) * 10;
var Min = Math.floor(arrayMin(valuesRy) / 10) * 10;
var aStepValue = (Max - Min) / (vData);
console.log("aStepValue: " + aStepValue); //8 units
var verticalUnit = aStep / aStepValue;
var a = [];
ctx.textAlign = "right";
ctx.textBaseline = "middle";
for (var i = 0; i <= vData; i++) {
if (i == 0) {
a[i] = {
x: A.x,
y: A.y + 25,
val: Max
}
} else {
a[i] = {}
a[i].x = a[i - 1].x;
a[i].y = a[i - 1].y + aStep;
a[i].val = a[i - 1].val - aStepValue;
}
drawCoords(a[i], 3, 0);
}
//horizontal ( B - C )
var b = [];
ctx.textAlign = "center";
ctx.textBaseline = "hanging";
var bStep = chartWidth / (hData + 1);
for (var i = 0; i < hData; i++) {
if (i == 0) {
b[i] = {
x: B.x + bStep,
y: B.y,
val: propsRy[0]
};
} else {
b[i] = {}
b[i].x = b[i - 1].x + bStep;
b[i].y = b[i - 1].y;
b[i].val = propsRy[i]
}
drawCoords(b[i], 0, 3)
}
function drawCoords(o, offX, offY) {
ctx.beginPath();
ctx.moveTo(o.x - offX, o.y - offY);
ctx.lineTo(o.x + offX, o.y + offY);
ctx.stroke();
ctx.fillText(o.val, o.x - 2 * offX, o.y + 2 * offY);
}
//----------------------------------------------------------
// DATA
var oDots = [];
var oFlat = [];
var i = 0;
for (var prop in oData) {
oDots[i] = {}
oFlat[i] = {}
oDots[i].x = b[i].x;
oFlat[i].x = b[i].x;
oDots[i].y = b[i].y - oData[prop] * verticalUnit - 25;
oFlat[i].y = b[i].y - 25;
oDots[i].val = oData[b[i].val];
i++
}
///// Animation Chart ///////////////////////////
//var speed = 3;
function animateChart() {
requestId = window.requestAnimationFrame(animateChart);
frames += speed; //console.log(frames)
ctx.clearRect(60, 0, cw, ch - 60);
for (var i = 0; i < oFlat.length; i++) {
if (oFlat[i].y > oDots[i].y) {
oFlat[i].y -= speed;
}
}
drawCurve(oFlat);
for (var i = 0; i < oFlat.length; i++) {
ctx.fillText(oDots[i].val, oFlat[i].x, oFlat[i].y - 25);
ctx.beginPath();
ctx.arc(oFlat[i].x, oFlat[i].y, 3, 0, 2 * Math.PI);
ctx.fill();
}
if (frames >= Max * verticalUnit) {
window.cancelAnimationFrame(requestId);
}
}
requestId = window.requestAnimationFrame(animateChart);
/////// EVENTS //////////////////////
c.addEventListener("mousemove", function(e) {
label.innerHTML = "";
label.style.display = "none";
this.style.cursor = "default";
var m = oMousePos(this, e);
for (var i = 0; i < oDots.length; i++) {
output(m, i);
}
}, false);
function output(m, i) {
ctx.beginPath();
ctx.arc(oDots[i].x, oDots[i].y, 20, 0, 2 * Math.PI);
if (ctx.isPointInPath(m.x, m.y)) {
//console.log(i);
label.style.display = "block";
label.style.top = (m.y + 10) + "px";
label.style.left = (m.x + 10) + "px";
label.innerHTML = "<strong>" + propsRy[i] + "</strong>: " + valuesRy[i] + "%";
c.style.cursor = "pointer";
}
}
// CURVATURE
function controlPoints(p) {
// given the points array p calculate the control points
var pc = [];
for (var i = 1; i < p.length - 1; i++) {
var dx = p[i - 1].x - p[i + 1].x; // difference x
var dy = p[i - 1].y - p[i + 1].y; // difference y
// the first control point
var x1 = p[i].x - dx * t;
var y1 = p[i].y - dy * t;
var o1 = {
x: x1,
y: y1
};
// the second control point
var x2 = p[i].x + dx * t;
var y2 = p[i].y + dy * t;
var o2 = {
x: x2,
y: y2
};
// building the control points array
pc[i] = [];
pc[i].push(o1);
pc[i].push(o2);
}
return pc;
}
function drawCurve(p) {
var pc = controlPoints(p); // the control points array
ctx.beginPath();
//ctx.moveTo(p[0].x, B.y- 25);
ctx.lineTo(p[0].x, p[0].y);
// the first & the last curve are quadratic Bezier
// because I'm using push(), pc[i][1] comes before pc[i][0]
ctx.quadraticCurveTo(pc[1][1].x, pc[1][1].y, p[1].x, p[1].y);
if (p.length > 2) {
// central curves are cubic Bezier
for (var i = 1; i < p.length - 2; i++) {
ctx.bezierCurveTo(pc[i][0].x, pc[i][0].y, pc[i + 1][1].x, pc[i + 1][1].y, p[i + 1].x, p[i + 1].y);
}
// the first & the last curve are quadratic Bezier
var n = p.length - 1;
ctx.quadraticCurveTo(pc[n - 1][0].x, pc[n - 1][0].y, p[n].x, p[n].y);
}
//ctx.lineTo(p[p.length-1].x, B.y- 25);
ctx.stroke();
ctx.save();
ctx.fillStyle = grd;
ctx.fill();
ctx.restore();
}
function arrayMax(array) {
return Math.max.apply(Math, array);
};
function arrayMin(array) {
return Math.min.apply(Math, array);
};
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return { //objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}
body {
margin: 0;
overflow: hidden;
background: #152B39;
font-family: Courier, monospace;
font-size: 14px;
color:#ccc;
}
.wrapper {
display: block;
margin: 5em auto;
border: 1px solid #555;
width: 700px;
height: 350px;
position: relative;
}
p{text-align:center;}
.label {
height: 1em;
padding: .3em;
background: rgba(255, 255, 255, .8);
position: absolute;
display: none;
color:#333;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<canvas id='c'></canvas>
<div class="label">text</div>
</div>
<p>Please mouse over the dots</p>
var label = document.querySelector(".label");
var c = document.getElementById("c");
var ctx = c.getContext("2d");
var cw = c.width = 700;
var ch = c.height = 350;
var cx = cw / 2,
cy = ch / 2;
var rad = Math.PI / 180;
var frames = 0;
ctx.lineWidth = 1;
ctx.strokeStyle = "#999";
ctx.fillStyle = "#ccc";
ctx.font = "14px monospace";
var grd = ctx.createLinearGradient(0, 0, 0, cy);
grd.addColorStop(0, "hsla(167,72%,60%,1)");
grd.addColorStop(1, "hsla(167,72%,60%,0)");
var oData = {
"1220": 262,
"1120": 338,
"1020": 244,
"0920": 314,
"0820": 311,
"0720": 302,
"0620": 300,
"0520": 269,
"0420": 232,
"0320": 347
};
var valuesRy = [];
var propsRy = [];
for (var prop in oData) {
valuesRy.push(oData[prop]);
propsRy.push(prop);
}
var vData = 4;
var hData = valuesRy.length;
var offset = 50.5; //offset chart axis
var chartHeight = ch - 2 * offset;
var chartWidth = cw - 2 * offset;
var t = 1 / 7; // curvature : 0 = no curvature
var speed = 2; // for the animation
var A = {
x: offset,
y: offset
}
var B = {
x: offset,
y: offset + chartHeight
}
var C = {
x: offset + chartWidth,
y: offset + chartHeight
}
/*
A ^
| |
+ 25
|
|
|
+ 25
|__|_________________________________ C
B
*/
// CHART AXIS -------------------------
ctx.beginPath();
ctx.moveTo(A.x, A.y);
ctx.lineTo(B.x, B.y);
ctx.lineTo(C.x, C.y);
ctx.stroke();
// vertical ( A - B )
var aStep = (chartHeight - 50) / (vData);
var Max = Math.ceil(arrayMax(valuesRy) / 10) * 10;
var Min = Math.floor(arrayMin(valuesRy) / 10) * 10;
var aStepValue = (Max - Min) / (vData);
console.log("aStepValue: " + aStepValue); //8 units
var verticalUnit = aStep / aStepValue;
var a = [];
ctx.textAlign = "right";
ctx.textBaseline = "middle";
for (var i = 0; i <= vData; i++) {
if (i == 0) {
a[i] = {
x: A.x,
y: A.y + 25,
val: Max
}
} else {
a[i] = {}
a[i].x = a[i - 1].x;
a[i].y = a[i - 1].y + aStep;
a[i].val = a[i - 1].val - aStepValue;
}
drawCoords(a[i], 3, 0);
}
//horizontal ( B - C )
var b = [];
ctx.textAlign = "center";
ctx.textBaseline = "hanging";
var bStep = chartWidth / (hData + 1);
for (var i = 0; i < hData; i++) {
if (i == 0) {
b[i] = {
x: B.x + bStep,
y: B.y,
val: propsRy[0]
};
} else {
b[i] = {}
b[i].x = b[i - 1].x + bStep;
b[i].y = b[i - 1].y;
b[i].val = propsRy[i]
}
drawCoords(b[i], 0, 3)
}
function drawCoords(o, offX, offY) {
ctx.beginPath();
ctx.moveTo(o.x - offX, o.y - offY);
ctx.lineTo(o.x + offX, o.y + offY);
ctx.stroke();
ctx.fillText(o.val, o.x - 2 * offX, o.y + 2 * offY);
}
//----------------------------------------------------------
// DATA
var oDots = [];
var oFlat = [];
var i = 0;
for (var prop in oData) {
oDots[i] = {}
oFlat[i] = {}
oDots[i].x = b[i].x;
oFlat[i].x = b[i].x;
oDots[i].y = b[i].y - oData[prop] * verticalUnit - 25;
oFlat[i].y = b[i].y - 25;
oDots[i].val = oData[b[i].val];
i++
}
///// Animation Chart ///////////////////////////
//var speed = 3;
function animateChart() {
requestId = window.requestAnimationFrame(animateChart);
frames += speed; //console.log(frames)
ctx.clearRect(60, 0, cw, ch - 60);
for (var i = 0; i < oFlat.length; i++) {
if (oFlat[i].y > oDots[i].y) {
oFlat[i].y -= speed;
}
}
drawCurve(oFlat);
for (var i = 0; i < oFlat.length; i++) {
ctx.fillText(oDots[i].val, oFlat[i].x, oFlat[i].y - 25);
ctx.beginPath();
ctx.arc(oFlat[i].x, oFlat[i].y, 3, 0, 2 * Math.PI);
ctx.fill();
}
if (frames >= Max * verticalUnit) {
window.cancelAnimationFrame(requestId);
}
}
requestId = window.requestAnimationFrame(animateChart);
/////// EVENTS //////////////////////
c.addEventListener("mousemove", function(e) {
label.innerHTML = "";
label.style.display = "none";
this.style.cursor = "default";
var m = oMousePos(this, e);
for (var i = 0; i < oDots.length; i++) {
output(m, i);
}
}, false);
function output(m, i) {
ctx.beginPath();
ctx.arc(oDots[i].x, oDots[i].y, 20, 0, 2 * Math.PI);
if (ctx.isPointInPath(m.x, m.y)) {
//console.log(i);
label.style.display = "block";
label.style.top = (m.y + 10) + "px";
label.style.left = (m.x + 10) + "px";
label.innerHTML = "<strong>" + propsRy[i] + "</strong>: " + valuesRy[i] + "%";
c.style.cursor = "pointer";
}
}
// CURVATURE
function controlPoints(p) {
// given the points array p calculate the control points
var pc = [];
for (var i = 1; i < p.length - 1; i++) {
var dx = p[i - 1].x - p[i + 1].x; // difference x
var dy = p[i - 1].y - p[i + 1].y; // difference y
// the first control point
var x1 = p[i].x - dx * t;
var y1 = p[i].y - dy * t;
var o1 = {
x: x1,
y: y1
};
// the second control point
var x2 = p[i].x + dx * t;
var y2 = p[i].y + dy * t;
var o2 = {
x: x2,
y: y2
};
// building the control points array
pc[i] = [];
pc[i].push(o1);
pc[i].push(o2);
}
return pc;
}
function drawCurve(p) {
var pc = controlPoints(p); // the control points array
ctx.beginPath();
//ctx.moveTo(p[0].x, B.y- 25);
ctx.lineTo(p[0].x, p[0].y);
// the first & the last curve are quadratic Bezier
// because I'm using push(), pc[i][1] comes before pc[i][0]
ctx.quadraticCurveTo(pc[1][1].x, pc[1][1].y, p[1].x, p[1].y);
if (p.length > 2) {
// central curves are cubic Bezier
for (var i = 1; i < p.length - 2; i++) {
ctx.bezierCurveTo(pc[i][0].x, pc[i][0].y, pc[i + 1][1].x, pc[i + 1][1].y, p[i + 1].x, p[i + 1].y);
}
// the first & the last curve are quadratic Bezier
var n = p.length - 1;
ctx.quadraticCurveTo(pc[n - 1][0].x, pc[n - 1][0].y, p[n].x, p[n].y);
}
//ctx.lineTo(p[p.length-1].x, B.y- 25);
ctx.stroke();
ctx.save();
ctx.fillStyle = grd;
ctx.fill();
ctx.restore();
}
function arrayMax(array) {
return Math.max.apply(Math, array);
};
function arrayMin(array) {
return Math.min.apply(Math, array);
};
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return { //objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}
body {
margin: 0;
overflow: hidden;
background: #152B39;
font-family: Courier, monospace;
font-size: 14px;
color:#ccc;
}
.wrapper {
display: block;
margin: 5em auto;
border: 1px solid #555;
width: 700px;
height: 350px;
position: relative;
}
p{text-align:center;}
.label {
height: 1em;
padding: .3em;
background: rgba(255, 255, 255, .8);
position: absolute;
display: none;
color:#333;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<canvas id='c'></canvas>
<div class="label">text</div>
</div>
<p>Please mouse over the dots</p>

Asteroid - Computer Space Mix Up in JavaScript

I've been making a coding project in which I simply create a 2 player shooter with asteroids. For some reason my asteroids occasionally disappear and I can't find a way to stop it. I tried some debugging strategies that i got off the internet. Forgive me for the messy code because I'm relatively new to coding and would love to have some help. This is my entire code -
const FPS = 60;
const FRICTION = 0.7;
const PROJ_DIST = 0.6;
const PROJ_EXPLODE_DUR = 0.3;
const PROJ_MAX = 3;
const PROJ_SPEED = 600;
const ROIDS_JAG = 0.4;
const ROIDS_NUM = 5;
const ROIDS_SPEED = 50;
const ROIDS_SIZE = 100;
const ROIDS_VERT = 10;
const PLAYER_SIZE = 30;
const ROT_SPEED = 250;
const PLAYER_THRUST = 5;
const PLAYER_MAX_SPEED = 12;
const SHOW_BOUNDING = false;
const SHOW_CENTER = false;
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
canvas.width = innerWidth;
canvas.height = innerHeight;
addEventListener("resize", () => {
canvas.width = innerWidth
canvas.height = innerHeight
})
class Player {
constructor(x, y, r, c, a, pc, p, scoreEl) {
this.x = x;
this.y = y;
this.or = r;
this.r = r;
this.p = p
this.c = c;
this.a = a
this.rot = 0
this.pc = pc
this.v = {
x: 0,
y: 0
}
this.thrusting = false
this.projectiles = []
this.destroy = []
this.top = {
x: this.x + 4 / 3 * this.r * Math.cos(this.a),
y: this.y - 4 / 3 * this.r * Math.sin(this.a)
}
this.left = {
x: this.x - this.r * (2 / 3 * Math.cos(this.a) + Math.sin(this.a)),
y: this.y + this.r * (2 / 3 * Math.sin(this.a) - Math.cos(this.a))
}
this.right = {
x: this.x - this.r * (2 / 3 * Math.cos(this.a) - Math.sin(this.a)),
y: this.y + this.r * (2 / 3 * Math.sin(this.a) + Math.cos(this.a))
}
this.thrustdir = 0
this.canShoot = false
this.scoreEl = scoreEl
this.score = 0
this.exploding = false;
}
draw() {
ctx.fillStyle = this.c
ctx.beginPath();
ctx.moveTo(this.top.x, this.top.y);
ctx.lineTo(this.left.x, this.left.y);
ctx.lineTo(this.right.x, this.right.y);
ctx.closePath();
ctx.fill();
}
update() {
this.setPoints();
this.move();
this.edge()
this.Update();
this.scoreEl.innerHTML = this.score
this.draw()
}
rotate(dir) {
this.rot = toRadians(ROT_SPEED * dir) / FPS
}
move() {
if (!this.exploding) {
if (this.thrusting) {
this.v.x += (Math.abs(this.v.x) < PLAYER_MAX_SPEED) ? PLAYER_THRUST * this.thrustdir * Math.cos(this.a) / FPS : 0;
this.v.y -= (Math.abs(this.v.y) < PLAYER_MAX_SPEED) ? PLAYER_THRUST * this.thrustdir * Math.sin(this.a) / FPS : 0;
} else {
this.v.x -= FRICTION * this.v.x / FPS
this.v.y -= FRICTION * this.v.y / FPS
}
this.a += this.rot
this.x += this.v.x
this.y += this.v.y
}
}
thrust(dir) {
this.thrustdir = dir;
this.thrusting = (dir == 0) ? false : true
}
edge() {
if (this.x < 0 - this.r) {
this.x = canvas.width + this.r
} else if (this.x > canvas.width + this.r) {
this.x = 0 - this.r
}
if (this.y < 0 - this.r) {
this.y = canvas.height + this.r
} else if (this.y > canvas.height + this.r) {
this.y = 0 - this.r
}
}
setPoints() {
this.top = {
x: this.x + 4 / 3 * this.r * Math.cos(this.a),
y: this.y - 4 / 3 * this.r * Math.sin(this.a)
}
this.left = {
x: this.x - this.r * (2 / 3 * Math.cos(this.a) + Math.sin(this.a)),
y: this.y + this.r * (2 / 3 * Math.sin(this.a) - Math.cos(this.a))
}
this.right = {
x: this.x - this.r * (2 / 3 * Math.cos(this.a) - Math.sin(this.a)),
y: this.y + this.r * (2 / 3 * Math.sin(this.a) + Math.cos(this.a))
}
}
Update() {
this.projectiles.forEach((projectile, index) => {
projectile.update();
if (projectile.kill()) {
this.projectiles.splice(index, 1)
}
asteroids.forEach((asteroid, index2) => {
this.explode(asteroid, projectile, false, () => {
asteroids.splice(index2, 1)
var radius = Math.random() * (ROIDS_SIZE - 4) + 4
if (Math.random() < 0.5) {
var x = Math.random() < 0.5 ? 0 - radius * 2 : canvas.width + radius * 2
var y = Math.random() * canvas.height
} else {
var x = Math.random() * canvas.width
var y = Math.random() < 0.5 ? 0 - radius * 2 : canvas.height + radius * 2
}
asteroids.push(new Asteroid(x, y, radius, {
x: Math.random() * ROIDS_SPEED / FPS * (Math.random() < 0.5 ? 1 : -1),
y: Math.random() * ROIDS_SPEED / FPS * (Math.random() < 0.5 ? 1 : -1)
}))
},
(asteroid) => {
if (!this.exploding) {
this.score += 5
}
this.projectiles.splice(index, 1)
if (asteroid.r > 35) {
gsap.to(asteroid, 0.5, {
r: asteroid.r - 30
}).then(asteroid.or = asteroid.r)
return false;
}
return true;
})
})
});
asteroids.forEach((asteroid, index) => {
this.explode(this, asteroid, true, () => {
this.respawn(this);
}, () => {
this.v = {
x: 0,
y: 0
}
})
})
this.projectiles.forEach((projectile, index) => {
this.explode(players[this.p == 0 ? 1 : 0], projectile, false, () => {
this.respawn(players[this.p == 0 ? 1 : 0]);
console.log("hit")
}, () => {
if (!players[this.p == 0 ? 1 : 0].exploding) {
this.score += 10
};
players[this.p == 0 ? 1 : 0].v = {
x: 0,
y: 0
};
this.projectiles.splice(index, 1);
return true
})
})
}
shoot() {
if (this.canShoot && this.projectiles.length < PROJ_MAX) {
this.projectiles.push(new Projectile(this.top.x, this.top.y, 5, this.pc, {
x: PROJ_SPEED * Math.cos(this.a) / FPS,
y: -PROJ_SPEED * Math.sin(this.a) / FPS,
}));
this.canShoot = false
}
}
respawn(object) {
if (object.exploding) {
object.v = {
x: 0,
y: 0
}
do {
var x = Math.random() < 0.5
var y = Math.random() < 0.5
object.x = x ? object.or * 2 : canvas.width - object.or * 2
object.y = y ? object.or * 4 : canvas.height - object.or * 2
} while (this.hitAsteroid(object.x, object.y))
object.a = this.getStartAngle(x, y)
gsap.to(object, {
r: object.or
})
object.exploding = false
}
}
explode(object1, object2, place, t = function() {}, f = function(object1 = null, object2 = null, object3 = null) {
return false
}) {
if (this.hit(object1, object2)) {
var x = place ? object1.x : object2.x
var y = place ? object1.y : object2.y
for (var i = 0; i < object1.r * 2; i++) {
particles.push(new Particle(x, y, Math.random() * 2, object1.c, {
x: (Math.random() - 0.5) * object1.r / 15,
y: (Math.random() - 0.5) * object1.r / 15
}))
}
if (f(object1, object2, this)) {
gsap.to(object1, 0.5, {
r: 0
}).then(t)
}
object1.exploding = true
}
}
hit(object1, object2) {
return Math.hypot(object2.x - object1.x, object2.y - object1.y) < object2.r + object1.r
}
hitAsteroid(x, y) {
asteroids.forEach((asteroid) => {
if (this.hit({x: x, y: y}, asteroid)) {
return true
}
})
return false;
}
getStartAngle(x, y) {
if (x && y) {
return toRadians(315)
} else if (x) {
return toRadians(45)
} else if (y) {
return toRadians(225)
} else {
return toRadians(135)
}
}
}
class Projectile {
constructor(x, y, r, c, v) {
this.x = x;
this.y = y;
this.r = r;
this.c = c;
this.v = v;
this.dist = 0
}
draw() {
ctx.fillStyle = this.c
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, false);
ctx.closePath();
ctx.fill();
}
update() {
this.x += this.v.x
this.y += this.v.y
this.dist += Math.hypot(this.v.x, this.v.y)
this.edge();
this.draw()
}
kill() {
return (this.dist > PROJ_DIST * canvas.width)
}
edge() {
if (this.x < 0 - this.r) {
this.x = canvas.width + this.r
} else if (this.x > canvas.width + this.r) {
this.x = 0 - this.r
}
if (this.y < 0 - this.r) {
this.y = canvas.height + this.r
} else if (this.y > canvas.height + this.r) {
this.y = 0 - this.r
}
}
}
class Asteroid {
constructor(x, y, r, v) {
this.x = x;
this.y = y;
this.r = r;
this.c = `hsl(${Math.random() * 360}, 50%, 50%)`;
this.v = v;
this.a = toRadians(Math.random() * 360);
this.vert = Math.floor(Math.random() * (ROIDS_VERT + 1) + ROIDS_VERT / 2);
this.offset = this.createOffset();
this.or = r;
}
draw() {
ctx.fillStyle = this.c
ctx.beginPath();
ctx.moveTo(
this.x + this.r * this.offset[0] * Math.cos(this.a),
this.y + this.r * this.offset[0] * Math.sin(this.a)
);
for (var j = 1; j < this.vert; j++) {
ctx.lineTo(
this.x + this.r * this.offset[j] * Math.cos(this.a + j * Math.PI * 2 / this.vert),
this.y + this.r * this.offset[j] * Math.sin(this.a + j * Math.PI * 2 / this.vert)
)
}
ctx.closePath();
ctx.fill();
}
update() {
this.x += this.v.x
this.y += this.v.y
this.edge()
this.draw()
}
edge() {
if (this.x < 0 - this.r) {
this.x = canvas.width + this.r
} else if (this.x > canvas.width + this.r) {
this.x = 0 - this.r
}
if (this.y < 0 - this.r) {
this.y = canvas.height + this.r
} else if (this.y > canvas.height + this.r) {
this.y = 0 - this.r
}
}
createOffset() {
var off = [];
for (var i = 0; i < this.vert; i++) {
off.push(Math.random() * ROIDS_JAG * 2 + 1 - ROIDS_JAG)
}
return off
}
hit(projectile) {
return (Math.hypot(projectile.x - this.x, projectile.y - this.y) < this.r + projectile.r)
}
}
class Particle {
constructor(x, y, r, c, v) {
this.x = x;
this.y = y;
this.r = r;
this.c = c;
this.v = v;
this.al = 1
}
draw() {
ctx.save()
ctx.globalAlpha = this.al
ctx.fillStyle = this.c
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, false);
ctx.closePath();
ctx.fill();
ctx.restore();
}
update() {
this.draw()
this.x += this.v.x
this.y += this.v.y
this.al -= 0.01
}
}
const player1 = new Player(canvas.width / 2, canvas.height / 2, PLAYER_SIZE / 2, "blue", toRadians(Math.random() * 360), "blue", 0, document.getElementById("score1"));
const player2 = new Player(canvas.width / 2, canvas.height / 2, PLAYER_SIZE / 2, "red", toRadians(Math.random() * 360), "red", 1, document.getElementById("score2"));
const asteroids = []
for (var i = 0; i < ROIDS_NUM; i++) {
var radius = Math.random() * (ROIDS_SIZE - 4) + 4
if (Math.random() < 0.5) {
var x = Math.random() < 0.5 ? 0 - radius : canvas.width + radius
var y = Math.random() * canvas.height
} else {
var x = Math.random() * canvas.width
var y = Math.random() < 0.5 ? 0 - radius : canvas.height + radius
}
asteroids.push(new Asteroid(x, y, radius, {
x: Math.random() * ROIDS_SPEED / FPS * (Math.random() < 0.5 ? 1 : -1),
y: Math.random() * ROIDS_SPEED / FPS * (Math.random() < 0.5 ? 1 : -1)
}))
}
const particles = []
const players = [player1, player2]
addEventListener("keydown", (event) => {
switch (event.keyCode) {
case 32:
player1.shoot()
break;
case 37:
player1.rotate(1)
break;
case 39:
player1.rotate(-1)
break;
case 38:
player1.thrust(1)
break;
case 40:
player1.thrust(-1)
break;
case 69:
player2.shoot()
break;
case 65:
player2.rotate(1)
break;
case 68:
player2.rotate(-1)
break;
case 87:
player2.thrust(1)
break;
case 83:
player2.thrust(-1)
break;
}
});
addEventListener("keyup", (event) => {
switch (event.keyCode) {
case 37:
case 39:
player1.rot = 0
break;
case 38:
case 40:
player1.thrust(0);
case 32:
player1.canShoot = true;
case 65:
case 68:
player2.rot = 0
break;
case 87:
case 83:
player2.thrust(0);
case 69:
player2.canShoot = true;
}
});
var animationId;
function animate() {
animationId = requestAnimationFrame(animate);
ctx.fillStyle = "rgba(0, 0, 0, 0.1)"
ctx.fillRect(0, 0, canvas.width, canvas.height);
asteroids.forEach((asteroid) => {
asteroid.update()
})
particles.forEach((particle, index) => {
if (particle.al <= 0) {
particles.splice(index, 1)
} else {
particle.update();
}
})
player1.update();
player2.update()
}
function toRadians(a) {
return a / 180 * Math.PI
}
animate();
body {
margin: 0;
height: 100vh;
width: 100vw;
}
.scores {
width: 100vw;
}
#score1 {
display: inline-flex;
flex: right;
}
#score2 {
position: absolute;
top: 0;
left: calc(100vw - 4rem);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="./tailwind.min.css">
<title>Asteroids</title>
</head>
<body>
<div class="flex scores w-full">
<div class="fixed text-white ml-4 mt-1 text-4xl text-left" id="score1">0</div>
<div class="fixed text-white ml-4 mt-1 text-4xl text-right" id="score2">0</div>
</div>
<canvas id="gameCanvas"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js" integrity="sha512-IQLehpLoVS4fNzl7IfH8Iowfm5+RiMGtHykgZJl9AWMgqx0AmJ6cRWcB+GaGVtIsnC4voMfm8f2vwtY+6oPjpQ==" crossorigin="anonymous"></script>
<script src="./game.js"></script>
</body>
</html>

Canavs is not drawing all the dots. Only one is showing up

In this script I’m trying to make a coordinate plane with two dots/circles. When I add the second dot in the code, it only shows the second one.
The part with the dots is this piece of code:
point(AX, AY, false, 'red', 6)
point(BX, BY, false, 'red', 6)
Can someone please help me with this problem? Thanks a lot!
start();
function start() {
console.clear();
document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var AX = document.getElementById("AX").value;
var AY = document.getElementById("AY").value;
var BX = document.getElementById("BX").value;
var BY = document.getElementById("BY").value;
var SQUARE_SIZE = 30;
var XSCALE = 1;
var YSCALE = 1;
var centerX = 0;
var centerY = 0;
selected = [];
points = [];
lines = [];
segments = [];
history = [];
circles = [];
function point(x, y, isSelected, color, r) {
this.x = x;
this.y = y;
this.color = color;
this.r = r;
this.add = function () {
plotPoint(this.x, this.y, this.color, this.r);
};
points.push(this);
if (isSelected) {
selected.push(this);
}
this.distance = function (gx, gy) {
return Math.sqrt(Math.pow(this.x - gx, 2) + Math.pow(this.y - gy, 2));
};
}
function point1(x, y, isSelected, color, r) {
this.x = x;
this.y = y;
this.color = color;
this.r = r;
this.add = function () {
plotPoint(this.x, this.y, this.color, this.r);
};
points.push(this);
if (isSelected) {
selected.push(this);
}
this.distance = function (gx, gy) {
return Math.sqrt(Math.pow(this.x - gx, 2) + Math.pow(this.y - gy, 2));
};
}
function circle(x, y, color, r) {
this.x = x;
this.y = y;
this.color = color;
this.r = r;
this.add = function () {
ctx.beginPath();
ctx.arc(convertX(x), convertY(y), r, 0, 2 * Math.PI);
ctx.stroke();
};
}
function line(m, b, color, width) {
this.m = m;
this.b = b;
this.color = color;
this.width = width;
lines.push(this);
}
function segment(a, b, color, width) {
this.a = a;
this.b = b;
this.color = color;
this.width = width;
this.getSlope = function () {
return (b.y - a.y) / (b.x - a.x);
};
this.getIntercept = function () {
var m = this.getSlope();
return a.y - m * a.x;
};
this.getLength = function () {
return Math.sqrt(this.a.x - this.b.x + this.a.y - this.b.y);
};
this.distance = function (gx, gy) {
//var m = (b.y-a.y)/(b.x-a.x)
//var bb = a.y-m*a.x
var m = this.getSlope();
var bb = this.getIntercept();
var pim = 1 / -m;
var pib = gy - pim * gx;
if (m === 0) {
pix = gx;
piy = this.a.y;
} else if (Math.abs(m) === Infinity) {
var pix = this.a.x;
var piy = gy;
} else {
var pix = (pib - bb) / (m - pim); //((gy-(gx/m)-bb)*m)/(m*m-1)
var piy = pim * pix + pib;
}
//console.log("m:"+m+" pim:"+pim+" pib:"+pib+" pix"+pix+" piy:"+piy)
if (
((this.a.x <= pix && pix <= this.b.x) ||
(this.b.x <= pix && pix <= this.a.x)) &&
((this.a.y <= piy && piy <= this.b.y) ||
(this.b.y <= piy && piy <= this.a.y))
) {
var d = Math.sqrt(Math.pow(gx - pix, 2) + Math.pow(gy - piy, 2));
return d;
} else {
var d = Math.min(this.a.distance(gx, gy), this.b.distance(gx, gy));
return d;
}
};
this.add = function () {
if (selected.indexOf(this) > -1) {
plotLine(this.a.x, this.a.y, this.b.x, this.b.y, color, width, [5, 2]);
} else {
plotLine(this.a.x, this.a.y, this.b.x, this.b.y, color, width);
}
};
segments.push(this);
}
// var a = new point(1,1)
// var b = new point(3,4)
// new segment(a,b)
//var testline = new line(1, 2, 'red', 1)
function drawLine(x1, y1, x2, y2, color, width, dash) {
ctx.save();
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.strokeStyle = color;
ctx.lineWidth = width;
if (dash !== undefined) {
ctx.setLineDash(dash);
}
ctx.stroke();
ctx.restore();
}
function convertX(x) {
return ((x - xmin - centerX) / (xmax - xmin)) * width;
}
function revertX(x) {
return (x * (xmax - xmin)) / width + centerX + xmin;
}
function convertY(y) {
return ((ymax - y - centerY) / (ymax - ymin)) * height;
}
function revertY(y) {
return (y * (ymin - ymax)) / height - centerY - ymin;
}
function addAxis() {
var TICK = 0;
for (
var i = Math.floor(xmin + centerX);
i <= Math.floor(xmax + centerX);
i += XSCALE
) {
drawLine(
convertX(i),
convertY(0) + TICK,
convertX(i),
convertY(0) - TICK
);
}
for (
var i = Math.floor(ymin - centerY);
i <= Math.floor(ymax - centerY);
i += YSCALE
) {
drawLine(
convertX(0) - TICK,
convertY(i),
convertX(0) + TICK,
convertY(i)
);
}
}
function addGrid() {
for (
var i = Math.floor(ymin - centerY);
i <= Math.floor(ymax - centerY);
i += YSCALE
) {
drawLine(0, convertY(i), width, convertY(i), "lightgrey", 1);
}
for (
var i = Math.floor(xmin + centerX);
i <= Math.floor(xmax + centerX);
i += XSCALE
) {
drawLine(convertX(i), height, convertX(i), 0, "lightgrey", 1);
}
}
function addPoints() {
for (const p of points) {
p.add();
}
}
function addCircles() {
for (const c of circles) {
c.add();
}
}
function addLines() {
for (const l of lines) {
plotLine(
xmin + centerX,
l.m * (xmin + centerX) + l.b,
xmax + centerX,
l.m * (xmax + centerX) + l.b,
l.color,
l.width
);
}
}
function addSegments() {
for (const s of segments) {
s.add();
}
}
function plotPoint(x, y, color, r) {
if (r === undefined) {
r = 2;
}
if (color === undefined) {
color = "black";
}
ctx.fillStyle = color;
ctx.beginPath();
ctx.arc(convertX(x), convertY(y), r, 0, 2 * Math.PI);
ctx.fill();
}
function plotCircle(x, y, color, r) {
if (r === undefined) {
r = 2;
}
if (color === undefined) {
color = "black";
}
ctx.beginPath();
ctx.arc(convertX(x), convertY(y), r, 0, 2 * Math.PI);
ctx.stroke();
}
function plotLine(x1, y1, x2, y2, color, width, dash) {
ctx.save();
ctx.beginPath();
ctx.moveTo(convertX(x1), convertY(y1));
ctx.lineTo(convertX(x2), convertY(y2));
ctx.strokeStyle = color;
ctx.lineWidth = width;
if (dash !== undefined) {
ctx.setLineDash(dash);
}
ctx.stroke();
ctx.restore();
}
function snap(x) {
if ((x - Math.round(x)) * (x - Math.round(x)) < 0.01) {
return Math.round(x);
} else {
return x;
}
}
function mouseDown(evt) {
x = evt.clientX;
y = evt.clientY;
ocx = centerX;
ocy = centerY;
if (evt.buttons === 2) {
for (const p of points) {
if (
nx * nx - 2 * convertX(p.x) * nx + convertX(p.x) * convertX(p.x) <
36 &&
ny * ny - 2 * convertY(p.y) * ny + convertY(p.y) * convertY(p.y) < 36
) {
s = new segment(p, new point(revertX(x), revertY(y), true));
selected.push(s);
return;
}
}
new point(snap(revertX(x)), snap(revertY(y)));
}
if (evt.buttons === 1) {
for (const p of points) {
if (p.distance(revertX(x), revertY(y)) < 0.2) {
selected.push(p);
}
console.log(p.distance(revertX(x), revertY(y)));
}
for (const s of segments) {
if (s.distance(revertX(x), revertY(y)) < 0.2) {
selected.push(s);
}
console.log(s.distance(revertX(x), revertY(y)));
}
}
onresize();
}
function mouseUp() {
selected = [];
}
function mouseMove(evt) {
console.clear();
nx = evt.clientX;
ny = evt.clientY;
gx = revertX(nx);
gy = revertY(ny);
if (evt.buttons === 1) {
if (selected.length > 0) {
for (const p of selected) {
p.x = snap(gx);
p.y = snap(gy);
}
} else {
centerX = (x - nx) / SQUARE_SIZE + ocx;
centerY = (y - ny) / SQUARE_SIZE + ocy;
}
}
if (evt.buttons === 2) {
for (const p of selected) {
p.x = snap(gx);
p.y = snap(gy);
}
}
console.log("coords: " + gx + ", " + gy);
console.log("points: " + points);
console.log("segments:" + segments);
console.log("selected: " + selected);
onresize();
}
function keyPress(evt) {
if ((evt.keyCode = 32)) {
//space
if (selected.length > 0) selected = [];
}
onresize();
}
point(AX, AY, false, "red", 6);
point(BX, BY, false, "red", 6);
window.onresize = function () {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
xmin = -width / SQUARE_SIZE / 2;
xmax = width / SQUARE_SIZE / 2;
ymin = -height / SQUARE_SIZE / 2;
ymax = height / SQUARE_SIZE / 2;
addGrid();
addAxis();
addPoints();
addLines();
addSegments();
addCircles();
ctx.font = "12px Arial";
ctx.fillStyle = "black";
ctx.fillText("Number of Points: " + points.length, 20, 30);
ctx.fillText("Points Slected: " + selected.length, 20, 50);
};
onresize();
}
<h2>LocusCreator v1.0 - © Niels Langerak</h2>
<p>Use the inputboxes to fill in all the info to make the locus.</p>
<p>Circle A - X:</p>
<input type="number" id="AX" value="0">
<p>Circle A - Y:</p>
<input type="number" id="AY" value="0">
<p>Circle B - X:</p>
<input type="number" id="BX" value="1">
<p>Circle B - Y:</p>
<input type="number" id="BY" value="1">
<button onclick="start()">Reload</button>
<canvas width=600px height=600px id='canvas'>
You should use the new keyword when creating your point:
new point(AX, AY, false, 'red', 6)
new point(BX, BY, false, 'red', 6)
It creates a new instance of point, but not overwrite it, as it works in your code.

html5-canvas background doesn't cover entire page

I'm currently using a canvas animation as the background of my new portfolio page. It works wonderfully until there's more content than can be displayed on a single page, but once you scroll down you'll find the canvas stops at the dimensions of the initial page display even though it's supposed to be the same size as the body element.
I apologize if this is a question that has been answered but I've been looking for a solution all morning and I'm coming up with nothing. Any help you can give is greatly appreciated.
My deployed page can be found here, and below is the JS.
Javascript:
var canvas,
ctx,
circ,
nodes,
mouse,
SENSITIVITY,
SIBLINGS_LIMIT,
DENSITY,
NODES_QTY,
ANCHOR_LENGTH,
MOUSE_RADIUS;
// how close next node must be to activate connection (in px)
// shorter distance == better connection (line width)
SENSITIVITY = 100;
// note that siblings limit is not 'accurate' as the node can actually have more connections than this value that's because the node accepts sibling nodes with no regard to their current connections this is acceptable because potential fix would not result in significant visual difference
// more siblings == bigger node
SIBLINGS_LIMIT = 10;
// default node margin
DENSITY = 50;
// total number of nodes used (incremented after creation)
NODES_QTY = 0;
// avoid nodes spreading
ANCHOR_LENGTH = 20;
// highlight radius
MOUSE_RADIUS = 200;
circ = 2 * Math.PI;
nodes = [];
canvas = document.querySelector("canvas");
resizeWindow();
mouse = {
x: canvas.width / 2,
y: canvas.height / 2
};
ctx = canvas.getContext("2d");
if (!ctx) {
alert("Ooops! Your browser does not support canvas :'(");
}
function Node(x, y) {
this.anchorX = x;
this.anchorY = y;
this.x = Math.random() * (x - (x - ANCHOR_LENGTH)) + (x - ANCHOR_LENGTH);
this.y = Math.random() * (y - (y - ANCHOR_LENGTH)) + (y - ANCHOR_LENGTH);
this.vx = Math.random() * 2 - 1;
this.vy = Math.random() * 2 - 1;
this.energy = Math.random() * 100;
this.radius = Math.random();
this.siblings = [];
this.brightness = 0;
}
Node.prototype.drawNode = function() {
var color = "rgba(216, 48, 168, " + this.brightness + ")";
ctx.beginPath();
ctx.arc(
this.x,
this.y,
2 * this.radius + (2 * this.siblings.length) / SIBLINGS_LIMIT,
0,
circ
);
ctx.fillStyle = color;
ctx.fill();
};
Node.prototype.drawConnections = function() {
for (var i = 0; i < this.siblings.length; i++) {
var color = "rgba(24, 168, 216, " + this.brightness + ")";
ctx.beginPath();
ctx.moveTo(this.x, this.y);
ctx.lineTo(this.siblings[i].x, this.siblings[i].y);
ctx.lineWidth = 1 - calcDistance(this, this.siblings[i]) / SENSITIVITY;
ctx.strokeStyle = color;
ctx.stroke();
}
};
Node.prototype.moveNode = function() {
this.enbergy -= 2;
if (this.energy < 1) {
this.energy = Math.random() * 100;
if (this.x - this.anchorX < -ANCHOR_LENGTH) {
this.vx = Math.random() * 2;
} else if (this.x - this.anchorX > ANCHOR_LENGTH) {
this.vx = Math.random() * -2;
} else {
this.vx = Math.random() * 4 - 2;
}
if (this.y - this.anchorY < -ANCHOR_LENGTH) {
this.vy = Math.random() * 2;
} else if (this.y - this.anchorY > ANCHOR_LENGTH) {
this.vy = Math.random() * -2;
} else {
this.vy = Math.random() * 4 - 2;
}
}
this.x += (this.vx * this.energy) / 100;
this.y += (this.vy * this.energy) / 100;
};
function initNodes() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
nodes = [];
for (var i = DENSITY; i < canvas.width; i += DENSITY) {
for (var j = DENSITY; j < canvas.height; j += DENSITY) {
nodes.push(new Node(i, j));
NODES_QTY++;
}
}
}
function calcDistance(node1, node2) {
return Math.sqrt(
Math.pow(node1.x - node2.x, 2) + Math.pow(node1.y - node2.y, 2)
);
}
function findSiblings() {
var node1, node2, distance;
for (var i = 0; i < NODES_QTY; i++) {
node1 = nodes[i];
node1.siblings = [];
for (var j = 0; j < NODES_QTY; j++) {
node2 = nodes[j];
if (node1 !== node2) {
distance = calcDistance(node1, node2);
if (distance < SENSITIVITY) {
if (node1.siblings.length < SIBLINGS_LIMIT) {
node1.siblings.push(node2);
} else {
var node_sibling_distance = 0;
var max_distance = 0;
var s;
for (var k = 0; k < SIBLINGS_LIMIT; k++) {
node_sibling_distance = calcDistance(node1, node1.siblings[k]);
if (node_sibling_distance > max_distance) {
max_distance = node_sibling_distance;
s = k;
}
}
if (distance < max_distance) {
node1.siblings.splice(s, 1);
node1.siblings.push(node2);
}
}
}
}
}
}
}
function redrawScene() {
resizeWindow();
ctx.clearRect(0, 0, canvas.width, canvas.height);
findSiblings();
var i, node, distance;
for (i = 0; i < NODES_QTY; i++) {
node = nodes[i];
distance = calcDistance(
{
x: mouse.x,
y: mouse.y
},
node
);
if (distance < MOUSE_RADIUS) {
node.brightness = 1 - distance / MOUSE_RADIUS;
} else {
node.brightness = 0;
}
}
for (i = 0; i < NODES_QTY; i++) {
node = nodes[i];
if (node.brightness) {
node.drawNode();
node.drawConnections();
}
node.moveNode();
}
requestAnimationFrame(redrawScene);
}
function initHandlers() {
document.addEventListener("resize", resizeWindow, false);
canvas.addEventListener("mousemove", mousemoveHandler, false);
}
function resizeWindow() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
function mousemoveHandler(e) {
mouse.x = e.clientX;
mouse.y = e.clientY;
}
initHandlers();
initNodes();
redrawScene();
})();
Set the canvas width property to document.body.scrollHeight, that's the full height of the document
Set the canvas height property to document.body.clientWidth, that's the full width of the document minus the scroll bar.
Change the height style of the canvas to fit-content or remove it. height: 100% will make it as high as the viewport.

Categories