I am trying to animate a line in HTML5 canvas. The line is supposed to move according to the keyboard strokes (just as the red square). Unfortunately it gets longer but it should just move sideways...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
<title>Test</title>
</head>
<body onload="init();">
<canvas id="myCanvas" width="600" height="400">Your browser does not support the canvas tag.</canvas>
<script>
var canvas;
var ctx;
var incrementX = 0;
var x = 250;
var y = 350;
function init() {
// This function is called after the page is loaded
// 1 - Get the canvas
canvas = document.getElementById('myCanvas');
// 2 - Get the context
ctx = canvas.getContext('2d');
// 3 add key listeners to the window element
window.addEventListener('keydown', handleKeydown, false);
window.addEventListener('keyup', handleKeyup, false);
// 4 - start the animation
requestId = requestAnimationFrame(animationLoop);
}
function handleKeydown(evt) {
if (evt.keyCode === 37) {
//left key
incrementX = -1;
} else if (evt.keyCode === 39) {
// right key
incrementX = 1;
}
}
function handleKeyup(evt) {
incrementX = 0;
}
function animationLoop() {
// 1 - Clear
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 2 Draw
drawLine(x, y);
// 3 Move
x += incrementX;
// call again mainloop after 16.6 ms (60 frames/s)
requestId = requestAnimationFrame(animationLoop);
}
function drawLine(x, y) {
ctx.save();
ctx.translate(x, y);
ctx.moveTo(0,0);
ctx.lineTo(100,0);
ctx.stroke();
ctx.fillStyle='red';
ctx.fillRect(35,30,20,20);
ctx.restore();
}
</script>
</body>
</html>
Related
I have an HTML page that allows a person to draw. Its very simple. The code for It is included down below.
I'm trying to add a button that inserts text that is editable and can be resized within the canvas element.
I have tried many options, but found no success. Is there a way to do that in Javascript?
The code I have:
<head>
<meta charset="utf-8">
<title>
Web Paint!
</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
#draw{
border-color: yellow;
}
</style>
</head>
<body>
<input id="hex" placeholder="enter hex color"></input>
<canvas id="draw"></canvas>
<script>
var canvas = document.getElementById("draw");
var ctx = canvas.getContext("2d");
//resize();
// resize canvas when window is resized
function resize() {
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
}
// initialize position as 0,0
var pos = { x: 0, y: 0 };
// new position from mouse events
function setPosition(e) {
pos.x = e.clientX-160;
pos.y = e.clientY-5;
}
function draw(e) {
if (e.buttons !== 1) return; // if mouse is not clicked, do not go further
var color = document.getElementById("hex").value;
ctx.beginPath(); // begin the drawing path
ctx.lineWidth = 20; // width of line
ctx.lineCap = "round"; // rounded end cap
ctx.strokeStyle = color; // hex color of line
ctx.moveTo(pos.x, pos.y); // from position
setPosition(e);
ctx.lineTo(pos.x, pos.y); // to position
ctx.stroke(); // draw it!
}
// add window event listener to trigger when window is resized
window.addEventListener("resize", resize);
// add event listeners to trigger on different mouse events
document.addEventListener("mousemove", draw);
document.addEventListener("mousedown", setPosition);
document.addEventListener("mouseenter", setPosition);
</script>
</body>
I am trying to make a simple game. The green block is my game character. I used a the keydown event to make my character able to move right and left. When I hold down the right or left arrow key, the character keeps on accelerating. If you start by tapping the right or left arrow key, you will see that the space interval between where the character was and where it is increases as you click more. How can I make my character move at a constant speed with constant space intervals.
//variables
var canvas = document.getElementById("canvas");
var draw = canvas.getContext("2d");
var characterx = 20;
var charactery = window.innerHeight - 60;
var dx = 0.01;
var dy = 0.01;
//canvas size
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
//main game function
function run() {
//loops the function
requestAnimationFrame(run);
//clears the screen
draw.clearRect(0, 0, canvas.width, canvas.height)
//draws the ground
draw.beginPath();
draw.fillStyle = "#823819";
draw.fillRect(0, canvas.height - 20, canvas.width, 20);
draw.fill();
draw.closePath();
//draws the main character
draw.beginPath();
draw.fillStyle = "#128522";
draw.fillRect(characterx, charactery, 40, 40);
draw.fill();
draw.closePath();
//key evevnts
window.addEventListener("keydown",function(event) {
if(event.keyCode == 39) {
characterx += dx;
}
});
window.addEventListener("keydown",function(event) {
if(event.keyCode == 37) {
characterx -= dx;
}
});
};
run();
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<style type="text/css">
body {
margin: 0;
overflow: hidden;
}
canvas {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
Your event listeners should be added outside of your game loop.
Currently you are adding an extra listener for each keypress on every frame, meaning that on the first frame you will move dx * 1 for a keypress, but on frame 100 you will move dx * 100 for a single keypress.
This is also why your dx value had to be so low - I've increased it in the sample below, but you can adjust it as needed.
//variables
var canvas = document.getElementById("canvas");
var draw = canvas.getContext("2d");
var characterx = 20;
var charactery = window.innerHeight - 60;
var dx = 3.0;
var dy = 3.0;
//canvas size
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
//key evevnts
window.addEventListener("keydown",function(event) {
if(event.keyCode == 39) {
characterx += dx;
}
});
window.addEventListener("keydown",function(event) {
if(event.keyCode == 37) {
characterx -= dx;
}
});
//main game function
function run() {
//loops the function
requestAnimationFrame(run);
//clears the screen
draw.clearRect(0, 0, canvas.width, canvas.height)
//draws the ground
draw.beginPath();
draw.fillStyle = "#823819";
draw.fillRect(0, canvas.height - 20, canvas.width, 20);
draw.fill();
draw.closePath();
//draws the main character
draw.beginPath();
draw.fillStyle = "#128522";
draw.fillRect(characterx, charactery, 40, 40);
draw.fill();
draw.closePath();
};
run();
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<style type="text/css">
body {
margin: 0;
overflow: hidden;
}
canvas {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
I need to prevent the cursor from going out of the window.
I've read that it's not possible, however I've already done that with a WebGL export from a Unity project. You first had to click the canvas, then the browser would show you a notification saying that you should press 'escape' to exit and get your cursor back.
Since a Unity WebGL canvas can do it, I assume it can be done without Unity?
Use the HTML5 Pointer Lock API
https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API
Not my code example below, all creds to
https://github.com/mdn/dom-examples/tree/master/pointer-lock
HTML
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>Pointer lock demo</title>
<link type="text/css" rel="stylesheet" href="style.css">
</head>
<body>
<div class="information">
<h1>Pointer lock demo</h1>
<p>This demo demonstrates usage of the pointer lock API. Click on the canvas area and your mouse will directly control the ball inside the canvas, not your mouse pointer. You can press escape to return to the standard expected state.</p>
</div>
<canvas width="640" height="360">
Your browser does not support HTML5 canvas
</canvas>
<div id="tracker"></div>
<script src="app.js"></script>
</body>
</html>
JS
// helper function
const RADIUS = 20;
function degToRad(degrees) {
var result = Math.PI / 180 * degrees;
return result;
}
// setup of the canvas
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
var x = 50;
var y = 50;
function canvasDraw() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#f00";
ctx.beginPath();
ctx.arc(x, y, RADIUS, 0, degToRad(360), true);
ctx.fill();
}
canvasDraw();
// pointer lock object forking for cross browser
canvas.requestPointerLock = canvas.requestPointerLock ||
canvas.mozRequestPointerLock;
document.exitPointerLock = document.exitPointerLock ||
document.mozExitPointerLock;
canvas.onclick = function() {
canvas.requestPointerLock();
};
// pointer lock event listeners
// Hook pointer lock state change events for different browsers
document.addEventListener('pointerlockchange', lockChangeAlert, false);
document.addEventListener('mozpointerlockchange', lockChangeAlert, false);
function lockChangeAlert() {
if (document.pointerLockElement === canvas ||
document.mozPointerLockElement === canvas) {
console.log('The pointer lock status is now locked');
document.addEventListener("mousemove", updatePosition, false);
} else {
console.log('The pointer lock status is now unlocked');
document.removeEventListener("mousemove", updatePosition, false);
}
}
var tracker = document.getElementById('tracker');
var animation;
function updatePosition(e) {
x += e.movementX;
y += e.movementY;
if (x > canvas.width + RADIUS) {
x = -RADIUS;
}
if (y > canvas.height + RADIUS) {
y = -RADIUS;
}
if (x < -RADIUS) {
x = canvas.width + RADIUS;
}
if (y < -RADIUS) {
y = canvas.height + RADIUS;
}
tracker.textContent = "X position: " + x + ", Y position: " + y;
if (!animation) {
animation = requestAnimationFrame(function() {
animation = null;
canvasDraw();
});
}
}
I want the HTML5 canvas to never end so that the square never stops moving, it keeps on "running" so that it can jump over obstacles and the score increases etc. I really do not know how to do this. Please help and thanks in advance. I have posted my code below for everyone to see, I incorporated the JS into the HTML, yep.
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<meta charset="UTF-8">
<title>Move Square</title>
</head>
<body>
<div id="centre">
<canvas id="myCanvas" height="100px" width="200px"></canvas>
</div>
<script>
function draw(){
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.fillStyle = "grey";
ctx.fillRect(0,0,300,300);
ctx.fillRect(0,0,300,300);
ctx.closePath();
x+=dx/4;
//Draw Square
ctx.fillStyle = "red";
ctx.fillRect(x,y,20,20);
clearRect(0, 0, canvas.width, canvas.height);
}
var x = 20;
var y = 20;
var dx = 5;
var dy = 5;
setInterval(draw,10);
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) {
if(e.keyCode == 39) {
x+=dx;
}
}
</script>
</body>
</html>
You need to make every other object on the canvas move backward if you want your block to run endlessly "forward." Of course, to do this you would need to add another object for reference.
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<meta charset="UTF-8">
<title>Move Square</title>
</head>
<body>
<div id="centre">
<canvas id="myCanvas" height="100px" width="200px"></canvas>
</div>
<script>
function draw(){
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.fillStyle = "grey";
ctx.fillRect(0,0,300,300);
ctx.fillRect(0,0,300,300);
ctx.closePath();
//Draw Square
ctx.fillStyle = "red";
ctx.fillRect(x,y,20,20);
//Two extra green squares
ctx.fillStyle = "green";
ctx.fillRect(x2,50,20,20);
ctx.fillRect(x3,50,20,20);
//make them move backwards at the same speed
x2 -= dx/4;
x3 -= dx/4;
}
var x = 20;
var y = 20;
var dx = 5;
var dy = 5;
//X coordinates for green blocks:
var x2 = 50;
var x3 = 250;
setInterval(draw,10);
document.addEventListener("keydown", keyDownHandler, false);
//document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) {
if(e.keyCode == 39) {
x+=dx;
}
}
</script>
</body>
</html>
how to get mouseover to draw on html canvas with event listener with my code? https://jsfiddle.net/dannixx/d0p0j8cL/
jifiddle file, i want to be able to draw line on canvas with mouseover https://jsfiddle.net/dannixx/d0p0j8cL/
<!DOCTYPE html>
<html>
<head>
<title>Canvas</title>
<style type="text/css">
#Canvas1 {
border: : dotted 3px black;
background-color: blue;
}
</style>
<script>
window.onload = function(){
var theCanvas = document.getElementById("Canvas1");
if (theCanvas && document.getContext("2d")){
var ctx = theCanvas.getContext("2d";)
if(ctx){
ctx.fillStyle = "lightblue";
ctx.fillRect(0,0 ctx.canvas.width, ctx.canvas.height)
}
}
}
</script>
</head>
<body>
<h1>cnavas</h1>
<p>ex</p>
<canvas id="Canvas1" width="400", height="300"></canvas>
<p id="demo"></p>
</body>
</html>
Here is a really simple example using a onmousemove listener that updates the new mouse coordinates and draws a line from the previous coordinates to the new coordinates. Run it and see!
var x = null;
var y = null;
var c = null;
var ctx = null;
function getPos(e) {
//if it is the first time the event listener is called then set x and y to the new mouse coordinate
if(x == null) {
x=e.clientX;
y=e.clientY;
}
//otherwise draw from the previous point (x, y) to the new coordinates (e.clientX, e.clientY).
ctx.beginPath();
ctx.moveTo(x,y);
ctx.lineTo(e.clientX,e.clientY);
ctx.stroke();
x=e.clientX;
y=e.clientY;
}
window.onload = function(){
c=document.getElementById("Canvas1");
ctx=c.getContext("2d");
}
<canvas onmousemove="getPos(event)" id="Canvas1" width="400", height="300"></canvas>
Here is a simple example script (using the stroke method) for drawing on a canvas:
HTML :
<canvas id="can1"></canvas>
CSS :
#can1 {
border:dashed 3px #000;
}
JavaScript :
var can = document.getElementById("can1");
var canCtx = can.getContext("2d");
var sx = 0, sy = 0;
var clicked = false;
function _left(e){
return e.pageX - can.offsetLeft;
}
function _top(e){
return e.pageY - can.offsetTop;
}
function _draw(e, sx, sy){
var x = _left(e);
var y = _top(e);
canCtx.moveTo(sx, sy);
canCtx.lineTo(x, y);
canCtx.strokeStyle="red";
canCtx.stroke();
}
can.addEventListener("mousedown", function(e){
sx = _left(e);
sy = _top(e);
_draw(e, sx, sy);
clicked = true;
}, false);
can.addEventListener("mousemove", function(e){
if(clicked == true){
_draw(e, can);
}
}, false);
addEventListener("mouseup", function(){
clicked = false;
}, false);