I have 2 circles in the html canvas element, which I drew with Javascript. I want to make the first circle appear after 5 seconds.
I was wondering if you need to do this with Javascript and if so, how do you do this?
See the code for reference:
var c = document.getElementById("canvas1");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(30, 75, 20, 0,Math.PI*2);
ctx.stroke();
ctx.closePath;
ctx.beginPath();
ctx.arc(100,75,20,0,Math.PI*2);
ctx.stroke();
ctx.closePath();
#canvas1{
width: 300px;
height: 150px;
border: 1px solid black;
margin-top: 100px;
}
<canvas id="canvas1"></canvas>
use setTimeout method when the shape is created
setTimeout(function() {
ctx.beginPath();
ctx.arc(30, 75, 20, 0,Math.PI*2);
ctx.stroke();
ctx.closePath;
ctx.beginPath();
ctx.arc(100,75,20,0,Math.PI*2);
ctx.stroke();
ctx.closePath();
},5000)
You can use global function setTimeout, e.g. like this:
var c = document.getElementById("canvas1")
var ctx = c.getContext("2d")
function circle(a1, a2, a3, a4) {
ctx.beginPath()
ctx.arc(a1, a2, a3, a4 ,Math.PI*2)
ctx.stroke()
ctx.closePath()
}
setTimeout(circle, 5000 /*time in ms*/, 30, 75, 20, 0)
circle(100, 75, 20, 0)
#canvas1{
width: 300px;
height: 150px;
border: 1px solid black;
margin-top: 100px;
}
<canvas id="canvas1"></canvas>
Related
This question already has answers here:
Canvas is stretched when using CSS but normal with "width" / "height" properties
(10 answers)
Closed 5 months ago.
Hello I have a simple question. I am trying to draw a circle with ctx.arc(), but the output is always an oval. May I know what is my mistake here?
const canvas = document.querySelector("#canvas");
const ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.fillStyle = "red";
ctx.arc(300, 130, 100, 0, Math.PI * 2);
ctx.fill();
#canvas {
border: 1px solid black;
width: 640px;
height: 640px;
}
<canvas id="canvas">My Canvas</canvas>
The canvas needs to know the number of logical pixels in both height and width to draw the shapes in the right dimensions.
Explicitly set the width and height property of the canvas to fix the drawing.
const canvas = document.querySelector("#canvas");
const ctx = canvas.getContext("2d");
canvas.width = 640;
canvas.height = 640;
ctx.beginPath();
ctx.fillStyle = "red";
ctx.arc(300, 130, 100, 0, Math.PI * 2);
ctx.fill();
#canvas {
border: 1px solid black;
width: 640px;
height: 640px;
}
<canvas id="canvas">My Canvas</canvas>
Alternatively you could also set the properties as attributes in your HTML.
const canvas = document.querySelector("#canvas");
const ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.fillStyle = "red";
ctx.arc(300, 130, 100, 0, Math.PI * 2);
ctx.fill();
#canvas {
border: 1px solid black;
width: 640px;
height: 640px;
}
<canvas id="canvas" width="640" height="640">My Canvas</canvas>
I am trying to render two rectangles one on the top of other inside canvas element with globalCompositeOperation set to 'source-out' and globalAlpha set to 0.2. However globalAlpha is not working on Safari and the outer rectangle in getting rendered with opacity 1.
Below is the code.
const el = document.getElementById('canvas');
const ctx = el.getContext('2d');
ctx.globalCompositeOperation = 'source-out';
ctx.beginPath();
ctx.rect(200,200,400,400);
ctx.closePath();
ctx.fill();
ctx.globalAlpha = 0.2;
ctx.beginPath();
ctx.rect(0,0,800,800);
ctx.closePath();
ctx.fill();
body {
background-color: white;
margin: 0;
}
.canvas-container {
position: relative;
width: 75%;
height: 0;
margin: auto;
margin-top : 50px;
padding-bottom: 75%;
}
.canvas-container .canvas{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="canvas-container">
This is canvas container
<canvas id="canvas" class="canvas" width="800" height="800"></canvas>
</div>
</body>
</html>
I can definitely reproduce the bug, and being a bug, the only true solution is to report it in the hope it gets fixed.
Now, there are a lot of workarounds available.
The first one is to use a semi-transparent fillStyle rather than globalAlpha:
const el = document.getElementById('canvas');
const ctx = el.getContext('2d');
ctx.beginPath();
ctx.rect(100,100,200,200);
ctx.fill();
ctx.globalCompositeOperation = 'source-out';
ctx.fillStyle = "rgba(0,0,0,0.2)";
ctx.beginPath();
ctx.rect(0,0,400,400);
ctx.fill();
canvas { border: 1px solid; }
<canvas id="canvas" class="canvas" width="400" height="400"></canvas>
But this may not be really practical, for instance if you have complex gradients or even patterns as fillStyle.
A second workaround is to use the fillRect() method, which is not affected by the bug.
const el = document.getElementById('canvas');
const ctx = el.getContext('2d');
ctx.beginPath();
ctx.rect(100,100,200,200);
ctx.fill();
ctx.globalCompositeOperation = 'source-out';
ctx.globalAlpha = 0.2;
ctx.fillRect(0,0,400,400);
canvas { border: 1px solid; }
<canvas id="canvas" class="canvas" width="400" height="400"></canvas>
But this will obviously only work for rectangles, and not for any other shapes.
So a third workaround, which is probably the best one, consists in drawing the other way: first draw the semi-transparent contour, then the hole:
const el = document.getElementById('canvas');
const ctx = el.getContext('2d');
// first the contour
ctx.globalAlpha = 0.2;
ctx.beginPath();
ctx.rect(0,0,400,400);
ctx.fill();
// now the hole
ctx.globalCompositeOperation = 'destination-out';
ctx.globalAlpha = 1;
ctx.beginPath();
ctx.rect(100,100,200,200);
ctx.fill();
canvas { border: 1px solid; }
<canvas id="canvas" class="canvas" width="400" height="400"></canvas>
But if for some reasons you can't even do that, then a last resort workaround is to use a second canvas on which you'll draw your shape and do the compositing through drawImage(), which isn't affected either by this bug:
const el = document.getElementById('canvas');
const ctx = el.getContext('2d');
const copy_ctx= el.cloneNode().getContext("2d");
ctx.beginPath();
ctx.beginPath();
ctx.rect(100,100,200,200);
ctx.fill();
copy_ctx.beginPath();
copy_ctx.rect(0,0,400,400);
copy_ctx.fill();
// we can set the alpha either here or while drawing
// on copy_ctx, it doesn't change much, both work
ctx.globalAlpha = 0.2;
ctx.globalCompositeOperation = 'source-out';
ctx.drawImage(copy_ctx.canvas,0,0);
canvas { border: 1px solid; }
<canvas id="canvas" class="canvas" width="400" height="400"></canvas>
I have a canvas that is the only thing on a page I want really want to see. I'm trying to make it such that when I resize my window, I always have the entire canvas viewable with no scroll bars and maintain the aspect ratio.
MCVE
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let w = canvas.width;
let h = canvas.height;
ctx.fillStyle = 'teal';
ctx.fillRect(0, 0, w, h);
ctx.strokeStyle = 'red';
ctx.lineWidth = 10;
ctx.rect(5, 5, w - 5, h - 5);
ctx.stroke();
* {
background-color: white;
max-height: 100%;
max-width: 100%;
margin: 0;
padding: 0;
}
div#canvasDiv {}
canvas#canvas {
display: block;
margin: auto;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<div id="canvasDiv">
<canvas id="canvas" width="500" height="500" />
</div>
</body>
</html>
All here at jsfiddle
With this attempt, it rescales just fine when I resize the width. However, when I resize the height, I get overflow.
Resize Width with appropriate rescaling
Resize Height with unwanted overflow
You may like to read this article: [Centering in CSS: A Complete Guide](https://css-tricks.com/centering-css-complete-guide/
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let w = canvas.width;
let h = canvas.height;
ctx.fillStyle = 'teal';
ctx.fillRect(0, 0, w, h);
ctx.strokeStyle = 'red';
ctx.lineWidth = 10;
ctx.rect(5, 5, w - 5, h - 5);
ctx.stroke();
* {
background-color: white;
max-height: 100%;
max-width: 100%;
margin: 0;
padding: 0;
}
canvas#canvas {
display: block;
margin: auto;
position:absolute;
top:0;bottom:0;
left:0;
right:0;
}
<div id="canvasDiv">
<canvas id="canvas" width="500" height="500"/>
</div>
My problem is I try to paint circles in an X position of a canvas and always painted with a difference of more than 100px I give. I see no pattern in terms of pixel added. The position of X given is that I need regarding this painting canvas where I do not need 100px or more. Leave a basic code sample.
Style
.defaul_paint
{
margin:1px auto;
overflow:hidden;
text-align:center;
float:right;
background:#394147;
max-width:660px;
width:660px;
height: 30px;
margin-bottom: 2px;
}
.paint{
margin:1px auto;
overflow:hidden;
text-align:center;
float:right;
max-width:660px;
height: 340px;
margin-bottom: 2px;
background:#394147;
}
JavaScript
function paint(xx, yy, radio, begin, grades, booleanVar, context) {
context.arc(xx, yy, radio, begin, (Math.PI * 2), booleanVar);
circle = new Circle(xx, yy, radio);
circles.push(circle);
}
function testing() {
var canvas, ctx;
canvas = $('.paint')[0];
ctx = canvas.getContext('2d');
ctx.fillStyle = '#FFF';
ctx.beginPath();
paint(47, 5, 5, 0, Math.PI * 2, true, ctx);
ctx.closePath();
ctx.fill();
}
HTML
<article class="defaul_paint">
<canvas class='paint'>
</canvas>
</article ">
Don't use CSS to resize your canvas--this will cause your pixels to be stretched.
Instead, resize the canvas element itself. This will add pixels to the canvas.
You don't show your Circle "class" here's a example code: http://jsfiddle.net/m1erickson/VkV9n/
<!doctype html>
<html>
<head>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
window.onload = function() {
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
function Circle(x,y,radius,fill){
this.x=x;
this.y=y;
this.radius=radius;
this.fill=fill;
}
Circle.prototype.draw=function(){
ctx.beginPath();
ctx.arc(this.x,this.y,this.radius,0,Math.PI*2);
ctx.closePath();
if(ctx.fillStyle!=this.fill){ctx.fillStyle=this.fill;}
ctx.fill();
};
var c1=new Circle(150,150,100,"skyblue");
c1.draw();
}; // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
I trying to reproduce the CSS3 border radius in canvas.
It's easy to draw a rounded rectangle but in CSS, the value of each border can be high.
For example :
HTML
<div class="normal_radius"></div>
<div class="high_radius"></div>
<div class="high2_radius"></div>
CSS
div { height:50px;width:50px;position:absolute;top:10px; }
.normal_radius {
border: 1px solid black;
border-radius: 5px 5px 10px 15px;
left: 10px;
}
.high_radius {
border: 1px solid red;
border-radius: 5000px 500px 100px 150px;
left: 80px;
}
.high2_radius {
border: 1px solid blue;
border-radius: 2500px 250px 50px 75px;
left: 160px;
}
Here a jsfiddle
The black, normal border radius value, i can reproduce that.
The red, high value for border radius, i don't know how reproduce that.
And the blue, high value divided by 2, same result of red.
My question is simple, how to reproduce the red and the blue in canvas?
Best regards.
The function below is pretty close. Although if you use values greater than the width and height you're going to have issues.
Live Demo
function canvasRadius(x, y, w, h, tl, tr, br, bl){
var r = x + w,
b = y + h;
ctx.beginPath();
ctx.moveTo(x+tl, y);
ctx.lineTo(r-(tr), y);
ctx.quadraticCurveTo(r, y, r, y+tr);
ctx.lineTo(r, b-br);
ctx.quadraticCurveTo(r, b, r-br, b);
ctx.lineTo(x+bl, b);
ctx.quadraticCurveTo(x, b, x, b-bl);
ctx.lineTo(x, y+tl);
ctx.quadraticCurveTo(x, y, x+tl, y);
ctx.stroke();
}
canvasRadius(10,10,50,50,5,5,10,15);
ctx.strokeStyle = "red";
canvasRadius(80,10,50,50,47,3,0,0);
ctx.strokeStyle = "blue";
canvasRadius(160,10,50,50,47,3,0,0);
here the solution :
CanvasRenderingContext2D.prototype.roundRect=function(x,y,width,height,tl,tr,br,bl) {
var x1,x2,x3,x4,y1,y2,y3,y4,radii,ratio=0,CURVE2KAPPA=0.5522847498307934;
ratio=Math.min(Math.min(width/(tl+tr),width/(br+bl)),Math.min(height/(tl+bl),height/(tr+br)));
if ((ratio>0)&&(ratio<1)) {
tl*=ratio;
tr*=ratio;
bl*=ratio;
br*=ratio;
}
xw=x+width;
yh=y+height;
x1=x+tl;
x2=xw-tr;
x3=xw-br;
x4=x+bl;
y1=y+tr;
y2=yh-br;
y3=yh-bl;
y4=y+tl;
this.beginPath();
this.moveTo(x1,y);
this.lineTo(x2,y);
radii=CURVE2KAPPA*tr;
this.bezierCurveTo(x2+radii,y,xw,y1-radii,xw,y1);
this.lineTo(xw,y2);
radii=CURVE2KAPPA*br;
this.bezierCurveTo(xw,y2+radii,x3+radii,yh,x3,yh);
this.lineTo(x4,yh);
radii=CURVE2KAPPA*bl;
this.bezierCurveTo(x4-radii,yh,x,y3+radii,x,y3);
this.lineTo(x,y4);
radii=CURVE2KAPPA*tl;
this.bezierCurveTo(x,y4-radii,x1-radii,y,x1,y);
this.stroke();
}
ctx.roundRect(0,0,50,50,5,5,10,15);
ctx.strokeStyle="red";
ctx.roundRect(0,0,50,50,5000,500,100,150);
ctx.strokeStyle="blue";
ctx.roundRect(0,0,50,50,2500,250,50,75);
Live demo
Have fun.