set grid made by js on the background of canvas - javascript

I try to make paint app in javascript. I need to make square grid and by pushing button. I made such grid but it is not on the background. How should I pass grid made by js on the background?
function print_grid()
{
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillRect(0, 0, 5100, 5100);
ctx.clearRect(0, 0, 5100, 5100);
ctx.beginPath();
for (let i = 0; i < 39; i++)
{
ctx.lineWidth = 1;
ctx.moveTo(50*i, 0);
ctx.lineTo(50*i, 5100);
ctx.moveTo(0, 50*i);
ctx.lineTo(5100, 50*i);
}
ctx.stroke();
}
<!DOCTYPE html>
<html>
<body>
<h1>Board</h1>
<button onclick="print_grid()">square</button>
<p >draw!!!</p>
<canvas id="myCanvas" width="1000" height="1000" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
</body>
</html>

One easy solution is using two canvases layered on top of each other. This way you can draw the grid onto the background layer independent from the canvas in the foreground.
Here's an example:
const canvas = document.getElementById('canvas2');
const ctx = canvas.getContext('2d');
let coordinates = {
x: 0,
y: 0
};
let painting = false;
function getPosition(event) {
coordinates.x = event.clientX - canvas.offsetLeft;
coordinates.y = event.clientY - canvas.offsetTop;
}
function startPainting(event) {
painting = true;
getPosition(event);
}
function stopPainting() {
painting = false;
}
function draw(event) {
if (!painting) return;
ctx.beginPath();
ctx.lineWidth = 5;
ctx.lineCap = 'round';
ctx.strokeStyle = 'red';
ctx.moveTo(coordinates.x, coordinates.y);
getPosition(event);
ctx.lineTo(coordinates.x, coordinates.y);
ctx.stroke();
}
function clearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
function printGrid() {
let backgroundCanvas = document.getElementById('canvas');
let context = backgroundCanvas.getContext("2d");
context.beginPath();
for (let a = 0; a < 10; a++) {
context.moveTo(0, parseInt(a * (backgroundCanvas.height / 9)));
context.lineTo(backgroundCanvas.width, parseInt(a * (backgroundCanvas.height / 9)));
context.moveTo(parseInt(a * (backgroundCanvas.width / 9)), 0);
context.lineTo(parseInt(a * (backgroundCanvas.width / 9)), backgroundCanvas.height);
}
context.stroke();
context.closePath();
}
printGrid();
document.addEventListener('mousedown', startPainting);
document.addEventListener('mouseup', stopPainting);
document.addEventListener('mousemove', draw);
<button onclick='clearCanvas();'>Clear</button>
<div>
<canvas id='canvas' style='position: absolute'></canvas>
<canvas id='canvas2' style='position: absolute'></canvas>
</div>

Related

javascript my arc is not showing up or moving across the screen

hello i am trying to make a white circle move across a black box in javascript my circle is not showing up the big black box does but the circle does not show up i dont know why i am loading the page in google chrome here is the code
<html>
<head>
<title>paddle</title>
</head>
<body>
<canvas id="myCanvas" width="800" height="600"></canvas>
<script>
var canvas
var canvasContext
var ballX = 5
window.onload = function() {
var fps = 30;
setInterval(updateAll, 1000)
canvas = document.getElementById("myCanvas");
canvasContext = canvas.getContext("2d")
canvasContext.fillStyle = "black"
canvasContext.fillRect(0, 0, canvas.width, canvas.height)
}
function updateAll() {
ballX++
canvasContext.fillStyle = "white";
canvasContext.beginPath()
canvasContext.arc(ballX, 100, 10, 0, Math.PI*2, true);
canvasContext.stroke()
}
</script>
</body>
</html>
The problem is that you are using stroke to draw the circle but you have not set the stroke style which is by default black. So you are drawing a black circle on a black background. Hence no see circle.
Also it is best to use requestAnimationFrame to animate rather than set interval.
Example animating a circle
requestAnimationFrame(animationLoop);
const ctx = myCanvas.getContext("2d");
var ballX = 5;
var speed = 1
const radius = 10;
const fps = 30;
var frameCount = 0;
function animationLoop() {
if (frameCount % (60 / fps) === 0) {
ctx.fillStyle = "black"
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
draw();
}
frameCount ++;
requestAnimationFrame(animationLoop);
}
function draw() {
ballX = (ballX + speed) % (ctx.canvas.width + radius * 2);
ctx.strokeStyle = "white";
ctx.lineWidth = 2;
ctx.beginPath()
ctx.arc(ballX - radius, 20, 10, 0, Math.PI * 2);
ctx.stroke()
}
<canvas id="myCanvas" width="600" height="40"></canvas>

How to undraw the a rectangle when recalling a function [duplicate]

This question already has answers here:
How to clear the canvas for redrawing
(25 answers)
Closed 3 years ago.
I want to make a rectangle that moves from the right to the left.
I could draw a new rectangle in the left of the previous one but i couldn't erase the previous one.
Here is my code:
let cvs = document.getElementById("canvas");
let ctx = cvs.getContext('2d');
let firstpos = 400;
let blocks = [];
blocks[0] = {
x: 400,
y: Math.floor(Math.random() * 360)
}
function draw() {
for (var i = 0; i < blocks.length; i++) {
ctx.beginPath()
ctx.fillStyle = "white";
ctx.fillRect(blocks[i].x, 0, 70, blocks[i].y);
ctx.fill();
blocks[i].x -= 0;
}
requestAnimationFrame(draw);
}
draw()
#canvas {
background-color: #000;
}
<canvas id="canvas" width="1000" height="500"></canvas>
Working snippet
Take advantage of CanvasRenderingContext2D.clearRect()
let cvs = document.getElementById("canvas");
let ctx = cvs.getContext('2d');
let firstpos = 400;
let blocks = [];
blocks[0] = {
x: 0,
y: Math.floor(Math.random() * 360)
}
function draw() {
blocks[0].x++;
ctx.clearRect(0, 0, canvas.width, canvas.height); // canvas clear up
for (var i = 0; i < blocks.length; i++) {
ctx.beginPath()
ctx.fillStyle = "white";
ctx.fillRect(blocks[i].x, 0, 70, blocks[i].y);
ctx.fill();
blocks[i].x -= 0;
}
requestAnimationFrame(draw);
}
setInterval(draw, 500)
#canvas {
background-color: #000;
}
<canvas id="canvas" width="1000" height="500"></canvas>
It's not possible to "undraw" something in canvas. However, you can clear the canvas on each frame with clearRect and re-draw everything in a new position.
Additionally, the current code uses blocks[i].x -= 0; which won't change the animation state even with a clear and redraw.
Parameters to fillRect appear incorrect or mislabeled. ctx.fillRect(blocks[i].x, 0, 70, blocks[i].y); should be ctx.fillRect(blocks[i].x, blocks[i].y, width, height);. There's also no need for creating a path or calling fill for this method.
It's typical to encapsulate all data for a block inside the object. We need a color, speed and x/y/height/width.
Note that y: Math.floor(Math.random() * 360) can result in a height of zero.
Here's a simple example of moving a block on the canvas:
const cvs = document.getElementById("canvas");
cvs.width = innerWidth;
cvs.height = innerHeight;
const ctx = cvs.getContext("2d");
const blocks = [{
x: innerWidth - 50,
y: 20,
velocityX: -1,
width: 50,
height: 50,
color: "white"
}];
(function draw() {
ctx.clearRect(0, 0, cvs.width, cvs.height);
for (const block of blocks) {
ctx.fillStyle = block.color;
ctx.fillRect(block.x, block.y, block.width, block.height);
block.x += block.velocityX;
}
requestAnimationFrame(draw);
})();
#canvas {
background-color: #000;
}
<canvas id="canvas"></canvas>

How to restart canvas drawing?

When I click start, I get whole circle. But when I click clean and again start, previously part of the circle remaining and straight line appear.
DEMO: https://fiddle.jshell.net/1xhkfk73/
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var draw = 0;
var stepDraw = 0;
ctx.strokeStyle = "#FF0000";
ctx.translate(0.5, 0.5);
var delay = 30;
var drawing = 0;
function drawCircle(steps) {
draw = ((2 * Math.PI) / steps);
stepDraw = draw;
drawing = setInterval(function() {
ctx.arc(400, 200, 120, draw, draw, false);
ctx.stroke();
draw += stepDraw;
}, delay)
}
$("#click").click(function() {
drawCircle(120);
});
$("#clean").click(function() {
clearInterval(drawing);
ctx.clearRect(0, 0, 800, 400);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="click">start</span>
<span id="clean">clean</span>
<canvas id="myCanvas" class="center-block" width="800" height="400">
Canvas not supported!
</canvas>
Try this.
You need to have your path closed.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var draw = 0;
var stepDraw = 0;
ctx.strokeStyle = "#FF0000";
ctx.translate(0.5, 0.5);
var delay = 30;
var drawing = 0;
function drawCircle(steps) {
draw = ((2 * Math.PI) / steps);
stepDraw = draw;
drawing = setInterval(function() {
ctx.beginPath();
ctx.arc(400, 200, 120, draw, draw+stepDraw, false);
ctx.stroke();
draw += stepDraw;
}, delay)
}
$("#click").click(function() {
drawCircle(120);
});
$("#clean").click(function() {
clearInterval(drawing);
ctx.clearRect(0, 0, 800, 400);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="click">start</span>
<span id="clean">clean</span>
<canvas id="myCanvas" class="center-block" width="800" height="400">
Canvas not supported!
</canvas>

2048 in javascript: updating the canvas

I am in a computer science class at my high school, and for my final project, my partner and I have decided to make 2048. We are not going to have the tiles "move", but instead, the 4x4 board will have "tiles" that are have properties of the number and color of the "tile" as it appears on the board. We are able to get the x and y coordinates of a tile to change, but the canvas will not update. We have had this problem for two weeks now, and have tried everything, but nothing has worked. Our code is posted below.
Please keep in mind that as we have only used javascript for a couple months, and only to do very simple things, our understanding is limited. Thank you for your help.
<!DOCTYPE html>
<html lang = "en">
<body style="background-color:lightgrey;">
<title>2048</title>
<canvas id="myCanvas" width="410" height="410" style="border:1px solid #d3d3d3;">
</canvas>
<script>
var x = 10;
var y = 10;
document.addEventListener('keydown', function(event)
{
if(event.keyCode == 37)//left
{
x -= 100;
console.log("x:"+ x);
}
else if(event.keyCode == 38)//up
{
y -= 100;
console.log("y:"+ y);
}
else if(event.keyCode == 39)//right
{
x += 100;
console.log("x:"+ x);
}
else if(event.keyCode == 40)//down
{
y += 100;
console.log("y:"+ y);
}
});
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// grey rectangle
ctx.beginPath();
ctx.lineWidth = "2";
ctx.strokeStyle = "grey";
ctx.rect(5, 5, 400, 400);
ctx.stroke();
// blue rectangle
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "blue";
ctx.rect(x, y, 100, 100);
ctx.stroke();
ctx.fillStyle = "blue";
ctx.fill();
</script>
</body>
</html>
What your game needs is a game loop. So the drawing needs to happen continously, at the moment you draw only one time at the beginning.
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
function draw() {
// clear the canvas so the old rectangles are gone
ctx.clearRect(0, 0, c.width, c.height);
// grey rectangle
ctx.beginPath();
ctx.lineWidth = "2";
ctx.strokeStyle = "grey";
ctx.rect(5, 5, 400, 400);
ctx.stroke();
// blue rectangle
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "blue";
ctx.rect(x, y, 100, 100);
ctx.stroke();
ctx.fillStyle = "blue";
ctx.fill();
}
// repeat game loop function forever, 30 times per second
window.setInterval(draw, 1000.0 / 30.0)
Notice the use of window.setInterval and ctx.clearRect.
Every time you want to update what is shown on the canvas, you have to 'Draw' again. Your code will run once when the page loads but never draws again so your changes to x and y are never seen.
I added a draw function here that is called on startup and after each keydown.
<!DOCTYPE html>
<html lang = "en">
<body style="background-color:lightgrey;">
<title>2048</title>
<canvas id="myCanvas" width="410" height="410" style="border:1px solid #d3d3d3;">
</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var x = 10;
var y = 10;
document.addEventListener('keydown', function(event)
{
if(event.keyCode == 37)//left
{
x -= 100;
console.log("x:"+ x);
}
else if(event.keyCode == 38)//up
{
y -= 100;
console.log("y:"+ y);
}
else if(event.keyCode == 39)//right
{
x += 100;
console.log("x:"+ x);
}
else if(event.keyCode == 40)//down
{
y += 100;
console.log("y:"+ y);
}
draw();
});
function draw(){
ctx.clearRect(0, 0, c.width, c.height);
// grey rectangle
ctx.beginPath();
ctx.lineWidth = "2";
ctx.strokeStyle = "grey";
ctx.rect(5, 5, 400, 400);
ctx.stroke();
// blue rectangle
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "blue";
ctx.rect(x, y, 100, 100);
ctx.stroke();
ctx.fillStyle = "blue";
ctx.fill();
}
draw();
</script>
</body>
</html>

How to rotate an image on HTML5 canvas when the right and left arrow keys are pressed

I need help trying to rotate the rectangle that I have drawn on the canvas. I would like the top of the rectangle to pivot either to the right or left once I press on the arrow keys on my keyboard. This is my code so far:
HTML:
<body >
<div id="canvas-container">
<canvas id="canvas" width="500" height="400"></canvas>
</div>
</body>
CSS:
canvas {
display: inline;
}
Javascript:
document.addEventListener("DOMContentLoaded", function() {
drawBorder();
});
var canvas;
var context;
var size;
drawRectangle();
drawHalfCircle();
function drawBorder() {
canvas = document.getElementById("canvas");
context = canvas.getContext('2d');
size = {
x: canvas.width,
y: canvas.height
};
//have to set colors etc befor it is drawn
context.strokeStyle = 'black';
//takes 4 parameters
context.strokeRect(0, 0, size.x, size.y);
}
function drawRectangle() {
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
ctx.rect(246, 290, 8, 80);
ctx.stroke();
}
function drawHalfCircle(){
var c= document.getElementById("canvas");
var ctx=c.getContext("2d");
ctx.beginPath();
ctx.arc(250,579,308,1.2*Math.PI, 1.8*Math.PI);
ctx.stroke();
}
I have mocked something up is this along the correct lines of what you are wanting.
document.addEventListener("DOMContentLoaded", function() {
drawBorder();
});
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
var size;
var angle = 0;
setInterval(function () {
context.save();
context.clearRect(0, 0, canvas.width, canvas.height);
drawBorder();
drawHalfCircle();
drawRectangle();
context.restore();
}, 100);
function drawBorder() {
size = {
x: canvas.width,
y: canvas.height
};
//have to set colors etc befor it is drawn
context.strokeStyle = 'black';
//takes 4 parameters
context.strokeRect(0, 0, size.x, size.y);
}
function drawRectangle() {
context.rotate(Math.PI / 180 * (angle));
context.rect(246, 290, 8, 80);
context.stroke();
}
function drawHalfCircle(){
context.beginPath();
context.arc(250,579,308,1.2*Math.PI, 1.8*Math.PI);
context.stroke();
}
document.onkeydown = function(e) {
var event = window.event ? window.event : e;
if (e.keyCode == '37') {
angle += 5;
}
else if (e.keyCode == '39') {
angle -= 5;
}
}
Basically set an interval and redraw (ie frames like in a movie) and rotate via a variable.
See a demo here
https://jsbin.com/qititacazu/edit?js,output
If you want to translate it so it will rotate around a different point do something like this.
context.translate(246, 290);
context.rotate(Math.PI / 180 * (angle));
context.rect(-4, 0, 4, 80);

Categories