How to draw on the canvas? - javascript

I have a blue circle which is revolving around the red circle and both are moving to right combined.
I need to draw on the canvas on the path of the red circle moves, but I don't want the blue circle to draw.
at present the circle is moving along right but I want the circle to move in the direction of blue circle at the point of time of mouse press.
const canvas = document.getElementById('canvas1');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let positionX = 100;
let positionY = 100;
let X = 50;
let Y = 50;
let angle = 0;
function circle(){
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.arc(X, Y, 20, 0, Math.PI*2);
ctx.closePath();
ctx.fill();
}
function direction(){
ctx.fillStyle = 'blue';
ctx.beginPath();
ctx.arc(positionX + X, positionY + Y, 10, 0, Math.PI*2);
ctx.closePath();
ctx.fill();
}
function animate(){
ctx.clearRect(0,0, canvas.width, canvas.height);
circle();
direction();
positionX = 35 * Math.sin(angle);
positionY = 35 * Math.cos(angle);
X+=1;
angle += 0.1;
canvas.addEventListener('onclick', function(){
});
requestAnimationFrame(animate);
}
animate();
#canvas1{
position: absolute;
top:0;
left: 0;
width: 100%;
height: 100%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas basics</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="canvas1"></canvas>
<script src="script.js"></script>
</body>
</html>

Related

How to make a line follow mouse event arctanget with class javascript

Hi every one I'm trying to make a line follow the mouse move event. I can do this with the ctx.save and restore but i don't know how to do if i want use class and draw other object. In fact whit using save and restore It Work but if i want to have the same result whit class i dont know how to do many thanks
window.onload = function() {
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
arrowX = width / 2,
arrowY = height / 2,
dx, dy,
angle = 0,
a = 0;
render();
function render() {
arrowX = width / 2 + Math.cos(a) * height * .4;
arrowY = height / 2 + Math.sin(a) * height * .4;
context.clearRect(0, 0, width, height);
context.save();
context.translate(arrowX, arrowY);
context.rotate(angle);
context.beginPath();
context.moveTo(20, 0);
context.lineTo(-20, 0);
context.moveTo(20, 0);
context.lineTo(10, -10);
context.moveTo(20, 0);
context.lineTo(10, 10);
context.stroke();
context.restore();
requestAnimationFrame(render);
}
document.body.addEventListener("mousemove", function(event) {
dx = event.clientX - arrowX;
dy = event.clientY - arrowY;
angle = Math.atan2(dy, dx);
});
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="height: 100vh;">
<Canvas id="canvas"></Canvas>
<script src="main.js"></script>
</body>
</html>
If i want use class i start like thaïs on the following code
var canvas = document.getElementById("canvas");
var c = canvas.getContext("2d");
var width = canvas.width = window.innerWidth;
var height = canvas.height = window.innerHeight;
var arrowX = width / 2;
var arrowY = height -20;
var dx;
var dy;
var angle = 0;
class Player{
constructor(x,y,radius,color)
{
this.x=x;
this.y=y;
this.radius=radius;
this.color=color;
}
draw(){
c.beginPath();
c.arc(this.x,this.y,this.radius, 0, Math.PI *2,false );
c.fillStyle=this.color;
c.fill();
}
}
class Shooter{
constructor(x,y,xEnd,yEnd,color){
this.x=x;
this.y=y;
this.xEnd=xEnd;
this.yEnd=yEnd;
this.color=color;
}
draw(){
c.beginPath();
c.moveTo(this.x, this.y);
c.lineTo(this.xEnd, this.yEnd);
c.strokeStyle=this.color;
c.stroke();
}
}
// const player= new Player(arrowX,arrowY,20,'white');
const shooter= new Shooter(arrowX,500,arrowX,arrowY,'white');
let animationId;
function animate(){
animationId=requestAnimationFrame(animate)
c.fillStyle='rgba(0, 0, 0, 0.5)';
c.fillRect(0,0,canvas.width,canvas.height);
//player.draw();
shooter.draw();
}
requestAnimationFrame(animate);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="height: 100vh;">
<Canvas id="canvas"></Canvas>
<script src="main.js"></script>
</body>
</html>
I can offer two methods for this. The first is to simply have the end of the vector the same coordinates as the mouse position. This will change the magnitude of the vector of course.
This method does not rotate or translate the context.
var canvas = document.getElementById("canvas");
var c = canvas.getContext("2d");
var width = (canvas.width = window.innerWidth);
var height = (canvas.height = window.innerHeight);
let canvasBounds = canvas.getBoundingClientRect()
let mouse = {x: 0, y: 0}
class Shooter {
constructor(x, y, color) {
this.x = x;
this.y = y;
this.xEnd = mouse.x;
this.yEnd = mouse.y;
this.color = color;
}
draw() {
c.beginPath();
c.moveTo(this.x, this.y);
c.lineTo(this.xEnd, this.yEnd);
c.strokeStyle = this.color;
c.stroke();
}
update() {
this.xEnd = mouse.x;
this.yEnd = mouse.y;
}
}
const shooter = new Shooter(width/2, height/2, "white");
canvas.addEventListener("mousemove", e => {
mouse.x = e.x - canvasBounds.x;
mouse.y = e.y - canvasBounds.y;
});
function animate() {
animationId = requestAnimationFrame(animate);
c.fillStyle = "rgba(0, 0, 0, 0.5)";
c.fillRect(0, 0, canvas.width, canvas.height);
//player.draw();
shooter.draw();
shooter.update();
}
requestAnimationFrame(animate);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="height: 100vh;">
<Canvas id="canvas"></Canvas>
<script src="main.js"></script>
</body>
</html>
The second method draws the start point at (0, 0) but then you can use translate to position it where ever you want. This also rotates the context but allows you to keeps the magnitude the same.
var canvas = document.getElementById("canvas");
var c = canvas.getContext("2d");
var width = (canvas.width = window.innerWidth);
var height = (canvas.height = window.innerHeight);
let canvasBounds = canvas.getBoundingClientRect()
let mouse = {x: 0, y: 0}
class Shooter {
constructor(x, y, color) {
this.x = 0;
this.y = 0;
this.xEnd = this.x + 50;
this.yEnd = this.y;
this.translate = {x: x, y: y}
this.color = color;
this.angle = 0;
}
draw() {
this.angle = Math.atan2(mouse.y - this.translate.y, mouse.x - this.translate.x)
c.save();
c.translate(this.translate.x, this.translate.y);
c.rotate(this.angle);
c.beginPath();
c.moveTo(this.x, this.y);
c.lineTo(this.xEnd, this.yEnd);
c.strokeStyle = this.color;
c.stroke();
c.restore()
}
update() {
}
}
const shooter = new Shooter(width/2, height/2, "white");
canvas.addEventListener("mousemove", e => {
mouse.x = e.x - canvasBounds.x;
mouse.y = e.y - canvasBounds.y;
});
function animate() {
requestAnimationFrame(animate);
c.fillStyle = "rgba(0, 0, 0, 0.5)";
c.fillRect(0, 0, canvas.width, canvas.height);
//player.draw();
shooter.draw();
}
requestAnimationFrame(animate);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="height: 100vh;">
<Canvas id="canvas"></Canvas>
<script src="main.js"></script>
</body>
</html>

How to translate and make canvas responsive?

I am trying to move to translate the canvas to (100,100) but it is not moving.
And the canvas is not responsive, when I try to change the size of canvas using CSS the circles are shrinking.
How can I add a button to toggle the drawing on canvas by the circle (i.e.: when button pressed don't draw then the circle should not draw on canvas, when pressed draw it should draw)
requestAnimationFrame(animate);
var ctx = canvas1.getContext('2d');
ctx.translate(100,100);
canvas1.width = innerWidth;
canvas1.height = innerHeight;
const bgCan = copyCanvas(canvas1);
const redSize = 6, blueSize = 5; // circle sizes on pixels
const drawSpeed = 1; // when button down draw speed in pixels per frame
var X = 50, Y = 50;
var angle = 0;
var mouseButtonDown = false;
document.addEventListener('mousedown', () => mouseButtonDown = true);
document.addEventListener('mouseup', () => mouseButtonDown = false);
function copyCanvas(canvas) {
const can = Object.assign(document.createElement("canvas"), {
width: canvas.width, height: canvas.height
});
can.ctx = can.getContext("2d");
return can;
}
function circle(ctx){
ctx.fillStyle = 'black';
ctx.beginPath();
ctx.arc(X, Y, redSize, 0, Math.PI*2);
ctx.fill();
}
function direction(ctx){
const d = blueSize + redSize + 3;
ctx.fillStyle = 'blue';
ctx.beginPath();
ctx.arc(d * Math.sin(angle) + X, d * Math.cos(angle) + Y, blueSize, 0, Math.PI*2);
ctx.fill();
}
function animate(){
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(bgCan, 0, 0);
if (mouseButtonDown) {
circle(bgCan.ctx);
X += Math.sin(angle) * drawSpeed;
Y += Math.cos(angle) * drawSpeed;
} else {
angle += 0.1;
circle(ctx);
}
direction(ctx);
requestAnimationFrame(animate);
}
#canvas1{
position: absolute;
top:0;
left: 0;
width: 100%;
height: 100%;
border-width: 1px;
border-style: solid;
border-color: Black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas basics</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="canvas1"></canvas>
<input onclick="change()" type="button" value="Write" id="mybutton1"></input>
<script src="script.js"></script>
</body>
</html>
the translate(100, 100) gets reset by new width/height of the canvas. It just needs to be executed after width/height is set
The easiest way is to have a window resize listener and update canvas style width/height
I'm not sure why, but for some reason canvas has a higher z-index therefor button's onclick() never fired
In the code below I've added boundaries restriction, it's affected by translate(100, 100).
requestAnimationFrame(animate);
var ctx = canvas1.getContext('2d');
canvas1.width = innerWidth;
canvas1.height = innerHeight;
ctx.translate(100, 100);
const bgCan = copyCanvas(canvas1);
const redSize = 6,
blueSize = 5; // circle sizes on pixels
const drawSpeed = 1; // when button down draw speed in pixels per frame
const drawButton = document.getElementById("mybutton1");
var draw = true;
var X = 50,
Y = 50;
var angle = 0;
var mouseButtonDown = false;
document.addEventListener('mousedown', onMouseEvent);
document.addEventListener('mouseup', onMouseEvent);
function copyCanvas(canvas) {
const can = Object.assign(document.createElement("canvas"), {
width: canvas.width,
height: canvas.height
});
can.ctx = can.getContext("2d");
return can;
}
function circle(ctx, mousedown) {
if (mousedown && !draw)
return;
ctx.fillStyle = 'black';
ctx.beginPath();
ctx.arc(X, Y, redSize, 0, Math.PI * 2);
ctx.fill();
}
function direction(ctx) {
const d = blueSize + redSize + 3;
ctx.fillStyle = draw ? 'blue' : 'red';
ctx.beginPath();
ctx.arc(d * Math.sin(angle) + X, d * Math.cos(angle) + Y, blueSize, 0, Math.PI * 2);
ctx.fill();
}
function animate() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(bgCan, 0, 0);
if (mouseButtonDown) {
circle(bgCan.ctx, mouseButtonDown);
const x = X + Math.sin(angle) * drawSpeed,
y = Y + Math.cos(angle) * drawSpeed;
if (x > (blueSize + redSize) * 2 && x < canvas1.width - (blueSize + redSize) * 2 &&
y > (blueSize + redSize) * 2 && y < canvas1.height - (blueSize + redSize) * 2)
{
X = x;
Y = y;
}
} else {
angle += 0.1;
circle(ctx);
}
direction(ctx);
requestAnimationFrame(animate);
}
function onMouseEvent(e) {
if (e.target === drawButton) {
if (e.type == "mouseup")
{
draw = !draw;
document.getElementById("mybutton1").value = draw ? "Write" : "Move";
}
return;
}
mouseButtonDown = e.type == "mousedown";
}
window.addEventListener("resize", handleResize)
function handleResize ()
{
const ratio = canvas1.width / canvas1.height;
let h = window.innerHeight,
w = h * ratio;
if (w > window.innerWidth) {
w = window.innerWidth;
h = w / ratio;
}
canvas1.style.width = w + 'px';
canvas1.style.height = h + 'px';
};
handleResize(); // First draw
#canvas1 {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-width: 1px;
border-style: solid;
border-color: Black;
z-index: -1; /* let other elements receive events */
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas basics</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="canvas1" scaleMode='fill'></canvas>
<input type="button" value="Write" id="mybutton1" />
<script src="script.js"></script>
</body>
</html>

How to move an object on a canvas continuously in one direction for as long as the mouse button is down?

I have a red circle with a blue circle circling around it. I am trying to move the red circle in the direction of the blue circle when the mouse button is pressed.
But it currently only moves once.
I would like to have it moving continually while I press the mouse button, so that it keeps moving towards the direction of where the blue circle happens to be, keeping the blue circle ahead of it (and not circling) for as long as the mouse button is down.
Here is my code. Click the mouse button to see the reaction of the red circle:
const canvas = document.getElementById('canvas1');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let positionX = 100;
let positionY = 100;
let X = 50;
let Y = 50;
let angle = 0;
canvas.addEventListener('mousedown', function(){
X += positionX;
Y += positionY;
})
function circle(){
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.arc(X, Y, 20, 0, Math.PI*2);
ctx.closePath();
ctx.fill();
}
function direction(){
ctx.fillStyle = 'blue';
ctx.beginPath();
ctx.arc(positionX + X, positionY + Y, 10, 0, Math.PI*2);
ctx.closePath();
positionX = 35 * Math.sin(angle);
positionY = 35 * Math.cos(angle);
angle += 0.1;
ctx.fill();
}
function animate(){
ctx.clearRect(0,0, canvas.width, canvas.height);
circle();
direction();
requestAnimationFrame(animate);
}
animate();
#canvas1{
position: absolute;
top:0;
left: 0;
width: 100%;
height: 100%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="canvas1"></canvas>
<script src="script.js"></script>
</body>
</html>
If you want to continually have the red circle move towards the blue one, for as long as the mouse button is down, then you need to maintain the state of the mouse button. You can do that by keeping a global flag updated with a handler for the mousedown and the mouseup event.
Then move the code that updates X and Y into the animation loop: make that update when the flag is true (when the mouse button is down). On the other hand, only update the angle (for the blue circle) when the mouse button is not down:
const canvas = document.getElementById('canvas1');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let positionX = 100;
let positionY = 100;
let X = 50;
let Y = 50;
let angle = 0;
let mouseButtonDown = false;
document.addEventListener('mousedown', () => mouseButtonDown = true);
document.addEventListener('mouseup', () => mouseButtonDown = false);
function circle(){
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.arc(X, Y, 20, 0, Math.PI*2);
ctx.closePath();
ctx.fill();
}
function direction(){
ctx.fillStyle = 'blue';
ctx.beginPath();
ctx.arc(positionX + X, positionY + Y, 10, 0, Math.PI*2);
ctx.closePath();
positionX = 35 * Math.sin(angle);
positionY = 35 * Math.cos(angle);
ctx.fill();
}
function animate(){
if (mouseButtonDown) {
X += positionX / 10;
Y += positionY / 10;
} else {
angle += 0.1;
}
ctx.clearRect(0,0, canvas.width, canvas.height);
circle();
direction();
requestAnimationFrame(animate);
}
animate();
#canvas1{
position: absolute;
top:0;
left: 0;
width: 100%;
height: 100%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="canvas1"></canvas>
<script src="script.js"></script>
</body>
</html>

Why can't I move my circle inside the canvas?

I'm trying to move two circles separately, but I can't seem to make the two circles move despite searching over w3school or youtube, I know how to move one circle but when I try to move two circle by creating a constructor it fails.
I'm sure this is a dumb question but I just can't help but ask.
let canvas = document.querySelector("#canvas");
let ctx = canvas.getContext("2d");
let ball = new drawCircle(50, 50, 20);
let ballTwo = new drawCircle(100, 100, 20);
function drawCircle(x, y, r) {
this.x = x;
this.y = y;
this.r = r;
this.draw = function() {
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI *2);
ctx.fillStyle = "lightskyblue";
ctx.fill();
}
}
function draw() {
ball.x += 1;
ball.draw();
ballTwo.x += 1;
ballTwo.draw();
if (x + r > canvas.width || x < r) {
dx = -dx;
}
if (y + r > canvas.width || y < r) {
dy = -dy;
}
requestAnimationFrame(draw)
}
draw();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Círculo</title>
<style>
body {
margin: 0;
display: flex;
justify-content: center;
}
#canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="canvas" width="300" height="300"></canvas>
</body>
<script src="/js/canvasTwo.js"></script>
</html>

Creating forms and html

I want to create a basic form in HTML+JavaScript, how to create it?
Here's a HTML form created by me, JavaScript (snowing) I took from Internet
function myFunction(){
var canvas = document.getElementByName("vardas");
alert(canvas);
console.log(canvas);
}
window.onload = function(){
//canvas init
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
//canvas dimensions
var W = window.innerWidth;
var H = window.innerHeight;
canvas.width = W;
canvas.height = H;
//snowflake particles
var mp = 100; //max particles
var particles = [];
for(var i = 0; i < mp; i++)
{
particles.push({
x: Math.random()*W, //x-coordinate
y: Math.random()*H, //y-coordinate
r: Math.random()*4+1, //radius
d: Math.random()*mp //density
})
}
//Lets draw the flakes
function draw()
{
ctx.clearRect(0, 0, W, H);
ctx.fillStyle = "white";
ctx.beginPath();
for(var i = 0; i < mp; i++)
{
var p = particles[i];
ctx.moveTo(p.x, p.y);
ctx.arc(p.x, p.y, p.r, 0, Math.PI*2, true);
}
ctx.fill();
update();
}
//Function to move the snowflakes
//angle will be an ongoing incremental flag. Sin and Cos functions will be applied to it to create vertical and horizontal movements of the flakes
var angle = 0;
function update()
{
angle += 0.01;
for(var i = 0; i < mp; i++)
{
var p = particles[i];
//Updating X and Y coordinates
//We will add 1 to the cos function to prevent negative values which will lead flakes to move upwards
//Every particle has its own density which can be used to make the downward movement different for each flake
//Lets make it more random by adding in the radius
p.y += Math.cos(angle+p.d) + 1 + p.r/2;
p.x += Math.sin(angle) * 2;
//Sending flakes back from the top when it exits
//Lets make it a bit more organic and let flakes enter from the left and right also.
if(p.x > W+5 || p.x < -5 || p.y > H)
{
if(i%3 > 0) //66.67% of the flakes
{
particles[i] = {x: Math.random()*W, y: -10, r: p.r, d: p.d};
}
else
{
//If the flake is exitting from the right
if(Math.sin(angle) > 0)
{
//Enter from the left
particles[i] = {x: -5, y: Math.random()*H, r: p.r, d: p.d};
}
else
{
//Enter from the right
particles[i] = {x: W+5, y: Math.random()*H, r: p.r, d: p.d};
}
}
}
}
}
//animation loop
setInterval(draw, 33);
}
body {
/*You can use any kind of background here.*/
background: #6b92b9;
}
canvas {
position: absolute;
display: block;
}
<!DOCTYPE html>
<html>
<head>
<title>forms</title>
<meta http-equiv="Content-Type" content="text/html" charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="mystyle.css">
<script src="demo.js"></script>
<canvas id="canvas"></canvas>
</head>
<body>
your name:<br>
<input type="text" name="vardas"><br>
<button type="button">Click Me!</button>
</body>
</html>
The form is created but I can't write on it.
Add z-index: -10; to canvas style.
canvas {
display: block;
position: absolute;
z-index: -10;
}
Remove canvas tag from head and put in body
Edit as per your requirement
<!DOCTYPE html>
<html>
<head>
<title>forms</title>
<meta http-equiv="Content-Type" content="text/html" charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="mystyle.css">
<script src="demo.js"></script>
</head>
<body>
<canvas id="canvas" style="z-index:-10;"></canvas>
your name:<br>
<input type="text" name="vardas"><br>
<button type="button">Click Me!</button>
<!-- remove canvas tag from head and put in body-->
</body>
</html>

Categories

Resources