Been having issues with this for a couple days, not sure why the text I'm rendering on the canvas is flashing so much. I'm using the requestAnimationFrame() function, but its still flickering.
What I want to have happen is for the text to move smoothly and they remove themselves from the array when they move completely off screen.
var canvas = document.getElementById("myCanvas");
var c = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var w = canvas.width;
var h = canvas.height;
var texts = [];
window.addEventListener("load", init);
function init() {
draw();
mainLoop();
}
function mainLoop() {
texts.push(createText("wow", "blue"));
texts.push(createText("wow", "green"));
texts.push(createText("wow", "red"));
setTimeout(function() { mainLoop(); }, 100);
}
function Text(x, y, vx, vy, varText, theColor){
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.color = theColor;
this.draw = function() {
drawStroked(varText, this.x, this.y, this.color);
}
}
function drawStroked(text, x, y, color) {
c.font = "30px bold Comic Sans MS";
c.strokeStyle = 'black';
c.lineWidth = 8;
c.strokeText(text, x, y);
c.fillStyle = color;
c.fillText(text, x, y);
}
function createText(varText, color) {
var x = (Math.random() * w / 2 ) + w/4;
var y = (Math.random() * h / 2) + h/2;
var vx = (Math.random() * .5) - .25
var vy = -(Math.random() * 3) - 1
return new Text(x, y, vx, vy, varText, color);
}
function draw() {
c.clearRect(0, 0, c.canvas.width, c.canvas.height);
for(var i = 0;i < texts.length; i++) {
var currentText = texts[i];
currentText.x += currentText.vx;
currentText.y += currentText.vy;
currentText.draw();
if(currentText.x>w||currentText.x<0||currentText.y<10){
texts.splice(i, 1);
}
}
requestAnimationFrame(draw);
}
body {
margin: 0;
padding: 0;
overflow: hidden;
}
<!DOCTYPE html>
<html>
<head>
<title>Game Screen</title>
</head>
<body>
<canvas id="myCanvas"></canvas>
</body>
</html>
The flickering you are seeing results from your looping code, where you skip elements of the array when deleting elements (Element 3 needs to be deleted? You call splice(3, 1) and then continue with the loop at index 4. Since the array shifts when you call splice, you should process element 3 again).
The imho easiest way to fix this is to iterate backwards over the array. Please note that iterating backwards is less CPU cache efficient (because every array access leads to a cache miss), so another fix would be
if(currentText.x>w||currentText.x<0||currentText.y<10){
texts.splice(i--, 1); // decrement i after accessing and deleting
}
var canvas = document.getElementById("myCanvas");
var c = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var w = canvas.width;
var h = canvas.height;
var texts = [];
window.addEventListener("load", init);
function init() {
draw();
mainLoop();
}
function mainLoop() {
texts.push(createText("wow", "blue"));
texts.push(createText("wow", "green"));
texts.push(createText("wow", "red"));
setTimeout(function() { mainLoop(); }, 100);
}
function Text(x, y, vx, vy, varText, theColor){
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.color = theColor;
this.draw = function() {
drawStroked(varText, this.x, this.y, this.color);
}
}
function drawStroked(text, x, y, color) {
c.font = "30px bold Comic Sans MS";
c.strokeStyle = 'black';
c.lineWidth = 8;
c.strokeText(text, x, y);
c.fillStyle = color;
c.fillText(text, x, y);
}
function createText(varText, color) {
var x = (Math.random() * w / 2 ) + w/4;
var y = (Math.random() * h / 2) + h/2;
var vx = (Math.random() * .5) - .25
var vy = -(Math.random() * 3) - 1
return new Text(x, y, vx, vy, varText, color);
}
function draw() {
c.clearRect(0, 0, c.canvas.width, c.canvas.height);
for(var i = texts.length - 1;i >= 0; i--) {
var currentText = texts[i];
currentText.x += currentText.vx;
currentText.y += currentText.vy;
currentText.draw();
if(currentText.x>w||currentText.x<0||currentText.y<10){
texts.splice(i, 1);
}
}
requestAnimationFrame(draw);
}
body {
margin: 0;
padding: 0;
overflow: hidden;
}
<!DOCTYPE html>
<html>
<head>
<title>Game Screen</title>
</head>
<body>
<canvas id="myCanvas"></canvas>
</body>
</html>
Related
I'm trying to make a ball which moves on a line and it bounces on it when clicked on it, but I don't know how to make it bounce on click.
Also, c.fill() doesn't work, I don't know why. (I've used it to fill the ball, maybe it doesn't work like that?)
Any advice would be really helpful since I'm a beginner in canvas, but know these 2 problems really concern me as I can't find any solutions for any of them. 😞
document.addEventListener('DOMContentLoaded', function () {
var canvas = document.querySelector('canvas');
var canvasx = document.getElementById('hr');
var c = canvas.getContext('2d');
canvas.width = canvasx.clientWidth;
canvas.height = canvasx.clientHeight;
var x = 80;
var y = 30;
var dx = 6;
var dy = 2;
var radius = 15;
var gravity = Math.random();
var friction = 0.9;
function animate() {
requestAnimationFrame(animate);
c.clearRect(0, 0, canvas.width, canvas.height);
c.beginPath();
c.arc(x, y, radius, 0, Math.PI * 2, false);
c.strokeStyle = "#eeede7";
c.stroke();
c.beginPath();
c.moveTo(50, canvas.height);
c.lineTo(1870, canvas.height);
c.lineWidth = 3;
c.fillStyle = "#77dff1";
c.fill();
c.strokeStyle = "#77dff1";
c.stroke();
update = function () {
if (y + 20 > canvas.height) {
dy = -dy * friction;
}
else {
dy += gravity;
}
y += dy;
x += dx;
}
function bounce() {
if ((x + radius + 50) > canvas.width || (x - radius - 50) < 0) {
dx = -dx;
}
}
update();
bounce();
}
animate();
function over() {
var px = event.pageX;
if (x - px < 0 || x - px > 0)
{
dx = -dx;
}
}
function bounceBall()
{
}
canvas.addEventListener('mouseover', over, false);
canvas.addEventListener('click', bounceBall, false)
}, false);
#hr {
position: relative;
bottom: 5%;
width: 100%;
margin: 0 auto;
}
hr {
border-color: #77dff1;
max-width: 90%;
}
canvas {
width: 100%;
}
<div id="hr">
<canvas></canvas>
<script src="js/canvas.js"></script>
</div>
I'm trying to make 2 rows and 5 columns of bricks using an object, but It doesn't seem to be working. I tried looking it up and using arrays, but It still didn't seem to work.
The bricks have a class of Brick
Demo
Here's the JavaScript
let canvas = $("#canvas")[0];
let ctx = canvas.getContext("2d");
let mouseX = 0;
let mouseY = 0;
class Paddle {
constructor(x, y, w, h, color) {
this.x = canvas.width / 2 - 100 / 2;
this.y = canvas.height - 60;
this.w = 100;
this.h = 10;
this.color = "#fff";
}
draw() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
}
}
class Ball {
constructor (x, y, r, speedX, speedY, color) {
this.x = canvas.width / 2 - 10 / 2;
this.y = canvas.height / 2 - 10 / 2;
this.r = 10;
this.speedX = 3;
this.speedY = 3;
this.color = "#fff";
}
draw() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
ctx.fill();
}
animate() {
this.x += this.speedX;
this.y += this.speedY;
}
collision() {
if(this.x >= canvas.width) {
this.speedX *= -1;
}
if(this.x <= 0) {
this.speedX *= -1;
}
if(this.y >= canvas.height) {
this.reset();
}
if(this.y <= 0) {
this.speedY *= -1;
}
let paddleTop = paddle.y;
let paddleBottom = paddleTop + paddle.h;
let paddleLeft = paddle.x;
let paddleRight = paddle.x + paddle.w;
if(ball.x >= paddleLeft &&
ball.x <= paddleRight &&
ball.y >= paddleTop &&
ball.y <= paddleBottom) {
ball.speedY *= -1;
ballControl();
}
}
reset() {
this.speedX = 3;
this.speedY = 3;
this.x = canvas.width / 2 - 10 / 2;
this.y = canvas.height / 2 - 10 / 2;
}
}
class Brick {
constructor(x, y, w, h, col, row, gap, color) {
this.x = 0;
this.y = 0;
this.w = 100;
this.h = 50;
this.col = 5; //# of brick columns
this.row = 2; //# of brick rows
this.gap = 2; //gap betweeb each brick
this.color = "#0000ff";
}
draw() {
for(let brickRow = 0; brickRow < this.row; brickRow++) {
for(let brickCol = 0; brickCol < this.col; brickCol++) {
ctx.fillStyle = this.color;
ctx.fillRect(this.x * brickCol, this.y * brickRow, this.w - this.gap, this.h - this.gap);
}
}
}
}
let paddle = new Paddle(this.x, this.y, this.w, this.h, this.color);
let ball = new Ball(this.x, this.y, this.r, this.speedX, this.speedY, this.color);
let brick = new Brick(this.x, this.y, this.w, this.h, this.col, this.row, this.gap, this.color);
// START
$(document).ready(() => {
let fps = 120;
setInterval(init, 1000 / fps);
$(canvas).bind("mousemove", paddleControl);
})
// INIT
let init = () => {
draw();
animate();
collision();
}
// DRAW
let draw = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
paddle.draw();
ball.draw();
brick.draw();
}
// ANIMATE
let animate = () => {
ball.animate();
}
// COLLISION
let collision = () => {
ball.collision();
}
// BALL CONTROL
let ballControl = () => {
let paddleCenter = paddle.x + paddle.w / 2;
let ballDistFromPaddleCenter = ball.x - paddleCenter;
ball.speedX = ballDistFromPaddleCenter * 0.15;
}
// PADDLE CONTROL
let paddleControl = (e) => {
let rect = canvas.getBoundingClientRect();
let root = document.documentElement;
mouseX = e.pageX - rect.left - root.scrollLeft;
mouseY = e.pageY - rect.top - root.scrollTop;
paddle.x = mouseX;
}
"Doesn't seem to work" is insufficient when describing your problem. You need to say what you expect and what you observe. Failing to do so has attracted 2 close votes for the reason that the question is unclear.
One of your problems is the way that you calculate the position of each brick.
Another potential problem is that you have one object representing all bricks, a better way would be for each brick to be it's own object - this will simplify collision detection (a lot!)
Your code also relies upon the script element appearing after all of the HTML - while functional, this is a broken paradigm. While it is good practise to put it after the html, so that the content is first rendered as soon as possible, having code that only works when it's put there is not so good. For instance - the classes wont initialise before the canvas has been located (since they rely on it's width - a better option would be to have them rely on a separate width variable, which is set to the width of the canvas during page init)
Couldn't get the fiddle to work, nor a snippet for that matter. But here's your code reworked a little. I can now see 2 rows of 5 blue bricks.
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<style>
#canvas {
position: absolute;
background-color: #000;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
</style>
<head>
<body>
<canvas id="canvas" width="600" height="500"></canvas>
<script>
var canvas, ctx, mouseX=0, mouseY=0;
canvas = $("#canvas")[0];
ctx = canvas.getContext("2d");
mouseX = 0;
mouseY = 0;
class Paddle
{
constructor(x, y, w, h, color)
{
this.x = canvas.width / 2 - 100 / 2;
this.y = canvas.height - 60;
this.w = 100;
this.h = 10;
this.color = "#fff";
}
draw()
{
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
}
}
class Ball {
constructor (x, y, r, speedX, speedY, color) {
this.x = canvas.width / 2 - 10 / 2;
this.y = canvas.height / 2 - 10 / 2;
this.r = 10;
this.speedX = 3;
this.speedY = 3;
this.color = "#fff";
}
draw() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
ctx.fill();
}
animate() {
this.x += this.speedX;
this.y += this.speedY;
}
collision() {
if(this.x >= canvas.width) {
this.speedX *= -1;
}
if(this.x <= 0) {
this.speedX *= -1;
}
if(this.y >= canvas.height) {
this.reset();
}
if(this.y <= 0) {
this.speedY *= -1;
}
let paddleTop = paddle.y;
let paddleBottom = paddleTop + paddle.h;
let paddleLeft = paddle.x;
let paddleRight = paddle.x + paddle.w;
if(ball.x >= paddleLeft &&
ball.x <= paddleRight &&
ball.y >= paddleTop &&
ball.y <= paddleBottom) {
ball.speedY *= -1;
ballControl();
}
}
reset() {
this.speedX = 3;
this.speedY = 3;
this.x = canvas.width / 2 - 10 / 2;
this.y = canvas.height / 2 - 10 / 2;
}
}
class Brick {
constructor(x, y, w, h, col, row, gap, color) {
this.x = 0;
this.y = 0;
this.w = 100;
this.h = 50;
this.col = 5; //# of brick columns
this.row = 2; //# of brick rows
this.gap = 2; //gap betweeb each brick
this.color = "#0000ff";
}
draw() {
for(let brickRow = 0; brickRow < this.row; brickRow++)
{
for(let brickCol = 0; brickCol < this.col; brickCol++)
{
ctx.fillStyle = this.color;
ctx.fillRect( (this.w+this.gap) * brickCol, (this.h+this.gap) * brickRow, this.w, this.h );
}
}
}
}
let paddle = new Paddle(this.x, this.y, this.w, this.h, this.color);
let ball = new Ball(this.x, this.y, this.r, this.speedX, this.speedY, this.color);
let brick = new Brick(this.x, this.y, this.w, this.h, this.col, this.row, this.gap, this.color);
// START
$(document).ready(() => {
let fps = 120;
setInterval(init, 1000 / fps);
$(canvas).bind("mousemove", paddleControl);
})
// INIT
let init = () => {
draw();
animate();
collision();
}
// DRAW
let draw = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
paddle.draw();
ball.draw();
brick.draw();
}
// ANIMATE
let animate = () => {
ball.animate();
}
// COLLISION
let collision = () => {
ball.collision();
}
// BALL CONTROL
let ballControl = () => {
let paddleCenter = paddle.x + paddle.w / 2;
let ballDistFromPaddleCenter = ball.x - paddleCenter;
ball.speedX = ballDistFromPaddleCenter * 0.15;
}
// PADDLE CONTROL
let paddleControl = (e) => {
let rect = canvas.getBoundingClientRect();
let root = document.documentElement;
mouseX = e.pageX - rect.left - root.scrollLeft;
mouseY = e.pageY - rect.top - root.scrollTop;
paddle.x = mouseX;
}
</script>
</body>
</html>
For this animation On click I need a different shapes to be made I need 5 different shapes in total. Also Ive had a hard time doing these things,
add a random motion vector to every circle
add an interval timer that redraws the background and each circle in its new position every 30 milliseconds
Check if any circle is outside the canvas width and height, and if so reverse its direction back onto the screen
also maybe If I can have some random text to fade in and fade out every couple of seconds too
The code...
var canvas;
var context;
var circles = [];
var timer;
function Circle(x, y, color) {
this.x = x;
this.y = y;
this.dx = Math.random() * 4 - 2;
this.dy = Math.random() * 4 - 2;
this.color = color;
}
function init() {
canvas = document.getElementById('canvas');
context = canvas.getContext("2d");
window.addEventListener('resize', resizeCanvas, false);
window.addEventListener('orientationchange', resizeCanvas, false);
resizeCanvas();
canvas.onclick = function (event) {
handleClick(event.clientX, event.clientY);
};
timer = setInterval(resizeCanvas, 20);
}
function handleClick(x, y) {
var found = false;
for (var i = 0; i < circles.length; i++) {
d = Math.sqrt((circles[i].x - x) * (circles[i].x - x) + (circles[i].y - y) * (circles[i].y - y));
if (d <= 30) {
circles.splice(i, 1);
found = true;
}
}
fillBackgroundColor();
if (!found) {
var colors = ["red", "green", "blue", "orange", "purple", "yellow"];
var color = colors[Math.floor(Math.random() * colors.length)];
circles.push(new Circle(x, y, color));
}
for (var i = 0; i < circles.length; i++) {
drawCircle(circles[i]);
}
}
function drawCircle(circle) {
context.beginPath();
context.arc(circle.x, circle.y, 30, 0, degreesToRadians(360), true);
context.fillStyle = circle.color;
context.fill();
if (circle.x + circle.dx > canvas.width || circle.x + circle.dx < 0)
circle.dx = -circle.dx;
if (circle.y + circle.dy > canvas.height || circle.y + circle.dy < 0)
circle.dy = -circle.dy;
circle.x += circle.dx;
circle.y += circle.dy;
}
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
fillBackgroundColor();
for (var i = 0; i < circles.length; i++) {
drawCircle(circles[i]);
}
}
function fillBackgroundColor() {
//var colors = ["white", "yellow", "blue", "red"];
//var bgColor = colors[Math.floor(Math.random() * colors.length)];
context.fillStyle = 'black';
context.fillRect(0, 0, canvas.width, canvas.height);
}
function degreesToRadians(degrees) {
//converts from degrees to radians and returns
return (degrees * Math.PI) / 180;
}
window.onload = init;
<canvas id='canvas' width=500 height=500></canvas>
I'm trying to make a blackhole simulation, and although I'm almost done, I wish to make disappear the dots that are drawn on the blackhole progressively, here is my code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>test trou noir</title>
<script>
var canvas, ctx;
var blackhole;
var circle;
var circles = new Array();
var G = 6.67e-11,//gravitational constant
pixel_G = G/1e-11,
c = 3e8, //speed of light (m/s)
M = 12e31,// masseof the blackhole in kg (60 solar masses)
pixel_M = M/1e32
Rs = (2 * G * M) / 9e16, //Schwarzchild radius
pixel_Rs = Rs/1e3, // scaled radius
ccolor=128;
function update() {
var pos, i, distance, somethingMoved = false;
for (i = 0; i < circles.length; i++) {
pos = circles[i].position;
distance = Math.sqrt(((pos.x - 700) * (pos.x - 700)) + ((pos.y - 400) * (pos.y - 400)));
if (distance > pixel_Rs && visible(circles[i])) {
var delta = new Vector2D(0, 0);
var forceDirection = Math.atan2(pos.y - 400, pos.x - 700);
var evelocity = Math.sqrt( (2*pixel_G*pixel_M)/(distance*1e-2));
delta.x += Math.cos(forceDirection) * evelocity;
delta.y += Math.sin(forceDirection) * evelocity;
pos.x += delta.x;
pos.y += delta.y;
somethingMoved = true;
}
}
if (somethingMoved) {
drawEverything();
requestAnimationFrame(update);
} else {
ccolor -=10;
};
}
function visible(ball) {
return ball.position.x > ball.radius && ball.position.x < canvas.width - ball.radius &&
ball.position.y > ball.radius && ball.position.y < canvas.height - ball.radius;
}
function drawEverything() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
blackhole.draw(ctx);
for (var i = 0; i < circles.length; i++) {
if (visible(circles[i])) {
circles[i].draw(ctx);
}
}
}
function init() {
canvas = document.getElementById("space");
ctx = canvas.getContext('2d');
blackhole = new Ball(pixel_Rs, {
x: 700,
y: 400
}, "black");
for (var i = 0; i < 200; i++) {
var vec2D = new Vector2D(Math.floor(Math.random() * 1400), Math.floor(Math.random() * 800));
circle = new Ball(5, vec2D, 'rgba('+ccolor+','+ccolor+','+ccolor+',1)');
circles.push(circle);
}
drawEverything();
requestAnimationFrame(update);
}
function Ball(radius, position, color) {
this.radius = radius;
this.position = position;
this.color = color;
}
Ball.prototype.draw = function(ctx) {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius, 0, 2 * Math.PI);
ctx.closePath();
ctx.fill();
};
function Vector2D(x, y) {
this.x = x;
this.y = y;
}
window.onload = init;
</script>
<style>
body {
background-color: #021c36;
margin: 0px;
}
</style>
</head>
<body>
<canvas id="space" , width="1400" , height="800">
</canvas>
</body>
</html>
now as you can see, I created a variable called ccolor which is integrated in the rgba code, but I don't know why the colors don't tend to zero, so the circles that are inside the blackhole gradually disappear, if someone could lend me a hand it'd be great
In update, if any circles[i] is captured by the Blackhole you decrement its this.color. It might be easier if you change this.color to an integer that you use to create a fillStyle:
ctx.fillStyle='rgba(' + this.color + ',' + this.color + ',' + this.color + ',1)'.
Here's a quick demo:
View this demo Full Page or the black hole is off-screen
var canvas, ctx;
var blackhole;
var circle;
var circles = new Array();
var G = 6.67e-11, //gravitational constant
pixel_G = G / 1e-11,
c = 3e8, //speed of light (m/s)
M = 12e31, // masseof the blackhole in kg (60 solar masses)
pixel_M = M / 1e32
Rs = (2 * G * M) / 9e16, //Schwarzchild radius
pixel_Rs = Rs / 1e3, // scaled radius
ccolor = 128;
function update() {
var pos, i, distance, somethingMoved = false;
for (i = 0; i < circles.length; i++) {
pos = circles[i].position;
distance = Math.sqrt(((pos.x - 700) * (pos.x - 700)) + ((pos.y - 400) * (pos.y - 400)));
if (distance > pixel_Rs && visible(circles[i])) {
var delta = new Vector2D(0, 0);
var forceDirection = Math.atan2(pos.y - 400, pos.x - 700);
var evelocity = Math.sqrt((2 * pixel_G * pixel_M) / (distance * 1e-2));
delta.x += Math.cos(forceDirection) * evelocity;
delta.y += Math.sin(forceDirection) * evelocity;
pos.x += delta.x;
pos.y += delta.y;
somethingMoved = true;
} else {
circles[i].color -= 0.50;
}
}
if (somethingMoved) {
drawEverything();
requestAnimationFrame(update);
};
}
function visible(ball) {
return ball.position.x > ball.radius && ball.position.x < canvas.width - ball.radius &&
ball.position.y > ball.radius && ball.position.y < canvas.height - ball.radius;
}
function drawEverything() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
blackhole.draw(ctx);
for (var i = 0; i < circles.length; i++) {
if (visible(circles[i])) {
circles[i].draw(ctx);
}
}
}
function init() {
canvas = document.getElementById("space");
ctx = canvas.getContext('2d');
blackhole = new Ball(pixel_Rs, {
x: 700,
y: 400
}, 0);
for (var i = 0; i < 200; i++) {
var vec2D = new Vector2D(Math.floor(Math.random() * 1400), Math.floor(Math.random() * 800));
circle = new Ball(5, vec2D, ccolor);
circles.push(circle);
}
drawEverything();
requestAnimationFrame(update);
}
function Ball(radius, position, color) {
this.radius = radius;
this.position = position;
this.color = color;
}
//
Ball.prototype.draw = function(ctx) {
var c=parseInt(this.color);
ctx.fillStyle = 'rgba(' + c + ',' + c + ',' + c + ',1)';
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius, 0, 2 * Math.PI);
ctx.closePath();
ctx.fill();
};
function Vector2D(x, y) {
this.x = x;
this.y = y;
}
init();
body{ background-color: #021c36; margin: 0px; }
<canvas id="space" width=1400 height=800></canvas>
Simple solution:
In drawEverything() function move blackhole.draw(ctx) to be the last step
Not so simple: Use one of the many JS particle systems
Been trying to animate an object on canvas by putting it in an array but it wont seem to work.
Only have one object drawn at the moment but the thought is to add several more objects to the canvas hence the array.
Is there something wrong with the functions im using to draw and animate the object?
var draw;
function Canvas(canvas, ctx) {
this.canvas = canvas;
this.ctx = ctx;
}
function Direction(x, y) {
this.x = x;
this.y = y;
}
function Measures(cW, cH, radius, hR, degree, dirX, dirY, degree) {
this.cW = cW;
this.cH = cH;
this.radius = radius;
this.hR = hR;
this.dirX = dirX;
this.dirY = dirY;
this.degree = degree;
}
function Drawing(cW, cH, width, height, radius, hR, color) {
this.cW = canvas.width;
this.cH = canvas.height;
this.width = width;
this.height = height;
this.radius = height / 2;
this.hR = width - this.radius;
this.color = color;
this.render = function() {
ctx.fillStyle = this.color;
ctx.strokeStyle = this.color;
ctx.lineWidth = 1;
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.degree * Math.PI / 180);
ctx.translate(-this.x, -this.y);
ctx.beginPath();
ctx.moveTo(this.x, this.y);
ctx.lineTo(x + this.hR, this.y);
ctx.arc(this.x + this.hR, this.y + this.radius, this.radius, - Math.PI / 2, Math.PI / 2);
ctx.lineTo(this.x, this.y + height);
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.restore();
}
this.move = function(multiplier) {
var multiplier = 2;
var borders = 5;
if(this.dirX > 0 && this.x > this.cW - borders - width){
this.degree = 90;
this.dirX = 0;
this.dirY = 1;
this.x = cW - borders;
}
else if(this.dirY > 0 && this.y > this.cH - borders - width){
this.degree = 180;
this.dirX = -1;
this.dirY = 0;
this.y = this.cH - borders;
}
else if(this.dirX < 0 && this.x < borders + width){
this.degree = -90;
this.dirX = 0;
this.dirY = -1;
this.x = borders;
}
else if(this.dirY < 0 && this.y < borders + width){
this.degree = 0;
this.dirX = 1;
this.dirY = 0;
this.y = borders;
}
this.x += this.dirX * multiplier;
this.y += this.dirY * multiplier;
this.render();
}
}
function animate() {
ctx.clearRect(0, 0, this.cW, this.cH);
draw.forEach(function(object) {
object.render(2);
});
requestAnimationFrame(animate);
}
function init() {
this.canvas = document.getElementById("my_canvas");
this.ctx = canvas.getContext("2d");
this.degree = Math.PI / 2;
draw = [];
draw.push(new Drawing(5, 5, 80, 60, new Direction(1,0), "#E5E5E5"));
animate();
}
window.onload = init;
</script>
<canvas id="my_canvas" width="1000" height="800" style="background-color:#33CC33"></canvas>