I am having a problem with integrating a simple timer to a game I am trying to build for a practice exercise. I have attempted to search for this solution on the internet but my basic knowledge of .js leaves me stuck at this problem. Can anyone help me with a solution to this?
My codepen is located here: https://codepen.io/jankyvision/pen/PoqYEXV
var c = document.createElement("canvas");
var ctx = c.getContext("2d");
c.width = 720;
c.height = 480;
document.body.appendChild(c);
var perm = [];
while (perm.length < 255){
while(perm.includes(val = Math.floor(Math.random()*255)));
perm.push(val);
}
var lerp = (a,b,t) => a + (b-a) * (1-Math.cos(t*Math.PI))/2;
var noise = x=>{
x = x * 0.01 % 254;
return lerp(perm[Math.floor(x)], perm[Math.ceil(x)], x - Math.floor(x));
}
var Player = function(){
this.x = c.width/2;
this.y = 0;
this.ySpeed = 0;
this.rot = 0;
this.rSpeed = 0;
this.img = new Image();
this.img.src = "./images/moto.png";
this.draw = function(){
var p1 = c.height - noise(t + this.x) * 0.25;
var p2 = c.height - noise(t+5 + this.x) * 0.25;
var grounded = 0;
if(p1-12 > this.y){
this.ySpeed += 0.1;
}else{
this.ySpeed -= this.y - (p1-12);
this.y = p1 - 12;
grounded = 1;
}
var angle = Math.atan2((p2-12) - this.y, (this.x+5) - this.x);
this.y += this.ySpeed;
if(!playing || grounded && Math.abs(this.rot) > Math.PI * 0.5){
playing = false;
this.rSpeed = 5;
k.ArrowUp = 1;
this.x -= speed * 5;
}
if(grounded && playing){
this.rot -= (this.rot - angle) * 0.65;
this.rSpeed = this.rSpeed - (angle - this.rot);
}
this.rSpeed += (k.ArrowLeft - k.ArrowRight) * 0.05;
this.rot -= this.rSpeed * 0.1;
if(this.rot > Math.PI) this.rot = -Math.PI;
if(this.rot < -Math.PI) this.rot = Math.PI;
ctx.save();
ctx.translate(this.x, this.y - 3);
ctx.rotate(this.rot);
ctx.drawImage(this.img, -15, -15, 60, 30);
ctx.restore();
}
}
var player = new Player();
var t = 0;
var speed = 0;
var playing = true;
var k = {ArrowUp:0, ArrowDown:0, ArrowLeft:0, ArrowRight:0};
function loop(){
speed -= (speed - (k.ArrowUp - k.ArrowDown)) * 0.01;
t += 10 * speed;
ctx.fillStyle = "#8D5BC2";
ctx.fillRect(0,0,c.width, c.height);
ctx.fillStyle = "rgba(0,0,0,0.1)";
ctx.beginPath();
ctx.moveTo(0, c.height);
for (let i = 0; i < c.width; i++)
ctx.lineTo(i, c.height*0.8 - noise(t + i*5) * 0.25);
ctx.lineTo(c.width, c.height);
ctx.fill();
ctx.fillStyle = "#444";
ctx.beginPath();
ctx.moveTo(0, c.height);
for (let i = 0; i < c.width; i++)
ctx.lineTo(i, c.height - noise(t + i) * 0.25);
ctx.lineTo(c.width, c.height);
ctx.fill();
player.draw();
if(player.x < 0)
restart();
requestAnimationFrame(loop);
}
onkeydown = d=> k[d.key] = 1;
onkeyup = d=> k[d.key] = 0;
function restart(){
player = new Player();
t = 0;
speed = 0;
playing = true;
k = {ArrowUp:0, ArrowDown:0, ArrowLeft:0, ArrowRight:0};
}
loop();
var instructions = document.createElement("div");
instructions.innerHTML += "[up] [down] = accelerate <br> [Left] [Rigth] = rotate";
document.body.appendChild(instructions);
With some help from https://stackoverflow.com/a/16255190/1309377 you are looking at a pretty simple function that uses ctx.fillText() to draw the amount of elapsed seconds onto the canvas.
You want to use the Date() object when doing a timer as it is more accurate than setTimeout or setInterval.
On restart you just set startTime to the current time again.
var c = document.createElement("canvas");
var ctx = c.getContext("2d");
var startTime = new Date();
c.width = 720;
c.height = 480;
document.body.appendChild(c);
var perm = [];
while (perm.length < 255) {
while (perm.includes(val = Math.floor(Math.random() * 255)));
perm.push(val);
}
var lerp = (a, b, t) => a + (b - a) * (1 - Math.cos(t * Math.PI)) / 2;
var noise = x => {
x = x * 0.01 % 254;
return lerp(perm[Math.floor(x)], perm[Math.ceil(x)], x - Math.floor(x));
}
function drawElapsedTime() {
var elapsed = parseInt((new Date() - startTime) / 1000);
ctx.save();
ctx.beginPath();
ctx.fillStyle = "black";
ctx.font = "14px Verdana"
// draw the running time at half opacity
ctx.globalAlpha = 0.50;
ctx.fillText(elapsed + " seconds", 30,30);
ctx.restore();
}
var Player = function() {
this.x = c.width / 2;
this.y = 0;
this.ySpeed = 0;
this.rot = 0;
this.rSpeed = 0;
this.img = new Image();
this.img.src = "https://upload.wikimedia.org/wikipedia/en/3/3b/SpongeBob_SquarePants_character.svg";
this.draw = function() {
var p1 = c.height - noise(t + this.x) * 0.25;
var p2 = c.height - noise(t + 5 + this.x) * 0.25;
var grounded = 0;
if (p1 - 12 > this.y) {
this.ySpeed += 0.1;
} else {
this.ySpeed -= this.y - (p1 - 12);
this.y = p1 - 12;
grounded = 1;
}
var angle = Math.atan2((p2 - 12) - this.y, (this.x + 5) - this.x);
this.y += this.ySpeed;
if (!playing || grounded && Math.abs(this.rot) > Math.PI * 0.5) {
playing = false;
this.rSpeed = 5;
k.ArrowUp = 1;
this.x -= speed * 5;
}
if (grounded && playing) {
this.rot -= (this.rot - angle) * 0.65;
this.rSpeed = this.rSpeed - (angle - this.rot);
}
this.rSpeed += (k.ArrowLeft - k.ArrowRight) * 0.05;
this.rot -= this.rSpeed * 0.1;
if (this.rot > Math.PI) this.rot = -Math.PI;
if (this.rot < -Math.PI) this.rot = Math.PI;
ctx.save();
ctx.translate(this.x, this.y - 3);
ctx.rotate(this.rot);
ctx.drawImage(this.img, -15, -15, 60, 30);
ctx.restore();
}
}
var player = new Player();
var t = 0;
var speed = 0;
var playing = true;
var k = {
ArrowUp: 0,
ArrowDown: 0,
ArrowLeft: 0,
ArrowRight: 0
};
function loop() {
speed -= (speed - (k.ArrowUp - k.ArrowDown)) * 0.01;
t += 10 * speed;
ctx.fillStyle = "#8D5BC2";
ctx.fillRect(0, 0, c.width, c.height);
ctx.fillStyle = "rgba(0,0,0,0.1)";
ctx.beginPath();
ctx.moveTo(0, c.height);
for (let i = 0; i < c.width; i++)
ctx.lineTo(i, c.height * 0.8 - noise(t + i * 5) * 0.25);
ctx.lineTo(c.width, c.height);
ctx.fill();
ctx.fillStyle = "#444";
ctx.beginPath();
ctx.moveTo(0, c.height);
for (let i = 0; i < c.width; i++)
ctx.lineTo(i, c.height - noise(t + i) * 0.25);
ctx.lineTo(c.width, c.height);
ctx.fill();
player.draw();
drawElapsedTime();
if (player.x < 0)
restart();
requestAnimationFrame(loop);
}
onkeydown = d => k[d.key] = 1;
onkeyup = d => k[d.key] = 0;
function restart() {
player = new Player();
startTime = new Date();
t = 0;
speed = 0;
playing = true;
k = {
ArrowUp: 0,
ArrowDown: 0,
ArrowLeft: 0,
ArrowRight: 0
};
}
loop();
var instructions = document.createElement("div");
instructions.innerHTML += "[up] [down] = accelerate <br> [Left] [Rigth] = rotate";
document.body.appendChild(instructions);
var secs = 0;
setInterval(function(){secs++},1000);
this.draw = function(){
// Fill in a rectangle to put the time inside of
ctx.fillStyle="#000000";
ctx.fillRect(10,10,55,25);
ctx.fillStyle="#8D5BC2";
ctx.font = "12px";
// Format the number of seconds - 0:00
timestr = Math.floor(secs/60) + ":";
timestr += ((secs%60<10)&&"0") + secs%60;
// Write the time string over the rectangle
ctx.fillText(timestr,25,25);
Related
There is a falling balls code https://jsfiddle.net/d1e8x7wk/,
which is generated using canvas
Code also added to this editor
window.addEventListener('load', () => {
//---------------------------------------
// Set up ball options
//---------------------------------------
const imgBalls = [
'https://cdn.iconscout.com/icon/premium/png-256-thumb/basketball-2500972-2093649.png',
'https://cdn.iconscout.com/icon/premium/png-256-thumb/basketball-2500972-2093649.png',
'https://cdn.iconscout.com/icon/premium/png-256-thumb/basketball-2500972-2093649.png',
'https://cdn.iconscout.com/icon/premium/png-256-thumb/basketball-2500972-2093649.png',
'https://cdn.iconscout.com/icon/premium/png-256-thumb/basketball-2500972-2093649.png',
'https://cdn.iconscout.com/icon/premium/png-256-thumb/basketball-2500972-2093649.png'
]
let ballCount = imgBalls.length, // How many balls
DAMPING = 0.4, // Damping
GRAVITY = 0.01, // Gravity strength
SPEED = 5, // Ball speed
ballAdditionTime = 100, // How fast are balls added
ballSrc = imgBalls, // Ball image source
topOffset = 400, // Adjust this for initial ball spawn point
xOffset = 0, // left offset
yOffset = 0, // bottom offset
ballDensity = 20, // How dense are the balls
ball_1_size = 200, // Ball 1 size
ball_2_size = 180, // Ball 2 size
ball_3_size = 62, // Ball 6 size
canvasWidth = 1500, // Canvas width
canvasHeight = 1000, // Canvas height
stackBall = true, // Stack the balls (or false is overlap)
ballsLoaded = 0,
stopAnimation = false;
//---------------------------------------
// Canvas globals
//---------------------------------------
let canvas,
ctx,
TWO_PI = Math.PI * 2,
balls = [],
vel_x,
vel_y;
let rect = {
x: 0,
y: 0,
w: canvasWidth,
h: canvasHeight
};
//---------------------------------------
// do the animation
//---------------------------------------
window.requestAnimFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, ballAdditionTime);
};
//---------------------------------------
// set up the ball
//---------------------------------------
const Ball = function(x, y, radius, num) {
this.x = x;
this.y = y;
this.px = x;
this.py = y;
this.fx = 0;
this.fy = 0;
this.radius = radius;
this.num = num;
this.angle = 0;
// Different ball sizes
let random = Math.round(Math.random() * imgBalls.length)
if (random === 0) {
this.width = ball_1_size;
this.height = ball_1_size;
if (stackBall) {
this.radius = ball_1_size / 2;
}
} else if (random === 1 || random === 2) {
this.width = ball_2_size;
this.height = ball_2_size;
if (stackBall) {
this.radius = ball_2_size / 2;
}
} else {
this.width = ball_3_size;
this.height = ball_3_size;
if (stackBall) {
this.radius = ball_3_size / 2;
}
}
ctx.rotate(this.angle * Math.PI / 180);
};
//---------------------------------------
// Apply the physics
//---------------------------------------
Ball.prototype.apply_force = function(delta) {
delta *= delta;
this.fy += GRAVITY;
this.x += this.fx * delta;
this.y += this.fy * delta;
this.fx = this.fy = 0;
};
//---------------------------------------
// Newtonian motion algorithm
//---------------------------------------
Ball.prototype.velocity = function() {
var nx = this.x * 2 - this.px;
var ny = this.y * 2 - this.py;
this.px = this.x;
this.py = this.y;
this.x = nx;
this.y = ny;
};
//---------------------------------------
// Ball prototype
//---------------------------------------
Ball.prototype.draw = function(ctx) {
img = new Image();
img.src = imgBalls[this.num];
if (stackBall) {
ctx.drawImage(
img,
this.x - this.radius - xOffset,
this.y - this.radius - xOffset,
this.width,
this.height
);
} else {
ctx.drawImage(
img,
this.x - xOffset,
this.y - yOffset,
this.width,
this.height
);
}
};
//---------------------------------------
// resolve collisions (ball on ball)
//---------------------------------------
let resolve_collisions = function(ip) {
let i = balls.length;
while (i--) {
let ball_1 = balls[i];
let n = balls.length;
while (n--) {
if (n == i) continue;
let ball_2 = balls[n];
let diff_x = ball_1.x - ball_2.x;
let diff_y = ball_1.y - ball_2.y;
let length = diff_x * diff_x + diff_y * diff_y;
let dist = Math.sqrt(length);
let real_dist = dist - (ball_1.radius + ball_2.radius);
if (real_dist < 0) {
let vel_x1 = ball_1.x - ball_1.px;
let vel_y1 = ball_1.y - ball_1.py;
let vel_x2 = ball_2.x - ball_2.px;
let vel_y2 = ball_2.y - ball_2.py;
let depth_x = diff_x * (real_dist / dist);
let depth_y = diff_y * (real_dist / dist);
ball_1.x -= depth_x * 0.5;
ball_1.y -= depth_y * 0.5;
ball_2.x += depth_x * 0.5;
ball_2.y += depth_y * 0.5;
if (ip) {
let pr1 = (DAMPING * (diff_x * vel_x1 + diff_y * vel_y1)) / length;
let pr2 = (DAMPING * (diff_x * vel_x2 + diff_y * vel_y2)) / length;
vel_x1 += pr2 * diff_x - pr1 * diff_x;
vel_x2 += pr1 * diff_x - pr2 * diff_x;
vel_y1 += pr2 * diff_y - pr1 * diff_y;
vel_y2 += pr1 * diff_y - pr2 * diff_y;
ball_1.px = ball_1.x - vel_x1;
ball_1.py = ball_1.y - vel_y1;
ball_2.px = ball_2.x - vel_x2;
ball_2.py = ball_2.y - vel_y2;
}
}
}
}
};
//---------------------------------------
// Bounce off the walls
//---------------------------------------
let check_walls = function() {
let i = balls.length;
while (i--) {
let ball = balls[i];
if (ball.x < ball.radius) {
let vel_x = ball.px - ball.x;
ball.x = ball.radius;
ball.px = ball.x - vel_x * DAMPING;
} else if (ball.x + ball.radius > canvas.width) {
vel_x = ball.px - ball.x;
ball.x = canvas.width - ball.radius;
ball.px = ball.x - vel_x * DAMPING;
}
// Ball is new. So don't do collision detection until it hits the canvas. (with an offset to stop it snapping)
if (ball.y > 100) {
if (ball.y < ball.radius) {
let vel_y = ball.py - ball.y;
ball.y = ball.radius;
ball.py = ball.y - vel_y * DAMPING;
} else if (ball.y + ball.radius > canvas.height) {
vel_y = ball.py - ball.y;
ball.y = canvas.height - ball.radius;
ball.py = ball.y - vel_y * DAMPING;
}
}
}
};
//---------------------------------------
// Add a ball to the canvas
//---------------------------------------
let add_ball = function(num) {
let x = Math.random() * canvas.width;
let y = Math.random() * canvas.height;
let r = 30 + Math.random() * ballDensity;
let diff_x = x;
let diff_y = y;
let dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y);
balls.push(new Ball(x, y, r, num));
};
//---------------------------------------
// iterate balls
//---------------------------------------
let update = function() {
let iter = 1;
let delta = SPEED / iter;
while (iter--) {
let i = balls.length;
while (i--) {
balls[i].apply_force(delta);
balls[i].velocity();
}
resolve_collisions();
check_walls();
i = balls.length;
while (i--) {
balls[i].velocity();
let ball = balls[i];
}
resolve_collisions();
check_walls();
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
i = balls.length;
while (i--) {
balls[i].draw(ctx);
}
requestAnimFrame(update);
};
//---------------------------------------
// Set up the canvas object
//---------------------------------------
function doBalls() {
stopAnimation = false;
canvas = document.getElementById("balls");
ctx = canvas.getContext("2d");
let $canvasDiv = document.querySelector(".section");
function respondCanvas() {
canvas.height = $canvasDiv.clientHeight;
canvas.width = $canvasDiv.clientWidth;
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
respondCanvas();
ballAdd();
}
function ballAdd() {
let count = 0;
let timer = setInterval(function() {
addBallTimer();
}, 100);
let addBallTimer = function() {
add_ball(count % ballCount);
count++;
if (count === ballCount) {
stopTimer();
}
};
let stopTimer = function() {
clearInterval(timer);
};
update();
}
doBalls();
});
.section {
position: relative;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: #000;
}
<div class="section">
<canvas id="balls"></canvas>
</div>
I'm trying to make a rotation the balls
const Ball = function(x, y, radius, num) {
this.x = x;
this.y = y;
this.px = x;
this.py = y;
this.fx = 0;
this.fy = 0;
this.radius = radius;
this.num = num;
this.angle = 0;
// Different ball sizes
let random = Math.round(Math.random() * imgBalls.length)
if (random === 0) {
this.width = ball_1_size;
this.height = ball_1_size;
if (stackBall) {
this.radius = ball_1_size / 2;
}
} else if (random === 1 || random === 2) {
this.width = ball_2_size;
this.height = ball_2_size;
if (stackBall) {
this.radius = ball_2_size / 2;
}
} else {
this.width = ball_3_size;
this.height = ball_3_size;
if (stackBall) {
this.radius = ball_3_size / 2;
}
}
ctx.rotate(this.angle * Math.PI / 180);
};
After reading the information,
I wrote this code, but it does not work for me
ctx.rotate(this.angle * Math.PI / 180);
I must have misunderstood how to do this, tell me how to properly rotate the balls
Thanks in advance
You will need to
increase the angle at some point in your code
apply a rotation transform to rotate around each ball center before each drawImage call
ctx.save();
ctx.translate(+this.x, +this.y);
ctx.rotate(this.angle++ * Math.PI / 180);
ctx.translate(-this.x, -this.y);
ctx.drawImage
ctx.restore()
ctx.save() and ctx.restore() is called to restore the canvas transform after each draw call.
Please read
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/rotate#rotating_a_shape_around_its_center
for details on applying transforms to Canvas.
I'm struggling with the implementation of a text particle in javascript.
My code is working fine with chromium-based browsers (Chromium: 84) but is unexpectedly slow on firefox (79.0).
I've searched a lot, but still don't find a solution and where the problem is.(This is pretty much linked to this Javascript Animation(Canvas) not working in firefox, Edge but works on Chrome).
Here is my codepen:
https://codepen.io/jgazeau/pen/LYNYPYB
function getRandomInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}
function getCssVar(v) {
return getComputedStyle(document.documentElement).getPropertyValue(v);
}
let text404 = '404';
let canvas = document.getElementById('scene');
let ch = canvas.height = canvas.getBoundingClientRect().height;
let cw = canvas.width = canvas.getBoundingClientRect().width;
let sceneBackground = getCssVar('--scene-background');
let context = canvas.getContext('2d');
let previousMouseCoord = {x:0, y:0};
let mouseCoord = {x:0, y:0};
let sceneResize = false;
let particlesCount = 0;
let particles = [];
let colors = [
getCssVar('--particle-color-1'),
getCssVar('--particle-color-2'),
getCssVar('--particle-color-3'),
getCssVar('--particle-color-4'),
getCssVar('--particle-color-5')
];
const dpi = 200;
let Particle = function(x, y) {
this.x = getRandomInt(cw);
this.y = getRandomInt(ch);
this.coord = {x:x, y:y};
this.r = Math.min((getRandomInt((cw / dpi)) + 1), 6);
this.vx = (Math.random() - 0.5) * 100;
this.vy = (Math.random() - 0.5) * 100;
this.accX = 0;
this.accY = 0;
this.friction = Math.random() * 0.05 + 0.90;
this.color = colors[Math.floor(Math.random() * 6)];
}
Particle.prototype.render = function(isDisableMouse) {
this.accX = (this.coord.x - this.x) / 100;
this.accY = (this.coord.y - this.y) / 100;
this.vx += this.accX;
this.vy += this.accY;
this.vx *= this.friction;
this.vy *= this.friction;
this.x += this.vx;
this.y += this.vy;
if (!isDisableMouse) {
let a = this.x - mouseCoord.x;
let b = this.y - mouseCoord.y;
var distance = Math.sqrt(a * a + b * b);
if(distance < (cw / 15)) {
this.accX = (this.x - mouseCoord.x) / 100;
this.accY = (this.y - mouseCoord.y) / 100;
this.vx += this.accX;
this.vy += this.accY;
}
}
context.fillStyle = this.color;
context.beginPath();
context.arc(this.x, this.y, this.r, 0, Math.PI * 2, false);
context.fill();
context.closePath();
}
function onmouseCoordMove(e) {
mouseCoord.x = e.clientX;
mouseCoord.y = e.clientY;
}
function onTouchMove(e) {
if(e.touches.length > 0 ) {
mouseCoord.x = e.touches[0].clientX;
mouseCoord.y = e.touches[0].clientY;
}
}
function onTouchEnd() {
mouseCoord.x = -9999;
mouseCoord.y = -9999;
}
function initScene() {
ch = canvas.height = canvas.getBoundingClientRect().height;
cw = canvas.width = canvas.getBoundingClientRect().width;
context.clearRect(0, 0, canvas.width, canvas.height);
context.font = 'bold ' + (cw / 5) + 'px sans-serif';
context.fillStyle = sceneBackground;
context.textAlign = 'center';
context.fillText(text404, cw / 2, ch / 2);
let imageData = context.getImageData(0, 0, cw, ch).data;
context.clearRect(0, 0, canvas.width, canvas.height);
context.globalCompositeOperation = 'screen';
particles = [];
for(let y = 0; y < ch; y += Math.round(cw / dpi)) {
for(let x = 0; x < cw; x += Math.round(cw / dpi)) {
if(imageData[((x + y * cw) * 4) + 3] > 128){
particles.push(new Particle(x, y));
}
}
}
particlesCount = particles.length;
}
function renderScene() {
context.clearRect(0, 0, canvas.width, canvas.height);
let isDisableMouse = false;
if ((previousMouseCoord.x === mouseCoord.x) && (previousMouseCoord.x === mouseCoord.x)) {
isDisableMouse = true;
} else {
previousMouseCoord.x = mouseCoord.x;
previousMouseCoord.x = mouseCoord.x;
isDisableMouse = false;
}
for (let i = 0; i < particlesCount; i++) {
particles[i].render(isDisableMouse);
}
requestAnimationFrame(renderScene);
};
document.addEventListener('DOMContentLoaded', function() {
initScene();
renderScene();
window.addEventListener('mousemove', onmouseCoordMove);
window.addEventListener('touchmove', onTouchMove);
window.addEventListener('touchend', onTouchEnd);
window.addEventListener('resize', function() {
if (!sceneResize) {
requestAnimationFrame(function() {
initScene();
sceneResize = false;
});
sceneResize = true;
}
});
});
Can anyone know where this slow issue could come from ?
Thanks a lot for your help.
This is a code from codepen. I am trying to work on this one. This code works on chrome but does not work in firefox or edge. I tried to solve the issue but could not fix it. Is the problem with requestAnimationFrame or something else? Can anyone please help? Here is the codepen link: https://codepen.io/iremlopsum/pen/MKNaxd
var canvas = document.querySelector("#scene"),
ctx = canvas.getContext("2d"),
particles = [],
amount = 0,
mouse = {
x: 0,
y: 0
},
radius = 0.7; //Init radius of the force field
var colors = ["rgba(255,255,255, .6)", "rgba(255,255,255, .6)", "rgba(255,255,255, .6)", "rgba(255,255,255, .6)", "rgba(255,255,255, .6)", "rgba(255,255,255, .6)"];
var colorsTwo = ["rgba(255,255,255, .6)", "rgba(255,255,255, .6)", "rgba(255,255,255, .6)", "rgba(255,255,255, .6)", "rgba(255,255,255, .6)", "rgba(255,255,255, .6)"];
var copy = "Mighty Byte"; // Text to display
var initSize = Math.floor(Math.random() * .6) + 1 ;
var hoverSize = initSize + .7;
var ww = canvas.width = window.innerWidth;
var wh = canvas.height = window.innerHeight;
function Particle(x, y) {
this.x = Math.random() * ww;
this.y = Math.random() * wh;
this.dest = {
x: x,
y: y
};
//this.r = Math.random() * 1; // the size of bubbles
this.vx = (Math.random() - 0.5) * 2;
this.vy = (Math.random() - 0.5) * 2;
this.accX = 0;
this.accY = 0;
this.friction = Math.random() * 0.015 + 0.94; // force of bounce, just try to change 0.015 to 0.5
//this.color = colors[Math.floor(Math.random() * 10)];
//this.colorTwo = colorsTwo[Math.floor(Math.random() * 10)];
}
Particle.prototype.render = function() {
this.accX = (this.dest.x - this.x) / 200; //acceleration for X
this.accY = (this.dest.y - this.y) / 200; //acceleration for Y
this.vx += this.accX;
this.vy += this.accY;
this.vx *= this.friction;
this.vy *= this.friction;
this.x += this.vx;
this.y += this.vy;
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, Math.PI * 2, false);
ctx.fill();
var a = this.x - mouse.x;
var b = this.y - mouse.y;
var distance = Math.sqrt(a * a + b * b);
if (distance < (radius * 70)) {
this.accX = (this.x - mouse.x) / 20; //acceleration on mouseover X, smaller faster
this.accY = (this.y - mouse.y) / 20; //acceleration on mouseover Y, smaller faster
this.vx += this.accX;
this.vy += this.accY;
//ctx.fillStyle = this.colorTwo;
}
if (distance < (radius * 70)) {
this.colorTwo = colorsTwo[Math.floor(Math.random() * 10)];
ctx.fillStyle = this.colorTwo;
this.r = hoverSize; // the size of bubbles
}
if (distance > (radius * 70)) {
this.colorOne = colors[Math.floor(Math.random() * 10)];
ctx.fillStyle = this.colorOne;
this.r = initSize
}
}
function onMouseMove(e) {
mouse.x = e.clientX;
mouse.y = e.clientY;
}
function initScene() {
ww = canvas.width = window.innerWidth;
wh = canvas.height = window.innerHeight;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.font = "bold " + (ww / 10) + "px sans-serif"; // Size of the text
ctx.textAlign = "center";
ctx.fillText(copy, ww / 2, wh / 2); //Centering
var data = ctx.getImageData(0, 0, ww, wh).data;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = "screen";
particles = [];
for (var i = 0; i < ww; i += Math.round(ww / 400)) { //400 here represents the amount of particles
for (var j = 0; j < wh; j += Math.round(ww / 400)) {
if (data[((i + j * ww) * 4) + 3] > 250) {
particles.push(new Particle(i, j));
}
}
}
amount = particles.length;
}
function onMouseClick() {
radius = 4; //onclick expand radius
}
function offMouseClick() {
radius = 0.5; //offClick init radius
}
function delayedInitRadius() {
setTimeout(offMouseClick, 500); //delay for offClick init radius
}
function render(a) {
requestAnimationFrame(render);
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < amount; i++) {
particles[i].render();
}
};
window.addEventListener("resize", initScene);
window.addEventListener("mousemove", onMouseMove);
window.addEventListener("mousedown", onMouseClick);
window.addEventListener("mouseup", delayedInitRadius);
initScene();
requestAnimationFrame(render);
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I new to JavaScript, learn from w3school and codepen.io. The script not run, need some explanation, thanks
var drops = [];
var raindropSize = 1;
var droplets = 3000;
var maxDrops = 3000;
var thue;
var flig = 0;
var thickness = 9;
var tx;
var ty = 10;
var loc = 0;
var direct = -1;
var trail = 0.1;
var fade = 1;
var ms;
var distancy;
var mob = 0;
var xp = 1;
var yp = 1;
function setup() {
//smooth();
noStroke();
colorMode(HSB, 360, 100, 50, 1);
createCanvas(window.innerWidth, window.innerHeight);
if (window.innerWidth < 801) mob = 1;
if (mob == 1) droplets = droplets / 12;
tx = random(-3, 3);
for (var i = 0; i < droplets; i++) {
var x = round((random(width / raindropSize)) * raindropSize);
var y = round(random(height / raindropSize)) * raindropSize - window.innerHeight;
var r = raindropSize;
var h = map(x, 0, width, 0, 360); //(0, 360);
var s = random(1, 19); //trail = random(0.26, .7);
thue = h;
distancey = random(100, window.innerHeight);
tswell = ((distancey / window.innerHeight) * 25) * s / 2;
drops[i] = new RainDrop(x, y, r, h, s, tswell, distancey);
}
}
function draw() {
//text(trail, 100, 100);
var spot = 0;
var lig = random(0, 5);
if (lig > 4.9) {
flig = 100;
thickness = round(random(1, 19));
lightening();
}
background(200, 100, flig, trail);
if (flig == 100) flig = 0;
for (var i = 0; i < droplets; i++) {
drops[i].move();
drops[i].display();
}
}
function RainDrop(tempX, tempY, tempDiameter, tempHue, tempSpeed, tswell, tdistance) {
colorMode(HSB, 360, 100, 50, 1);
this.x = tempX;
this.loc = tempX;
this.y = tempY;
this.spot = 0;
this.diameter = tempDiameter;
this.h = tempHue;
this.s = tempSpeed;
this.swell = tswell;
this.distancey = tdistance;
this.move = function() {
//var ty = this.s;
this.x += (tx * raindropSize);
if (this.y < tdistance) this.y += tempSpeed;
if (this.x > width) {
this.loc = this.x;
this.x = this.x - window.innerWidth;
}
if (this.x < -20) this.x = width;
// fill(255);
// text(this.y, 100, 100);
// noFill();}
if (this.y > tdistance) {
this.y = tdistance - raindropSize;
this.spot = 1;
this.x -= (tx * raindropSize);
var fd = this.swell / tswell;
//var puddle = map(tswell, 0, tdistance, 1, 20);
strokeWeight(raindropSize / 3);
stroke(this.h, 100, 50, fd);
noFill();
ellipse(this.x + 1, tdistance, this.swell / 3, this.swell / 15);
//console.log(this.h);
this.swell -= 5;
}
if (this.swell < 4) {
this.swell = tswell;
this.y = random(-window.innerHeight, 0);
this.spot = 0;
this.distancey = tdistance;
}
// this.f += 2;
//this.y -= (tempSpeed);
//if (this.f > 9) {this.y = 0; this.f = 0; }
//direct = direct * -1; }
//round(random(height / raindropSize)) * (raindropSize - height);
this.display = function() {
if (this.spot == 0) {
noStroke();
fill(tempHue, 100, 50, fd);
rect(this.x, this.y, this.diameter, this.diameter);
}
};
}
}
function mousePressed() {
colorMode(HSB, 360, 100, 50, 0.8);
raindropSize = random(0.25, 3.5);
droplets = round(random(10, 3050));
if (mob == 1) droplets = droplets / 12;
tx *= -1;
for (var i = droplets; i < maxDrops; i++) {
drops[i] = 0;
i++;
}
for (i = 0; i < droplets; i++) {
var x = random(-30, window.innerWidth);
var y = random(-window.innerHeight, -30); // - height;
var r = raindropSize;
var h = map(x, 0, width, 0, 360);
var s = random(4, 30);
trail = random(0.1, 0.4);
thue = h;
distancey = random(100, window.innerHeight);
tswell = ((distancey / window.innerHeight) * 15) * s / 2;
drops[i] = new RainDrop(x, y, r, h, s, tswell, distancey);
}
start();
}
function lightening() {
var starts = 0;
var xpos = random(0, width);
while (thickness > 0) {
var abolt = random(0, 100);
var bbolt = random(-20, 20);
strokeWeight(thickness);
stroke(200, 100, 50, 1);
line(xpos, starts, xpos + bbolt, starts + abolt);
xpos += bbolt;
starts += abolt;
thickness--;
}
}
body {padding: 0; margin: 0; overflow :hidden;}
There are 3 files HTML, CSS and js.
the rain not shows, can some one explain it, thanks.
var drops = [];
var raindropSize = 1;
var droplets = 3000;
var maxDrops = 3000;
var thue;
var flig = 0;
var thickness = 9;
var tx;
var ty = 10;
var loc = 0;
var direct = -1;
var trail = 0.1;
var fade = 1;
var ms;
var distancy;
var mob = 0;
var xp = 1;
var yp = 1;
function setup() {
//smooth();
noStroke();
colorMode(HSB, 360, 100, 50, 1);
createCanvas(window.innerWidth, window.innerHeight);
if (window.innerWidth < 801) mob = 1;
if (mob == 1) droplets = droplets / 12;
tx = random(-3, 3);
for (var i = 0; i < droplets; i++) {
var x = round((random(width / raindropSize)) * raindropSize);
var y = round(random(height / raindropSize)) * raindropSize - window.innerHeight;
var r = raindropSize;
var h = map(x, 0, width, 0, 360); //(0, 360);
var s = random(1, 19); //trail = random(0.26, .7);
thue = h;
distancey = random(100, window.innerHeight);
tswell = ((distancey / window.innerHeight) * 25) * s / 2;
drops[i] = new RainDrop(x, y, r, h, s, tswell, distancey);
}
}
function draw() {
//text(trail, 100, 100);
var spot = 0;
var lig = random(0, 5);
if (lig > 4.9) {
flig = 100;
thickness = round(random(1, 19));
lightening();
}
background(200, 100, flig, trail);
if (flig == 100) flig = 0;
for (var i = 0; i < droplets; i++) {
drops[i].move();
drops[i].display();
}
}
function RainDrop(tempX, tempY, tempDiameter, tempHue, tempSpeed, tswell, tdistance) {
colorMode(HSB, 360, 100, 50, 1);
this.x = tempX;
this.loc = tempX;
this.y = tempY;
this.spot = 0;
this.diameter = tempDiameter;
this.h = tempHue;
this.s = tempSpeed;
this.swell = tswell;
this.distancey = tdistance;
this.move = function() {
//var ty = this.s;
this.x += (tx * raindropSize);
if (this.y < tdistance) this.y += tempSpeed;
if (this.x > width) {
this.loc = this.x;
this.x = this.x - window.innerWidth;
}
if (this.x < -20) this.x = width;
// fill(255);
// text(this.y, 100, 100);
// noFill();}
if (this.y > tdistance) {
this.y = tdistance - raindropSize;
this.spot = 1;
this.x -= (tx * raindropSize);
var fd = this.swell / tswell;
//var puddle = map(tswell, 0, tdistance, 1, 20);
strokeWeight(raindropSize / 3);
stroke(this.h, 100, 50, fd);
noFill();
ellipse(this.x + 1, tdistance, this.swell / 3, this.swell / 15);
//console.log(this.h);
this.swell -= 5;
}
if (this.swell < 4) {
this.swell = tswell;
this.y = random(-window.innerHeight, 0);
this.spot = 0;
this.distancey = tdistance;
}
// this.f += 2;
//this.y -= (tempSpeed);
//if (this.f > 9) {this.y = 0; this.f = 0; }
//direct = direct * -1; }
//round(random(height / raindropSize)) * (raindropSize - height);
this.display = function() {
if (this.spot == 0) {
noStroke();
fill(tempHue, 100, 50, fd);
rect(this.x, this.y, this.diameter, this.diameter);
}
};
}
}
function mousePressed() {
colorMode(HSB, 360, 100, 50, 0.8);
raindropSize = random(0.25, 3.5);
droplets = round(random(10, 3050));
if (mob == 1) droplets = droplets / 12;
tx *= -1;
for (var i = droplets; i < maxDrops; i++) {
drops[i] = 0;
i++;
}
for (i = 0; i < droplets; i++) {
var x = random(-30, window.innerWidth);
var y = random(-window.innerHeight, -30); // - height;
var r = raindropSize;
var h = map(x, 0, width, 0, 360);
var s = random(4, 30);
trail = random(0.1, 0.4);
thue = h;
distancey = random(100, window.innerHeight);
tswell = ((distancey / window.innerHeight) * 15) * s / 2;
drops[i] = new RainDrop(x, y, r, h, s, tswell, distancey);
}
//start();
}
function lightening() {
var starts = 0;
var xpos = random(0, width);
while (thickness > 0) {
var abolt = random(0, 100);
var bbolt = random(-20, 20);
strokeWeight(thickness);
stroke(200, 100, 50, 1);
line(xpos, starts, xpos + bbolt, starts + abolt);
xpos += bbolt;
starts += abolt;
thickness--;
}
}
body {padding: 0; margin: 0; overflow :hidden;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/p5.js" charset="utf-8"></script>
You are missing to add p5.js library , just link it in your html.
Hi I try to create an animation with a circle. The function drawRandom(drawFunctions) should pic one of the three drawcircle functions and should bring it on the canvas. Now the problem is that this function become executed every second (main loop) and the circle change his colour. How can I fix that?
window.onload = window.onresize = function() {
var C = 1; // canvas width to viewport width ratio
var el = document.getElementById("myCanvas");
var viewportWidth = window.innerWidth;
var viewportHeight = window.innerHeight;
var canvasWidth = viewportWidth * C;
var canvasHeight = viewportHeight;
el.style.position = "fixed";
el.setAttribute("width", canvasWidth);
el.setAttribute("height", canvasHeight);
var x = canvasWidth / 100;
var y = canvasHeight / 100;
var ballx = canvasWidth / 100;
var n;
window.ctx = el.getContext("2d");
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
// draw triangles
function init() {
ballx;
return setInterval(main_loop, 1000);
}
function drawcircle1()
{
var radius = x * 5;
ctx.beginPath();
ctx.arc(ballx * 108, canvasHeight / 2, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'yellow';
ctx.fill();
}
function drawcircle2()
{
var radius = x * 5;
ctx.beginPath();
ctx.arc(ballx * 108, canvasHeight / 2, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'blue';
ctx.fill();
}
function drawcircle3()
{
var radius = x * 5;
ctx.beginPath();
ctx.arc(ballx * 105, canvasHeight / 2, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'orange';
ctx.fill();
}
function draw() {
var counterClockwise = false;
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
//first halfarc
ctx.beginPath();
ctx.arc(x * 80, y * 80, y * 10, 0 * Math.PI, 1 * Math.PI, counterClockwise);
ctx.lineWidth = y * 1;
ctx.strokeStyle = 'black';
ctx.stroke();
// draw stop button
ctx.beginPath();
ctx.moveTo(x * 87, y * 2);
ctx.lineTo(x * 87, y * 10);
ctx.lineWidth = x;
ctx.stroke();
ctx.beginPath();
ctx.moveTo(x * 95, y * 2);
ctx.lineTo(x * 95, y * 10);
ctx.lineWidth = x;
ctx.stroke();
function drawRandom(drawFunctions){
//generate a random index
var randomIndex = Math.floor(Math.random() * drawFunctions.length);
//call the function
drawFunctions[randomIndex]();
}
drawRandom([drawcircle1, drawcircle2, drawcircle3]);
}
function update() {
ballx -= 0.1;
if (ballx < 0) {
ballx = -radius;
}
}
function main_loop() {
draw();
update();
collisiondetection();
}
init();
function initi() {
console.log('init');
// Get a reference to our touch-sensitive element
var touchzone = document.getElementById("myCanvas");
// Add an event handler for the touchstart event
touchzone.addEventListener("mousedown", touchHandler, false);
}
function touchHandler(event) {
// Get a reference to our coordinates div
var can = document.getElementById("myCanvas");
// Write the coordinates of the touch to the div
if (event.pageX < x * 50 && event.pageY > y * 10) {
ballx += 1;
} else if (event.pageX > x * 50 && event.pageY > y * 10 ) {
ballx -= 1;
}
console.log(event, x, ballx);
draw();
}
initi();
draw();
}
Take a look at my code that I wrote:
var lastTime = 0;
function requestMyAnimationFrame(callback, time)
{
var t = time || 16;
var currTime = new Date().getTime();
var timeToCall = Math.max(0, t - (currTime - lastTime));
var id = window.setTimeout(function(){ callback(currTime + timeToCall); }, timeToCall);
lastTime = currTime + timeToCall;
return id;
}
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
canvas.width = window.innerWidth - 20;
canvas.height = window.innerHeight - 20;
canvas.style.width = canvas.width + "px";
canvas.style.height = canvas.height + "px";
var circles = [];
var mouse =
{
x: 0,
y: 0
}
function getCoordinates(x, y)
{
return "(" + x + ", " + y + ")";
}
function getRatio(n, d)
{
// prevent division by 0
if (d === 0 || n === 0)
{
return 0;
}
else
{
return n/d;
}
}
function Circle(x,y,d,b,s,c)
{
this.x = x;
this.y = y;
this.diameter = Math.round(d);
this.radius = Math.round(d/2);
this.bounciness = b;
this.speed = s;
this.color = c;
this.deltaX = 0;
this.deltaY = 0;
this.drawnPosition = "";
this.fill = function()
{
context.beginPath();
context.arc(this.x+this.radius,this.y+this.radius,this.radius,0,Math.PI*2,false);
context.closePath();
context.fill();
}
this.clear = function()
{
context.fillStyle = "#ffffff";
this.fill();
}
this.draw = function()
{
if (this.drawnPosition !== getCoordinates(this.x, this.y))
{
context.fillStyle = this.color;
// if commented, the circle will be drawn if it is in the same position
//this.drawnPosition = getCoordinates(this.x, this.y);
this.fill();
}
}
this.keepInBounds = function()
{
if (this.x < 0)
{
this.x = 0;
this.deltaX *= -1 * this.bounciness;
}
else if (this.x + this.diameter > canvas.width)
{
this.x = canvas.width - this.diameter;
this.deltaX *= -1 * this.bounciness;
}
if (this.y < 0)
{
this.y = 0;
this.deltaY *= -1 * this.bounciness;
}
else if (this.y+this.diameter > canvas.height)
{
this.y = canvas.height - this.diameter;
this.deltaY *= -1 * this.bounciness;
}
}
this.followMouse = function()
{
// deltaX/deltaY will currently cause the circles to "orbit" around the cursor forever unless it hits a wall
var centerX = Math.round(this.x + this.radius);
var centerY = Math.round(this.y + this.radius);
if (centerX < mouse.x)
{
// circle is to the left of the mouse, so move the circle to the right
this.deltaX += this.speed;
}
else if (centerX > mouse.x)
{
// circle is to the right of the mouse, so move the circle to the left
this.deltaX -= this.speed;
}
else
{
//this.deltaX = 0;
}
if (centerY < mouse.y)
{
// circle is above the mouse, so move the circle downwards
this.deltaY += this.speed;
}
else if (centerY > mouse.y)
{
// circle is under the mouse, so move the circle upwards
this.deltaY -= this.speed;
}
else
{
//this.deltaY = 0;
}
this.x += this.deltaX;
this.y += this.deltaY;
this.x = Math.round(this.x);
this.y = Math.round(this.y);
}
}
function getRandomDecimal(min, max)
{
return Math.random() * (max-min) + min;
}
function getRoundedNum(min, max)
{
return Math.round(getRandomDecimal(min, max));
}
function getRandomColor()
{
// array of three colors
var colors = [];
// go through loop and add three integers between 0 and 255 (min and max color values)
for (var i = 0; i < 3; i++)
{
colors[i] = getRoundedNum(0, 255);
}
// return rgb value (RED, GREEN, BLUE)
return "rgb(" + colors[0] + "," + colors[1] + ", " + colors[2] + ")";
}
function createCircle(i)
{
// diameter of circle
var minDiameter = 25;
var maxDiameter = 50;
// bounciness of circle (changes speed if it hits a wall)
var minBounciness = 0.2;
var maxBounciness = 0.65;
// speed of circle (how fast it moves)
var minSpeed = 0.3;
var maxSpeed = 0.45;
// getRoundedNum returns a random integer and getRandomDecimal returns a random decimal
var x = getRoundedNum(0, canvas.width);
var y = getRoundedNum(0, canvas.height);
var d = getRoundedNum(minDiameter, maxDiameter);
var c = getRandomColor();
var b = getRandomDecimal(minBounciness, maxBounciness);
var s = getRandomDecimal(minSpeed, maxSpeed);
// create the circle with x, y, diameter, bounciness, speed, and color
circles[i] = new Circle(x,y,d,b,s,c);
}
function makeCircles()
{
var maxCircles = getRoundedNum(2, 5);
for (var i = 0; i < maxCircles; i++)
{
createCircle(i);
}
}
function drawCircles()
{
var ii = 0;
for (var i = 0; ii < circles.length; i++)
{
if (circles[i])
{
circles[i].draw();
ii++;
}
}
}
function clearCircles()
{
var ii = 0;
for (var i = 0; ii < circles.length; i++)
{
if (circles[i])
{
circles[i].clear();
ii++;
}
}
}
function updateCircles()
{
var ii = 0;
for (var i = 0; ii < circles.length; i++)
{
if (circles[i])
{
circles[i].keepInBounds();
circles[i].followMouse();
ii++;
}
}
}
function update()
{
requestMyAnimationFrame(update,10);
updateCircles();
}
function draw()
{
requestMyAnimationFrame(draw,1000/60);
context.clearRect(0,0,canvas.width,canvas.height);
drawCircles();
}
window.addEventListener("load", function()
{
window.addEventListener("mousemove", function(e)
{
mouse.x = e.layerX || e.offsetX;
mouse.y = e.layerY || e.offsetY;
});
makeCircles();
update();
draw();
});