How would I align circles horizontally using loops? - javascript

I have managed to get the circles on top of each other but I have no clue how to make a line of circles that do not overlap.
This is what I have gotten so far.
HTML
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<canvas id="myCanvas" width="800" height="600"></canvas>
<script src="js/main.js"></script>
</body>
</html>
JavaScript
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext('2d');
for(var i = 0; i < 10; i++) {
ctx.fillStyle="rgba(0,0,0,0.5)";
fillCircle(200,200,i*20)
}
var width = window.innerWidth;
var height = 100;
function fillCircle(x, y, radius) {
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}

The x-value of any next circle must be at least be the sum of the current and next circle radii beyond the current circle's x-value.
So if:
var currentCircleX=20
var currentCircleRadius=15
var nextCircleRadius=25
Then:
var nextCircleX = currentCircleX + currentCircleRadius + nextCircleRadius
But if you are also stroking the circles:
Since a context stroke will extend half-outside the defined path, you must also add half the lineWidth for each circle to avoid the circles touching:
// account for the lineWidth that extends beyond the arc's path
var nextCircleX =
currentCircleX + currentCircleRadius + nextCircleRadius + context.lineWidth
Example code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
ctx.fillStyle="rgba(0,0,0,0.5)";
var currentCircleX=0;
var currentCircleRadius=0;
for(var i = 0; i < 10; i++) {
var nextCircleRadius=i*20;
var nextCircleX=currentCircleX+currentCircleRadius+nextCircleRadius;
fillCircle(nextCircleX,200,nextCircleRadius);
currentCircleX=nextCircleX;
currentCircleRadius=nextCircleRadius;
}
function fillCircle(x, y, radius) {
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>

Related

Flashing dots on canvas [duplicate]

This question already has answers here:
clearRect not working
(2 answers)
Closed 6 months ago.
I don't see why this code isn't working. It should just draw a white rectangle covering the screen. Then a randomly placed blue dot and wait for the loop to complete. And then repeat the cycle by drawing the white rectangle again and turning off the dot and then redrawing it.
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8"/>
<title>Peripheral vision checker</title>
<script type="application/javascript">
function draw() {
// draw crosshairs
var onFor = 1000;
const intervalID = setInterval(mytimer, onFor);
function mytimer()
{
// draw white rects
function getRandomInt(max) {
return Math.floor(Math.random() * max);
}
var x = 1280;//will be equal to window height
var y = 720;//will be equal to window width
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'white';
var xcoor =getRandomInt(x);
var ycoor =getRandomInt(y);
ctx.fillRect(0, 0, x, y);
ctx.fillStyle = 'blue';
var radius = 10;
moveTo(xcoor,ycoor);
ctx.arc(xcoor, ycoor, radius, 0, 2 * Math.PI);
//console.log(xcoor + ' ' + ycoor);//just temporary, to see they work
ctx.fill();
}
}
</script>
</head>
<h1>Peripheral vision checker</h1>
<body onload="draw();">
<canvas id="canvas" width="1280" height="720"></canvas>
</body>
</html>
You need to beginPath then closePath
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<title>Peripheral vision checker</title>
<script type="application/javascript">
function draw() {
// draw crosshairs
var onFor = 1000;
const intervalID = setInterval(mytimer, onFor);
function mytimer() {
// draw white rects
function getRandomInt(max) {
return Math.floor(Math.random() * max);
}
var x = 500; //will be equal to window height
var y = 250; //will be equal to window width
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'white';
var xcoor = getRandomInt(x);
var ycoor = getRandomInt(y);
ctx.fillRect(0, 0, x, y);
ctx.fillStyle = 'blue';
var radius = 10;
ctx.beginPath();
moveTo(xcoor, ycoor);
ctx.arc(xcoor, ycoor, radius, 0, 2 * Math.PI);
//console.log(xcoor + ' ' + ycoor);//just temporary, to see they work
ctx.fill();
// no need to:
// ctx.closePath();
}
}
</script>
</head>
<h1>Peripheral vision checker</h1>
<body onload="draw();">
<canvas id="canvas" width="500" height="250"></canvas>
</body>
</html>

Javascript Canvas one item flickering

I am trying to make to objects move towards each other in Canvas, when they meet and overlap one should then disappear and the other should fall down. Now I got the animation to do that, but one of the items is flickering.
<!DOCTYPE html>
<html>
<head>
<style>
canvas{border:#666 3px solid;}
</style>
</head>
<body onload="draw(530,15); draw1(1,15);">
<canvas id="canvas" width="600" height="400"></canvas>
<script>
function draw(x,y){
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.save();
ctx.clearRect(x, y, 600, 400);
ctx.fillStyle = "rgba(0,200,0,1)";
ctx.fillRect (x, y, 70, 50);
ctx.restore();
x -= 0.5;
if(x==300)
{
return;
};
var loopTimer = setTimeout('draw('+x+','+y+')',5);
};
function draw1(w,e){
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.save();
ctx.clearRect(w-1,e-2,600,400);
ctx.fillStyle = "rgba(0,200,0,1)";
ctx.fillRect (w, e, 70, 50);
ctx.restore();
w += 1;
if(w==265)
{
w -= 1;
e +=2;
};
var loopTimer = setTimeout('draw1('+w+','+e+')',10);
};
</script>
</body>
</html>
Been trying for two days, but can't seem to fix it properly. Thanks in advance.
You are rendering too many frames per second forcing the browser to present frames. Each time a draw function returns the browser presumes you want to present the frame to the page.
Animations need to be synced to the display refresh rate which for most devices is 60FPS. To do this you have one render loop that handles all the animation. You call this function via requestAnimationFrame (RAF) which ensures that the animation stays in sync with the display hardware and browser rendering.
<!DOCTYPE html>
<html>
<head>
<style>
canvas{border:#666 3px solid;}
</style>
</head>
<!-- dont need this <body onload="draw(530,15); draw1(1,15);">-->
<body>
<canvas id="canvas" width="600" height="400"></canvas>
<script>
var canvas,ctx,x,y,w,e;
var canvas,ctx,x,y,w,e;
function draw() {
ctx.fillStyle = "rgba(0,200,0,1)";
ctx.fillRect(x, y, 70, 50);
};
function draw1(w, e) {
ctx.fillStyle = "rgba(0,200,0,1)";
ctx.fillRect(w, e, 70, 50);
};
function update(time){ // high precision time passed by RAF when it calls this function
ctx.clearRect(0,0,canvas.width,canvas.height); // clear all of the canvas
if(w + 70 >= x){
e += 2;
}else{
x -= 0.75;
w += 1;
};
draw(x,y);
draw1(w,e);
requestAnimationFrame(update)
// at this point the function exits and the browser presents
// the canvas bitmap for display
}
function start(){ // set up
x = 530;
y = 15;
w = 1;
e = 15;
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
requestAnimationFrame(update)
}
window.addEventListener("load",start);
</script>
</body>
</html>
You're method of animation is very outdated (ie, the use of setTimeout). Instead you should be using requestAnimationFrame as demonstrated below. This will give smooth, flicker free animation.
<!DOCTYPE html>
<html>
<head>
<style>
canvas{border:#666 3px solid;}
</style>
</head>
<body onload="requestAnimationFrame(animate);">
<canvas id="canvas" width="600" height="400"></canvas>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var x = 530, y = 15;
function animate(){
requestID = requestAnimationFrame(animate);
ctx.clearRect(x, y, 600, 400);
ctx.fillStyle = "rgba(0,200,0,1)";
ctx.fillRect (x, y, 70, 50);
x -= 0.5;
if(x==300)
{
cancelAnimationFrame(requestID)
};
}
</script>
</body>
</html>
the first 2 parameters of ctx.clearReact in both draw functions should be 0:
ctx.clearRect(0, 0, 600, 400);
This means you clear all canvas.

Animate a Fill Circle like pie chart using Canvas

Basically I want to be able to Fill a Circle using canvas, but it animate like pie chart and mask to show new image in circle.
My canvas knowledge isn't amazing, Here is an image to display what i want.
an anyone shed some light on how to do it?
Here is a fiddle of what I've managed
var canvas = document.getElementById('Circle');
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 80;
var full = radius*2;
var amount = 0;
var amountToIncrease = 0.1;
function draw() {
context.beginPath();
context.arc(centerX, centerY, radius, 0, amount * Math.PI, false);
context.fillStyle = '#13a8a4';
context.fill();
context.lineWidth = 10;
context.strokeStyle = '#000000';
context.stroke();
amount += amountToIncrease;
if (amount > full) amount = 0; // restart
}
draw();
// Every second we'll fill more;
setInterval(draw, 100);
This is one way:
Draw your gray background.
Fill your percent-arc with a starting angle at -Math.PI*2 (=="12 on a clock") and an ending angle of -Math.PI*2 + Math.PI*2*percent (==a full circle of 2PI times your desired percent).
Draw your logo.
To animate, just use a requestAnimationFrame loop that incrementally draws the percent-arc starting at 0 percent and ending at your target percent.
Example code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var nextTime=0;
var duration=1000;
var endingPct=75;
var pct=0;
var increment=duration/pct;
requestAnimationFrame(animate);
function animate(time){
draw(pct);
pct++;
if(pct<=endingPct){requestAnimationFrame(animate);}
}
function draw(pct){
var endRadians=-Math.PI/2+Math.PI*2*pct/100;
ctx.fillStyle='lightgray';
ctx.fillRect(0,0,cw,ch);
ctx.beginPath();
ctx.arc(150,125,100,-Math.PI/2,endRadians);
ctx.lineTo(150,125);
ctx.fillStyle='white';
ctx.fill();
ctx.beginPath();
ctx.moveTo(150,100);
ctx.lineTo(175,150);
ctx.quadraticCurveTo(150,125,125,150);
ctx.closePath();
ctx.strokeStyle='#13a8a4';
ctx.lineJoin='bevel';
ctx.lineWidth=10;
ctx.stroke();
ctx.fillStyle='black';
ctx.textAlign='center';
ctx.textBaseline='middle'
ctx.font='18px arial';
ctx.fillText('ADUR',150,175);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>
[Update: We needed an image clipped inside the animated wedge]
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var nextTime=0;
var duration=1000;
var endingPct=75;
var pct=0;
var increment=duration/pct;
var cx=cw/2;
var cy=ch/2;
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/mm.jpg";
function start(){
requestAnimationFrame(animate);
}
function animate(time){
draw(pct);
pct++;
if(pct<=endingPct){requestAnimationFrame(animate);}
}
function draw(pct){
//
var endRadians=-Math.PI/2+Math.PI*2*pct/100;
//
ctx.fillStyle='lightgray';
ctx.fillRect(0,0,cw,ch);
//
ctx.beginPath();
ctx.arc(cx,cy,100,-Math.PI/2,endRadians);
ctx.lineTo(cx,cy);
ctx.save();
ctx.clip();
ctx.drawImage(img,cx-img.width/2,cx-img.height/2);
ctx.restore();
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>

Paint circle method JavaScript

I am trying to find a way to draw a circle using JavaScript and redraw it while erasing the old circle.
i got this code:
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
<script>
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 15;
drawCircle(centerX,centerY,radius);
drawCircle(150,150,25);
function drawCircle(centerX,centerY,radius)
{
var canvas = document.getElementById('myCanvas');
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'black';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();
};
</script>
The problem is that this two methods draw two circles instead of drawing one instead of the other.
I am beginner in JS would appreciate help on making better way of drawing and erasing the circle
Thanks
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 15;
function drawCircle(centerX,centerY,radius)
{
// Erase context
context.clearRect(0,0,canvas.width,canvas.height);
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'black';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();
};
drawCircle(centerX,centerY,radius);
drawCircle(150,150,25);
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
If you want to remove a circle from the canvas you will have to draw a circle (same position; same size) but this time with the color of the canvas background.
drawCircle(150,150,25,'black');
// ...
drawCircle(150,150,25,'white'); // removes previous circle if the canvas was white colored
If you want to erase everything from the canvas before drawing something new you can just execute this
context.clearRect(0, 0, canvas.width, canvas.height);

Javascript line around a circle

I want to programm this cool visualization with javascrip:
http://imgur.com/ZCUW7js
I have this: http://test.wikunia.de/pi/ but unfortunately I have no idea how to draw the lines that there is a black circle in the middle. Any idea?
I am using quadraticCurveTo now, but maybe bezier curve is a better option...
My full code:
var canvas = document.getElementById('myCanvas');
var color_arr = new Array("yellow","orange","OrangeRed","red","violetred","MediumSlateBlue","blue","aquamarine","green","greenyellow");
var sA = (Math.PI / 180) * 270;
var pA = (Math.PI / 180) * 36;
if (canvas && canvas.getContext) {
var ctx = canvas.getContext("2d");
if (ctx) {
ctx.fillStyle = "black";
ctx.fillRect(0,0,ctx.canvas.width, ctx.canvas.height);
for (var i=0; i <= 9; i++) {
ctx.strokeStyle = color_arr[i];
ctx.lineWidth = 5;
ctx.beginPath();
ctx.arc (350, 350, 250, sA+(i)*pA, sA+(i+1)*pA, false);
ctx.stroke();
ctx.closePath();
ctx.fillStyle = "white";
ctx.strokeStyle = "white";
ctx.font = "italic 30pt Arial";
if (i > 4 && i < 8) {
ctx.fillText(i.toString(), 350+290*Math.cos(sA+(i+0.5)*pA),350+290*Math.sin(sA+(i+0.5)*pA));
} else {
if (i == 3 || i == 4 || i == 8) {
ctx.fillText(i.toString(), 350+275*Math.cos(sA+(i+0.5)*pA),350+275*Math.sin(sA+(i+0.5)*pA));
} else {
ctx.fillText(i.toString(), 350+260*Math.cos(sA+(i+0.5)*pA),350+260*Math.sin(sA+(i+0.5)*pA));
}
}
}
var pi = '31415...';
for (i = 0; i <= 250; i++) {
line(parseInt(pi.substr(i,1)),parseInt(pi.substr(i+1,1)));
}
}
}
function line(no_1,no_2) {
var rand_1 = Math.random();
var rand_2 = Math.random();
var grad= ctx.createLinearGradient(350+250*Math.cos(sA+(no_1+rand_1)*pA), 350+250*Math.sin(sA+(no_1+rand_1)*pA), 350+250*Math.cos(sA+(no_2+rand_2)*pA), 350+250*Math.sin(sA+(no_2+rand_2)*pA));
grad.addColorStop(0, color_arr[no_1]);
grad.addColorStop(1, color_arr[no_2]);
ctx.lineWidth = 1;
ctx.strokeStyle = grad;
ctx.beginPath();
ctx.moveTo(350+250*Math.cos(sA+(no_1+rand_1)*pA), 350+250*Math.sin(sA+(no_1+rand_1)*pA));
ctx.quadraticCurveTo(350,350,350+250*Math.cos(sA+(no_2+rand_2)*pA),350+250*Math.sin(sA+(no_2+rand_2)*pA));
ctx.stroke();
}
Interesting!
The black circle in the middle is just an absence of curves.
The "lines" are cubic Bezier curves.
The beziers appear to be anchored on both ends to the circle circumference at intervals.
Here's my try at a simplified version of that PI: http://jsfiddle.net/m1erickson/Ju6E8/
This could be addictive so I'm leaving my attempt simple!
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; padding:50px; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var PI2=Math.PI*2;
var cx=150;
var cy=150;
var r=100;
ctx.arc(cx,cy,r,0,Math.PI*2);
ctx.closePath();
ctx.stroke();
for(var a=0;a<PI2;a+=PI2/20){
ctx.strokeStyle="blue";
curve(a,PI2/2.5,25);
ctx.strokeStyle="green";
curve(a,PI2/5,50);
ctx.strokeStyle="red";
curve(a,PI2/10,75);
}
function curve(rotation,offset,innerRadius){
var x1=cx+r*Math.cos(rotation);
var y1=cy+r*Math.sin(rotation);
var x2=cx+innerRadius*Math.cos(rotation+offset/3.5);
var y2=cy+innerRadius*Math.sin(rotation+offset/3.5);
var x3=cx+innerRadius*Math.cos(rotation+offset/1.5);
var y3=cy+innerRadius*Math.sin(rotation+offset/1.5);
var x4=cx+r*Math.cos(rotation+offset);
var y4=cy+r*Math.sin(rotation+offset);
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.bezierCurveTo(x2,y2,x3,y3,x4,y4);
ctx.stroke();
}
$("#stop").click(function(){});
}); // end $(function(){});
</script>
</head>
<body>
<button id="stop">Stop</button><br>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

Categories

Resources