Im having issues moving a rectangle on a canvas - javascript

I created a script to move a rectangle but as it moves, it doesn't remove the previous ones from the canvas.
Here is my javascript.
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const box =25;
let snake=[];
snake[0]={x:5*box,y:4*box}
function draw(){
ctx.rect(snake[0].x, snake[0].y, box, box);
ctx.fillStroke="black";
ctx.strokeRect(snake[0].x, snake[0].y, box, box);
snake.pop();
snake.unshift({x:6*box,y:4*box});
}
let game=setInterval(draw,100)
<canvas></canvas>

You can issue ctx.clearRect on canvas object on start of each draw function call and that will do it for you
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const box = 25;
let snake = [];
snake[0] = {
x: 5 * box,
y: 4 * box
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.rect(snake[0].x, snake[0].y, box, box);
ctx.fillStroke = "black";
ctx.strokeRect(snake[0].x, snake[0].y, box, box);
snake.pop();
snake.unshift({
x: 6 * box,
y: 4 * box
});
}
let game = setInterval(draw, 350)
<canvas id=canvas></canvas>

Heres the correct way to create animations with canvas:
So you must create an animation frame the canvas can use to redraw the rectangle every time its moved.
Your issue is that youre drawing the same canvas over itself, so use ctx.clearRect(0, 0, cvs.width, cvs.height) to clear the entire canvas.
Also.... Please NEVER use intervals with canvas drawing. Only use animation frames like in my function. Just place it at the end of your main draw function, and itll repeat it forever.
Scroll down and hit "Run code snippet" to see my example run in the browser. As you notice, the rectangle will move smoothly and it leaves no trail behind.
const cvs = document.querySelector(".canvas"),
ctx = cvs.getContext("2d");
let rectX = -30;
function init() {
ctx.width = 300;
ctx.height = 300;
ctx.clearRect(0, 0, cvs.width, cvs.height);
ctx.fillRect(rectX - 25, cvs.height / 2 - 25, 50, 50);
rectX++;
if (rectX > 325) {
rectX = -25;
}
window.requestAnimationFrame(init);
}
init();
<canvas class="canvas" style="border:1px solid black"></canvas>

Related

How to shrink the size of arc/ellipse in HTML Canvas

Problem
I want to draw arc on HTML Canvas, by which an image is masked.
I could draw the arc, which has an animation of expansion.
But, I couldn't make it shrink or smaller...
What's the problem?
Google Chrome dev tool doesn't expose any errors.
Thansk in advance.
Codes
<canvas id="canvas" width="350" height="184"></canvas>
<script>
var w = 350;
var h = 184;
var c = 0;
window.onload = function () {
draw();
}
function draw() {
var canvas = document.getElementById('canvas');
if(!canvas || !canvas.getContext) return false;
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = "MY_IMAGE.jpg";
img.onload = () => {
setInterval(() => {
ctx.restore();
ctx.save();
ctx.beginPath();
ctx.arc(0, 0, w - c, Math.PI * 2, 0, false); // Doens't work!
// ctx.arc(0, 0, c, Math.PI * 2, 0, false); // Works! But I want to make the arc smaller, not bigger...
ctx.clip();
ctx.drawImage(img, 0, 0, 350, 184);
c += 1;
if(c >= w) {
c = 0;
}
}, 20);
}
}
The code is working fine. It just appears to not be working because you are not clearing your canvas between re-draw frames. Once something is drawn on canvas it stays there. So the image is shrinking but you aren’t seeing it because the bigger image is already drawn and stays on the screen.
Add ctx.clearRect(0,0,canvas.width,canvas.height)
Before you draw the image. You also don’t need the save and restore methods.

How to resize my canvas to fit the same content no matter the size

I am creating a game concept with this code: https://pastebin.com/pMNR1CfH. However, depending on the size of the window, more or less of the objects on screen will be shown. How can I resize it so the view remains the same?
I have these variables to try and scale the canvas, but I don't know where to place the canvas.scale function.
var scalewidth = window.innerWidth / 1920;
var scaleheight = window.innerHeight / 969;
thank you
I'll assume that you want to:
keep the aspect ratio of the graphics in tact (a circle should not be displayed as ellipse)
completely visualise the area (0,0)-(1920,969) being used to make the drawing
centre the graphics when there is spare room in one of the two dimensions of the view port.
Here is how you can do that:
let canvas = document.querySelector("canvas");
let ctx = canvas.getContext("2d");
window.addEventListener('resize', draw);
function draw() {
// Get current
let viewSizes = [canvas.width = window.innerWidth, canvas.height = window.innerHeight];
// Reset the canvas
ctx.setTransform(1, 0, 0, 1, 0, 0); // reset transformation
ctx.clearRect(0, 0, ...viewSizes); // wipe
// Determine scale factor
let worldSizes = [1920, 969];
let scales = worldSizes.map((worldSize, i) => viewSizes[i] / worldSize);
let minScale = Math.min(...scales);
// Determine shift in order to center the content
let shift = scales.map((scale, i) => (viewSizes[i] - minScale * worldSizes[i]) / 2);
ctx.setTransform(minScale, 0, 0, minScale, ...shift);
// Draw the contents using world coordinates (0,0)-(1920,969): This is demo
ctx.beginPath();
ctx.arc(960, 485, 484, 0, 2 * Math.PI);
ctx.fillStyle = "blue";
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.rect(10, 455, 1900, 60);
ctx.fillStyle = "red";
ctx.fill();
ctx.stroke();
}
draw();
body { margin: 0; overflow: hidden }
<canvas></canvas>

How to make a circle appear on any color html5 canvas

I have an arc on a canvas that moves around wherever the mouse is. it is stroked onto the canvas with the color black. if the mouse goes over something black, the circle disappears. i would like it if the circle could change color, depending on what it is being drawn over. could anyone help me?
here is some code:
ctx.beginPath()
ctx.clearRect(0, 0, brush.prePos.x + brush.size*2, brush.prePos.y + brush.size*2)
ctx.arc(pos.x, pos.y, brush.size / 4, 0, Math.PI*2)
ctx.stroke()
ctx.closePath()
You can try different compositing modes, particularly XOR. From the MDN example:
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.globalCompositeOperation = 'xor';
#SamiHult's answer is a good answer. Using globalCompositeOperation will do the trick. Here comes a demo:
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let cw = canvas.width = 300,
cx = cw / 2;
let ch = canvas.height = 300,
cy = ch / 2;
// the mouse
let m = {}
// draw a black circle
ctx.beginPath();
ctx.arc(100,100,45,0,2*Math.PI);
ctx.fill();
canvas.addEventListener("mousemove",(evt)=>{
m = oMousePos(canvas, evt);
ctx.clearRect(0,0,cw,ch);
// draw a circle stroked black following the mouse
drawCircle(m);
// draw a black circle
ctx.beginPath();
ctx.arc(100,100,45,0,2*Math.PI);
ctx.fill();
// the important part:
ctx.globalCompositeOperation = "xor";
})
function drawCircle(p){
ctx.beginPath();
ctx.arc(p.x,p.y,10,0,2*Math.PI);
ctx.stroke();
}
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return { //objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}
canvas {
border:1px solid;
}
<canvas id="canvas"></canvas>

<canvas> clearRect() in a letter shape

I've recently started learning web techniques, so I'm still a newbie regarding pretty much everything. I've stumbled upon this portfolio site, link, which I'm trying to "recreate" as part of my learning process/practice.
Here I'm interested in the background of the page, and how to make that transparent letter on canvas. In my current work, I have a html background image set, fillRect() on a full screen with opacity of 0.9 , and now I don't know how to make use of clearRect().
The question is: Am I on the right track, and is there any way that I'm not aware of, in which I can use clearRect() to clear pixels on canvas in a letter shape? Like, without manually defining a path for clearRect(), but where I would only input a letter and clear pixels in its shape. Sorry if I posted my current code below the wrong way, it's my first time posting here.
var canvas = document.getElementById('layout');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
}
$(document).ready(function() {
window.addEventListener('resize', setCanvasSize); //false
window.addEventListener('resize', draw); //false
//set canvas size----------------------------------------
setCanvasSize();
function setCanvasSize() {
canvas.width = $(window).width();
canvas.height = $(window).height();
}
//draw---------------------------------------------------
draw();
function draw() {
var x = canvas.width;
var y = canvas.height;
ctx.fillStyle = "white";
ctx.fillRect(0, 0, x, y);
ctx.clearRect(50, 30, 110, 35);
}
});
You can achieve effects such as this using globalCompositeOperation.
Here's an example where some text is used as shape to erase drawn pixels:
var canvas = document.createElement("canvas");
canvas.width = 300;
canvas.height = 200;
var ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
ctx.fillStyle = "rgba(255, 255, 255, 0.8";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = "destination-out";
ctx.font = "70pt Arial";
ctx.fillText("Text", 50, 130);
Here's the JSFiddle: http://jsfiddle.net/eSpUv/

Moving Objects on html5 Canvas

I placed an text on html5 canvas object using fillText option, question is I need to move the text position or change the color of the text that is already rendered.
Shortly I need to know how to Manipulate particular child of canvas element
This will move a small circle over your canvas
var can = document.getElementById('canvas');
can.height = 1000; can.width = 1300;
var ctx = can.getContext('2d');
var x = 10, y = 100;
ctx.fillStyle = "black";
ctx.fillRect(700, 100, 100, 100);
function draw() {
ctx.beginPath();
ctx.arc(x, y, 20, 0, 2 * Math.PI);
ctx.fillStyle = 'rgba(250,0,0,0.4)';
ctx.fill();
x += 2;
ctx.fillStyle = "rgba(34,45,23,0.4)";
ctx.fillRect(0, 0, can.width, can.height);
requestAnimationFrame(draw);
//ctx.clearRect(0,0,can.width,can.height);
}
draw();
<canvas id="canvas" style="background:rgba(34,45,23,0.4)"></canvas>
I think there is no object model behind the canvas, so you cannot access a "child object" like a "text object" and change it.
What you can do is that you draw the text again with a different color that overwrites the "pixels" of the canvas.
If you want to move the text, first you have to either clear the canvas or re-draw the text with a background/transparent color to get rid of the text in the previous position. Then you can draw the text in the new position.
I've never tried it but I think this would be the way to do it.
var canvas = document.getElementById("canvas"); //get the canvas dom object
var ctx = canvas.getContext("2d"); //get the context
var c = { //create an object to draw
x:0, //x value
y:0, //y value
r:5; //radius
}
var redraw = function(){ // this function redraws the c object every frame (FPS)
ctx.clearRect(0, 0, canvas.width, canvas.height); // clear the canvas
ctx.beginPath(); //start the path
ctx.arc(c.x, c.y, c.r, 0, Math.PI*2); //draw the circle
ctx.closePath(); //close the circle path
ctx.fill(); //fill the circle
requestAnimationFrame(redraw);//schedule this function to be run on the next frame
}
function move(){ // this function modifies the object
var decimal = Math.random() // this returns a float between 0.0 and 1.0
c.x = decimal * canvas.width; // mulitple the random decimal by the canvas width and height to get a random pixel in the canvas;
c.y = decimal * canvas.height;
}
redraw(); //start the animation
setInterval(move, 1000); // run the move function every second (1000 milliseconds)
Here is a fiddle for it.
http://jsfiddle.net/r4JPG/2/
If you want easing and translations, change the move method accordingly.
Hope it is allowed to advertise somebody's project.
Take a look at http://ocanvas.org/ you can get inspiration there.
It is object like canvas library. Allows you to handle events, make animations etc.
<html>
<head>
<title>Canvas Exam</title>
</head>
<body>
<canvas id="my_canvas" height="500" width="500" style="border:1px solid black">
</canvas>
<script>
var dom=document.getElementById("my_canvas");
var ctx=dom.getContext("2d");
var x1=setInterval(handler,1);
var x=50;
var y=50;
r=40;
function handler()
{
ctx.clearRect(0,0,500,500);
r1=(Math.PI/180)*0;
r2=(Math.PI/180)*360;
ctx.beginPath();
//x=x*Math.random();
x=x+2;
r=r+10*Math.random();
ctx.arc(x,y,r,r1,r2);
ctx.closePath();
ctx.fillStyle="blue";
ctx.fill();
ctx.stroke();
if(x>400)
{
x=50;
y=y+10;
}
r=40;
}
</script>
</body>
</html>

Categories

Resources