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>
Related
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>
i am trying to make a blue square move across the X axis when i click the button i made.
When i push the button nothing happens. I dont know what im doing wrong.
Here is the code:
<html>
<head>
<canvas id="myCanvas" width="600" height="600"></canvas>
<title>tilte</title>
</head>
<body>
<button onclick="draw">/button>
<script>
onload = function() {
var canvas = document.getElementById("myCanvas")
var ctx = canvas.getContext("2d")
var recX = 250
var recY = 500
var speedX = 5;
draw()
move()
function draw() {
ctx.fillStyle = "red"
ctx.fillRect(0, 0, 600, 600)
ctx.fillStyle = "blue"
ctx.fillRect(recX, recY, 50, 50)
}
}
</script>
</body>
</html>
change the onload function into onClick, and call "onClick();" from the button...
<canvas id="myCanvas" width="600" height="600"></canvas>
<button onclick="onClick();">click to draw</button>
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
function onClick()
{
let recX = 250;
let recY = 500;
let speedX = 5;
draw(recX,recY);
move();
}
function draw(recX,recY)
{
ctx.fillStyle = "red";
ctx.fillRect(0, 0, 600, 600);
ctx.fillStyle = "blue";
ctx.fillRect(recX, recY, 50, 50);
}
</script>
is all you need
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>
So I have this rectangle that animates across to the right. How can I get the rectangle to reverse it when it hits the boundaries. I'm trying to make it go back and forth.
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript'>
window.onload=function(){
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var x = 0;
var y = 50;
var width = 10;
var height = 10;
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(x, y, width, height);
x++;
if(x <= 490) {
setTimeout(animate, 33);
}
}
animate();
}
</script>
</head>
<body>
<canvas id="canvas" width="500" height="400"
style="border: 1px solid #000000;"></canvas>
</body>
</html>
https://codepen.io/forTheLoveOfCode/pen/wqdpeg
Is that what you need? (link to codepen above).
var canvas = document.getElementById("canvas_id");
var context = canvas.getContext('2d');
var x=5;
var y=5;
var velocity = 10;
function move(){
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
x =x + velocity
if ((x+50)>canvas.width || x<0){
velocity *=-1;
}
draw()
}
function draw(){
context.fillStyle = "#E80C7A";
context.strokeStyle = "#000000";
context.lineWidth = '3';
context.fillRect(x, y, 50, 100);
context.strokeRect(x, y, 50, 100);
}
setInterval(move, 100);
<html>
<body>
<canvas id = "canvas_id">
</canvas>
</body>
</html>
here's a solution with boundaries detection
window.onload=function(){
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var x = 0;
var y = 50;
var width = 10;
var height = 10;
var speed = 10; // speed
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(x, y, width, height);
if(
(x >= 500 - width && speed > 0) || // going to the right and bound reached
(x <= 0 && speed < 0) // going to the left and bound reached
) {
speed *= -1; // inverting the direction
}
x += speed;
setTimeout(animate, 33);
}
animate();
}
<canvas id="canvas" width="500" height="400"
style="border: 1px solid #000000;"></canvas>
consider using requestAnimationFrame instead of setTimeout to do this kind of work.
i have a little problem, i have made 3 radial progress bars with canvas and js (following more or less the guide on thecodeplayer.com).
The result is almost good, and it's working, the problem is that if i have multiple bars the last one takes the percentage from the first. In my example the first is 65% and the last should be 88% but it take the data-attribute from the first.
Here is the code
Javascript:
window.onload = function(){
var canvas = document.getElementsByTagName('canvas');
for (var i = 0; i < canvas.length; i++) {
progressBar(canvas[i].id);
}
// load the canvas
function progressBar(canvasId) {
var canvas = document.getElementById(canvasId);
var ctx = canvas.getContext('2d');
// declare some variables
var cWidth = canvas.width;
var cHeight = canvas.height;
var progressColor = 'lightblue';
var circleColor = '#333';
var rawPerc = canvas.getAttribute('data-perc');
var definition = canvas.getAttribute('data-text');
var perc = parseInt(rawPerc);
var degrees = 0;
var endDegrees = (360*perc)/100;
var lineWidth = 10; // The 'brush' size
console.log(canvasId+' '+perc);
function getDegrees() {
if(degrees < endDegrees) {
degrees++;
}
else {
clearInterval(degreesCall);
}
drawProgressBar();
}
function drawProgressBar() {
//clear the canvas after every instance
ctx.clearRect(0,0,cWidth,cHeight);
// let's draw the background circle
ctx.beginPath();
ctx.strokeStyle = circleColor;
ctx.lineWidth = lineWidth -1;
ctx.arc(cHeight/2, cWidth/2, cWidth/3, 0, Math.PI*2, false);
ctx.stroke();
var radians = 0; // We need to convert the degrees to radians
radians = degrees * Math.PI/180;
// let's draw the actual progressBar
ctx.beginPath();
ctx.strokeStyle = progressColor;
ctx.lineWidth = lineWidth;
ctx.arc(cHeight/2, cWidth/2, cWidth/3, 0 - 90*Math.PI/180, radians - 90*Math.PI/180, false);
ctx.stroke();
// let's get the text
ctx.fillStyle = progressColor;
ctx.font = '20px Arial';
var outputTextPerc = Math.floor(degrees/360*100)+'%';
var outputTextPercWidth = ctx.measureText(outputTextPerc).width;
var outputTextDefinitionWidth = ctx.measureText(definition).width;
ctx.fillText(outputTextPerc, cWidth/2 - outputTextPercWidth/2, cHeight/2 - 10);
ctx.fillText(definition, cWidth/2 - outputTextDefinitionWidth/2, cHeight/2 + 15);
}
degreesCall = setInterval(getDegrees, 10/(degrees - endDegrees));
}
}
(sorry for the bad indend)
HTML:
<canvas id="canvas-3" width="300" height="300" data-text="Radial 1" data-perc="65"></canvas>
<canvas id="canvas-4" width="300" height="300" data-text="Radial 2" data-perc="90"></canvas>
<canvas id="canvas-1" width="450" height="450" data-text="Radial 3" data-perc="88"></canvas>
I have made a working jsfiddle at http://jsfiddle.net/ranqgnr8/.
Any idea why it's taking tha first percentage?
thanks to all who are reading.
EDIT:
the strange thing is that in the console log the percentage is right.
You forgot to define the degreesCall variable, so it ends up in the global space and you override the same interval
var canvas = document.getElementsByTagName('canvas');
for (var i = 0; i < canvas.length; i++) {
progressBar(canvas[i].id);
}
// load the canvas
function progressBar(canvasId) {
var degreesCall;
var canvas = document.getElementById(canvasId);
var ctx = canvas.getContext('2d');
// declare some variables
var cWidth = canvas.width;
var cHeight = canvas.height;
var progressColor = 'lightblue';
var circleColor = '#333';
var rawPerc = canvas.getAttribute('data-perc');
var definition = canvas.getAttribute('data-text');
var perc = parseInt(rawPerc);
var degrees = 0;
var endDegrees = (360*perc)/100;
var lineWidth = 10; // The 'brush' size
console.log(canvasId+' '+perc);
function getDegrees() {
if(degrees < endDegrees) {
degrees++;
}
else {
clearInterval(degreesCall);
}
drawProgressBar();
}
function drawProgressBar() {
//clear the canvas after every instance
ctx.clearRect(0,0,cWidth,cHeight);
// let's draw the background circle
ctx.beginPath();
ctx.strokeStyle = circleColor;
ctx.lineWidth = lineWidth -1;
ctx.arc(cHeight/2, cWidth/2, cWidth/3, 0, Math.PI*2, false);
ctx.stroke();
var radians = 0; // We need to convert the degrees to radians
radians = degrees * Math.PI/180;
// let's draw the actual progressBar
ctx.beginPath();
ctx.strokeStyle = progressColor;
ctx.lineWidth = lineWidth;
ctx.arc(cHeight/2, cWidth/2, cWidth/3, 0 - 90*Math.PI/180, radians - 90*Math.PI/180, false);
ctx.stroke();
// let's get the text
ctx.fillStyle = progressColor;
ctx.font = '20px Arial';
var outputTextPerc = Math.floor(degrees/360*100)+'%';
var outputTextPercWidth = ctx.measureText(outputTextPerc).width;
var outputTextDefinitionWidth = ctx.measureText(definition).width;
ctx.fillText(outputTextPerc, cWidth/2 - outputTextPercWidth/2, cHeight/2 - 10);
ctx.fillText(definition, cWidth/2 - outputTextDefinitionWidth/2, cHeight/2 + 15);
}
degreesCall = setInterval(getDegrees, 10/(degrees - endDegrees));
}
body {
padding-top: 100px;
background: #555;
}
canvas {
display: inline-block;
margin: auto;
}
<canvas id="canvas-3" width="300" height="300" data-text="Radial 1" data-perc="65"></canvas>
<canvas id="canvas-4" width="300" height="300" data-text="Radial 2" data-perc="90"></canvas>
<canvas id="canvas-1" width="450" height="450" data-text="Radial 3" data-perc="88"></canvas>