How to move an object in canvas with arrows? - javascript

Someone please can help me with an object moving automatically when I click on the right arrow in canvas.
My code is
if(e.keyCode == 39) {
bullet.x = +5;
setTimeout(function() {
ctx.clearRect(0,0,canvas.width,canvas.height)
ctx.drawImage(player.Image, player.x, player.y , player.width, player.height);
ctx.drawImage(bullet.Image , bullet.x , bullet.y , bullet.width , bullet.height);
}, 300);
console.log("DOWN");
}
What do I need to add for the object moving by the right arrow?

It is necessary to use ClearReact to advance with the function setInterval ()
let canvas = document.getElementById("mycanvas");
let ctx = canvas.getContext('2d');
juego();
let ev;
let x = 0;
let base_image = new Image();
base_image.src = 'https://img.icons8.com/pastel-glyph/2x/search.png';
window.onkeydown = function(e) {
this.ev = e;
}
function draw() {
if (typeof this.ev != 'undefined' && this.ev.keyCode == 39) {
x = x + 10;
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(base_image, x, 10);
}
}
function juego() {
pat = ctx.createPattern(canvas, "repeat");
window.setInterval(draw, 500);
}
canvas {
outline: black 3px solid;
}
<canvas id="mycanvas" width="150" height="150"></canvas>
for try press left arrow

Related

Why doesn't my code loop the animation correctly with Javascript and HTML5 canvas?

I'm super new to coding and I've been trying to figure out animations with Javascript and HTML5. I have this "loading bar" like animation where a rectangle expands until it fills up the canvas. The idea is that once the canvas is covered the box clears and starts over. Instead, the rectangle fills the canvas and just starts flickering. Any ideas?
window.onload = function() {
var wipeWidth = 0
var canvas = document.getElementById('canvas');
var context = canvas.getContext("2d");
console.log(context);
function drawRect() {
context.clearRect(0,0,300,150)
context.fillStyle = "#305ef2";
context.rect(0, 0, wipeWidth, 150);
context.fill()
wipeWidth += 10
if(wipeWidth > 300) {
wipeWidth = 0;
}
}
setInterval(drawRect,50)
}
You forgot to clear the path (beginPath). You can use fillRect instead to avoid this.
window.onload = function() {
var wipeWidth = 0
var canvas = document.getElementById('canvas');
var context = canvas.getContext("2d");
console.log(context);
function drawRect() {
context.clearRect(0, 0, 300, 150)
context.fillStyle = "#305ef2";
// this
context.beginPath()
context.rect(0, 0, wipeWidth, 150);
context.fill()
// or just this
// context.fillRect(0, 0, wipeWidth, 150);
wipeWidth += 10
if (wipeWidth > 300) {
wipeWidth = 0;
}
}
setInterval(drawRect, 50)
}
<canvas id="canvas"></canvas>
fillRect, requestAnimationFrame
var wipeWidth = 0
var canvas = document.getElementById('canvas');
var context = canvas.getContext("2d");
var direction = +10;
function drawRect() {
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "#305ef2";
context.fillRect(0, 0, wipeWidth, 150);
wipeWidth += direction
if (wipeWidth > canvas.width || wipeWidth < 0) {
direction *= -1;
}
requestAnimationFrame(drawRect)
}
drawRect()
canvas {
background: gray;
}
<canvas id="canvas" width="600" height="50"></canvas>

line rotation in class javascript canvas

I try to create a class with a function which might be use to change the angle of a line already drawn.
With what I write, the line doesn't move. When I press the right or left key, I have this error :
TypeError: this.changeAngle is not a function
Indeed, I don't have "function" keyword in my code ... I don't know what to use instead.
Could you help me ?
Thank you very much.
window.onload = init;
let canvas, ctx;
let mousePos;
let angle = 0;
class Lanceur {
constructor() {
this.changeAngle(this.angle);
}
update(ctx) {
this.drawAiguille(ctx);
}
drawSocleLanceur(ctx) {
ctx.save();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.arc(w/2, h, 20, 0, 2 * Math.PI);
ctx.stroke();
ctx.restore();
}
drawAiguille(ctx) {
ctx.save();
ctx.rotate(this.angle);
ctx.strokeStyle = "rgb(255, 0, 0)";
ctx.lineWidth=3;
ctx.beginPath();
ctx.moveTo(w/2, h-h*0.12);
ctx.lineTo(w/2, h-h*0.035);
ctx.stroke();
ctx.restore();
}
changeAngle(a) {
this.angle = a;
}
getAngle() {
return this.angle;
}
}
function init() {
canvas = document.querySelector("#jeu");
ctx = canvas.getContext("2d");
w = canvas.width;
h = canvas.height;
a = new Lanceur();
requestAnimationFrame(mainloop);
}
function mainloop() {
ctx.clearRect(0, 0, w, h);
a.update(ctx);
requestAnimationFrame(mainloop);
}
document.addEventListener('keypress', function(event){
gereTouches(event);
});
function gereTouches(event) {
if(event.key == "ArrowRight") {
this.changeAngle(this.getAngle - 1);
console.log("ça bouge : " + this.angle);
}else if(event.key == "ArrowLeft") {
this.changeAngle(this.getAngle + 1);
}
}
Main changes:
added this.angle to thr constructor()
using keydown event
the function gereTouches(event) uses a instead of this and a.getAngle() instead of a.getAngle
also 1 for the the angle is way too big (those are radians). I'm using .01 instead.
I hope it helps.
window.onload = init;
let canvas, ctx;
let mousePos;
let angle = 0;
class Lanceur {
constructor() {
this.angle = 0;
this.changeAngle(this.angle);
}
update(ctx) {
this.drawAiguille(ctx);
}
drawSocleLanceur(ctx) {
ctx.save();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.arc(w/2, h, 20, 0, 2 * Math.PI);
ctx.stroke();
ctx.restore();
}
drawAiguille(ctx) {
ctx.save();
ctx.rotate(this.angle);
ctx.strokeStyle = "rgb(255, 0, 0)";
ctx.lineWidth=3;
ctx.beginPath();
ctx.moveTo(w/2, h-h*0.12);
ctx.lineTo(w/2, h-h*0.035);
ctx.stroke();
ctx.restore();
}
changeAngle(a) {
this.angle = a;
}
getAngle() {
return this.angle;
}
}
function init() {
canvas = document.querySelector("#jeu");
ctx = canvas.getContext("2d");
w = canvas.width = 500;
h = canvas.height = 500;
a = new Lanceur();
requestAnimationFrame(mainloop);
}
function mainloop() {
ctx.clearRect(0, 0, w, h);
a.update(ctx);
requestAnimationFrame(mainloop);
}
document.addEventListener('keydown', function(event){
gereTouches(event);
});
function gereTouches(event) {
if(event.key == "ArrowRight") {
a.changeAngle(a.getAngle() - .01);
console.log("ça bouge : " + a.angle);
}else if(event.key == "ArrowLeft") {
a.changeAngle(a.getAngle() + .01);
}
}
canvas{border:1px solid}
<canvas id="jeu"></canvas>

Canvas: Strange behavior when pressing key down

By default the rectangle of my canvas should move from left to right. When pressing the key down, it should start moving down.
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
x = 0,
y = 0;
function draw(x_move, y_move) {
requestAnimationFrame(function() {
draw(x_move, y_move);
});
ctx.beginPath();
ctx.rect(x, y, 20, 20);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#ffffff";
ctx.fill();
ctx.closePath();
x = x + x_move;
y = y + y_move;
}
draw(1, 0);
document.addEventListener('keydown', function(event) {
//console.log(event.keyCode);
if (event.keyCode == 40) {
draw(0, 1);
}
});
canvas { background-color: red; }
<canvas id="canvas" width="600" height="400"></canvas>
Using the code above, you may at least notice two issues:
When pressing key down, the rectangle moves down but also keeps moving to the right.
When you keep pressing the down key multiple times, the speed gets increased.
How can I fix those issues?
See where you call
requestAnimationFrame(function() {
draw(x_move, y_move);
});
You're now recursively calling draw().
Now every time you call draw(), it gets called over and over and over again. And when you call it from the keydown event, you call it 2x as often, then 3x as often on the second time you press it, etc.
I'm not entirely clear on what your objective is here, but if you wanted to just adjust the trajectory of the square by pressing down, you could do something like this:
document.addEventListener('keydown', function(event) {
//console.log(event.keyCode);
if (event.keyCode == 40) {
adjustDownwardTrajectory();
}
});
and have that adjustDownwardTrajectory() change some downwardTrajectory variable such that:
function draw(x_move, y_move) {
requestAnimationFrame(function() {
draw(x_move, y_move);
});
ctx.beginPath();
ctx.rect(x, y, 20, 20);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#ffffff";
ctx.fill();
ctx.closePath();
x = x + x_move;
y = y + y_move + downwardTrajectory;
}
I believe this is what you want to be doing (and you were close!). I hope this is the behaviour you were looking for.
A related point: It may be a good idea to wrap x_move and y_move up in a closure with these functions so you avoid accidentally changing them in other parts of the program. That way the functions you implement for changing directions of the square will have private access to these variables.
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
x = 0,
y = 0;
var x_move = 1;
var y_move = 0;
function draw() {
requestAnimationFrame(function() {
draw();
});
ctx.beginPath();
ctx.rect(x, y, 20, 20);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#ffffff";
ctx.fill();
ctx.closePath();
x = x + x_move;
y = y + y_move;
}
draw();
document.addEventListener('keydown', function(event) {
//console.log(event.keyCode);
if (event.keyCode == 40) {
x_move = 0;
y_move = 1;
}
});
canvas {
background-color: red;
}
<canvas id="canvas" width="600" height="400"></canvas>
keyboardEvent.keyCode is a depreciated property. You should use keyboardEvent.code or keyboardEvent.key they provided a named key which is much easier to manage than trying to remember key codes.
You can use fillRect rather than rect and you don't need to use beginPath and fill. You don't need to use closePath you only use it if you want to close a shape (ie add a line from the last point to the first) rect is already closed
You can set the callback directly as the argument for requestAnimationFrame
It pays to group related data together. In this case the square has a position x, y and a delta position (x_move, y_move) that are better off in a object. A good clue that you have related data is when you find yourself adding the same name to a set of variables. Objects can also include behaviour in the form of functions like draw and update
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// list of named keys to record state of
const keys = {
ArrowDown: false,
};
// create key event listeners
document.addEventListener('keydown', keyEvent);
document.addEventListener('keyup', keyEvent);
// define the square
const square = {
x : 0, // position
y : 0,
dx : 0, // delta pos
dy : 0,
draw () { // function to render the square
ctx.fillStyle = "#ffffff";
ctx.fillRect(this.x, this.y, 20, 20);
},
update () { // function to update square
if(keys.ArrowDown){
this.dx = 0;
this.dy = 1;
}else {
this.dx = 1;
this.dy = 0;
}
this.x += this.dx;
this.y += this.dy;
}
}
// main animation update function called once per frame 1/60th second
function update () {
requestAnimationFrame(update);
ctx.clearRect(0, 0, canvas.width, canvas.height);
square.update();
square.draw();
}
// key event records named key state (false up, true down)
function keyEvent (event) {
if(keys[event.code] !== undefined){
keys[event.code] = event.type === "keydown";
}
}

How do I redraw the background, so it will look like my "player" moving in html5-canvas

This is my JavaScript. I have an animate function, I think this is where the redrawing background code goes. I have tried to use document.getElementById to get the id of the canvas, and give the style rule of background: white. But it didn't work. All help is appreciated!:
function initCanvas(){
var ctx = document.getElementById('my_canvas').getContext('2d');
var cW = ctx.canvas.width, cH = ctx.canvas.height;
var dist = 10;
function Player(){
this.x = 0, this.y = 0, this.w = 50, this.h = 50;
ctx.fillStyle = "orange";
this.render = function(){
ctx.fillRect(this.x, this.y, this.w, this.h);
}
}
var player = new Player();
player.x = 100;
player.y = 225;
function animate(){
//This is where I think the background redrawing should go
player.render();
}
var animateInterval = setInterval(animate, 30);
document.addEventListener('keydown', function(event) {
var key_press = String.fromCharCode(event.keyCode);
if(key_press == "W"){
player.y-=dist;
} else if(key_press == "S"){
player.y+=dist;
} else if(key_press == "A"){
player.x-=dist;
} else if(key_press == "D"){
player.x+=dist;
}
});
}
window.addEventListener('load', function(event) {
initCanvas();
});
Here are a couple things I've noticed:
You didn't declare var canvas = document.getElementById('my_canvas');
Your initCanvas() wasn't firing(It wasn't for me)
Your render() function should reset the fillStyle before it draws your character. Having the fillStyle set when initializing the Player constructor is useless(It can be overridden).
Here is what your animate() function should look like:
function animate(){
ctx.fillStyle = '#000';
ctx.fillRect(0,0,canvas.width, canvas.height);
player.render();
}
Notice how fillRect() clears the canvas before drawing the player.
I have created a working JSFiddle with the fixes here.

How would I put this code together?

I have a Javascript program working in three different places: here,
here, and here.
But I don't know how would I put them in one file. This is where I am at right now.
<!DOCTYPE html>
<html>
<head>
<title>TEST</title>
<style>
body {
background-color:#E4E0FF;
}
#canvas {
border:10px solid red;
background-color:white;
}
#canvas2 {
border:10px solid red;
background-color:white;
}
#canvas3 {
border:10px solid red;
background-color:white;
}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="300">
</canvas>
<canvas id="canvas2" width="400" height="300">
</canvas>
<canvas id="canvas3" width="400" height="300">
</canvas>
<script src="http://code.jquery.com/jquery-latest.min.js"
type="text/javascript"></script>
<script type="text/javascript">
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var $canvas = $("#canvas");
var canvasOffset = $canvas.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var scrollX = $canvas.scrollLeft();
var scrollY = $canvas.scrollTop();
var toggle=0;
var x=150;
var y=100;
var w=100;
var h=100;
var r=60;
var wasInside=false;
ctx.fillStyle = "#000000";
ctx.fillRect(x, y, w, h);
function changeColor() {
if (toggle == 0) {
ctx.fillStyle = "#04B45F";
toggle = 1;
} else if (toggle ==1){
ctx.fillStyle = "#04B45F";
toggle = 2;
}else if (toggle == 2){
ctx.fillStyle = "#0000FF";
toggle = 3;
}else if (toggle == 3){
ctx.fillStyle == "#190707";
toggle = 4;
}else if (toggle == 4){
ctx.fillStyle = "#210B61";
toggle = 5;
}else if (toggle == 5){
ctx.fillStyle = "#FA58AC";
toggle = 6;
}else if (toggle ==6){
ctx.fillStyle = "#FFFF00";
toggle = 7;
}else{
ctx.fillStyle = "#F5A9D0";
toggle = 0;
}
ctx.fillRect(x, y, w, h);
}
function changeRadius() {
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(0,0, 400, 300);
r = Math.floor((Math.random() * 80) + 20);
ctx.beginPath();
ctx.arc(200, 150, r, 0, 2 * Math.PI);
ctx.stroke();
}
function changeWidth() {
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(0,0, 400, 300);
width = Math.floor((Math.random()*50)+1);
ctx.lineWidth=width;
ctx.stroke();
}
function handleMouseMove(e) {
var mx = parseInt(e.clientX - offsetX);
var my = parseInt(e.clientY - offsetY);
var isInsideNow = (mx > x && mx < x + w && my > y && my <= y + h);
if (isInsideNow && !wasInside) {
changeColor();
wasInside = true;
} else if (!isInsideNow && wasInside) {
wasInside = false;
}
}
$("#canvas").mousemove(function (e) {
handleMouseMove(e);
});
$("#canvas2").mousemove(function (e) {
handleMouseMove(e);
});
$("#canvas3").mousemove(function (e) {
handleMouseMove(e);
});
</script>
</body>
</html>
So, how would I tell the program to do circle thing in 2nd canvas and line in 3rd canvas???
I haven't called the changeWidth and changeRadius functions yet, because it'll just do it in the first canvas making a mess.
I just need something in this part of the code to call different functions in different canvas's
if (isInsideNow && !wasInside) {
changeColor();
wasInside = true;
} else if (!isInsideNow && wasInside) {
wasInside = false;
}
I'm not a canvas expert, but just for giving you an idea, check this FIDDLE
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
inspect these 2 lines, the context ctx wil draw in the canvas with id=canvas. you can create other contex variables to draw in the other canvas or reuse the same.
updated FIDDLE
Update for the update: FIDDLE

Categories

Resources