I am trying to calculate and display the circumference by retrieving the already defined radius from the given code of a drawn circle. Is it the way I typed out the formula wrong or does it need to be in the same script section?
function draw() {
var canvas = document.getElementById('circle');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var X = canvas.width / 2;
var Y = canvas.height / 2;
var R = 45;
ctx.beginPath();
ctx.arc(X, Y, R, 0, 2 * Math.PI, false);
ctx.lineWidth = 3;
ctx.strokeStyle = '#FF0000';
ctx.stroke();
}
}
function calculatecircumference() {
var circumference = ((2) * (Math.Pi) * (R));
}
document.getElementById("Circumference").innerHTML = circumference;
<!Doctype>
<html>
<body onload="draw();">
<canvas id="circle" width="150" height="150"></canvas>
</body>
<p>Circumference: <span id="Circumference"></span></p>
</html>
Actually the math PI is wrong....you have written Math.Pi
var circumference = ((2) * (Math.Pi) * (R));
but in actual it is Math.PI
var circumference = ((2) * (Math.PI) * (R));
Hence it Returns a NaN for a radius of 45 ..
Check the working below code.... also you need to call the calculatecircumference function..and pass the Radius as param
function draw() {
var canvas = document.getElementById('circle');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var X = canvas.width / 2;
var Y = canvas.height / 2;
var R = 45;
ctx.beginPath();
ctx.arc(X, Y, R, 0, 2 * Math.PI, false);
ctx.lineWidth = 3;
ctx.strokeStyle = '#FF0000';
ctx.stroke();
calculatecircumference(R);
}
}
function calculatecircumference(R) {
var circumference = ((2) * (Math.PI) * (R));
document.getElementById("Circumference").innerHTML = circumference;
}
<body onload="draw();">
<canvas id="circle" width="150" height="150"></canvas>
</body>
<p>Circumference: <span id="Circumference"></span></p>
You have three problems:
First, you need to give calculatecircumference() scope to access R. This can be done by calling calculatecircumference() from within draw() and passing it through as a function parameter. You'll also need to tell calculatecircumference() that its function parameter should be assigned to the local variable R, by writing it as calculatecircumference(R).
Second, document.getElementById("Circumference").innerHTML does not have access to the scope of circumference. Simply run the line document.getElementById("Circumference").innerHTML = circumference line inside caluclatecircumference().
Finally, you called Math.Pi instead of Math.PI in calculatecircumference(). The PI must be uppercase.
Correcting these three issues fixes the problem, as can be seen below:
function draw() {
var canvas = document.getElementById('circle');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var X = canvas.width / 2;
var Y = canvas.height / 2;
var R = 45;
ctx.beginPath();
ctx.arc(X, Y, R, 0, 2 * Math.PI, false);
ctx.lineWidth = 3;
ctx.strokeStyle = '#FF0000';
ctx.stroke();
calculatecircumference(R);
}
}
function calculatecircumference(R) {
var circumference = ((2) * (Math.PI) * (R));
document.getElementById("Circumference").innerHTML = circumference;
}
<!Doctype>
<html>
<body onload="draw();">
<canvas id="circle" width="150" height="150"></canvas>
</body>
<p>Circumference: <span id="Circumference"></span></p>
</html>
Hope this helps! :)
Related
I've got this piece of code that draws a ball and i want to continuously pass in different cooridinates in order to make it move around but when the refresh rate gets way too high, canvas stops updating. How do i force canvas to update and redraw everything with the arguments passed in?
var c = document.getElementById("circle");
var ctx = c.getContext("2d");
var x = Math.floor(Math.random() * 50);
var y = Math.floor(Math.random() * 50);
function determinePosition(x, y) {
var trueX = x + 120;
var trueY = y + 80;
ctx.beginPath();
ctx.arc(trueX, trueY, 10, 0, 2 * Math.PI);
ctx.fillStyle = "black";
ctx.fill();
ctx.strokeStyle = "black";
ctx.stroke();
}
while(true){
determinePosition(x, y);
}
<div class="gcircle">
<canvas id="circle" width="240px" height="160"></canvas>
</div>
var c = document.getElementById("circle");
var ctx = c.getContext("2d");
function determinePosition(x, y) {
//clear the canvas
ctx.clearRect(0, 0, c.width, c.height);
var trueX = x + 120;
var trueY = y + 80;
ctx.beginPath();
ctx.arc(trueX, trueY, 10, 0, 2 * Math.PI);
ctx.fillStyle = "black";
ctx.fill();
ctx.strokeStyle = "black";
ctx.stroke();
}
//set random location for each 0.5 sec
setInterval(function() {
var x = Math.floor(Math.random() * 50);
var y = Math.floor(Math.random() * 50);
determinePosition(x, y);
}, 500)
<div class="gcircle">
<canvas id="circle" width="240px" height="160"></canvas>
</div>
`
Drawing should always happen in a requestAnimationFrame loop. requestAnimationFrame runs at your monitor's refresh rate, so it's the fastest any animation can run. You can set it up like this:
var c = document.getElementById("circle");
var ctx = c.getContext("2d");
var x = Math.floor(Math.random() * 50);
var y = Math.floor(Math.random() * 50);
var trueX = 0;
var trueY = 0;
function determinePosition(x, y) {
trueX = x + 120;
trueY = y + 80;
}
requestAnimationFrame(function draw() {
ctx.clearRect(0, 0, c.width, c.height);
ctx.beginPath();
ctx.arc(trueX, trueY, 10, 0, 2 * Math.PI);
ctx.fillStyle = "black";
ctx.fill();
ctx.strokeStyle = "black";
ctx.stroke();
requestAnimationFrame(draw);
})
determinePosition(x, y);
I want to implement a ripple effect in JavaScript for that I am using a canvas element of HTML 5.
I have created 4 circles in order to implement ripple effect I am thinking of showing only one circle at a time here is my code
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var i = window.innerWidth/4;
var canvas = document.getElementById("myCanvas");
canvas.width = window.innerWidth/2;
canvas.height = window.innerWidth/2;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.arc(i, i, i-i/1.5, 0, 2 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(i, i, i-i/2.5, 0, 2 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(i, i, i-i/5, 0, 2 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(i, i, i, 0, 2 * Math.PI);
ctx.stroke();
output
how can I remove a specific circle here
there is a function ctx.clearRect(x, y, width, height); but it works only on rectangle.
also, let me know whether it's a good approach to create a ripple effect in canvas
If you are looking for something like this, you can do it simply by resetting the canvas after some time.
Also you can trigger the elements to be created at a certain time to make that effect of showing them one by one.
Here is a sample
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var i = window.innerWidth/4;
var canvas = document.getElementById("myCanvas");
canvas.width = window.innerWidth/2;
canvas.height = window.innerWidth/2;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.arc(i, i, i-i/1.5, 0, 2 * Math.PI);
ctx.stroke();
window.setTimeout(() => {
ctx.beginPath();
ctx.arc(i, i, i-i/2.5, 0, 2 * Math.PI);
ctx.stroke();
}, 200*1)
window.setTimeout(() => {
ctx.beginPath();
ctx.arc(i, i, i-i/5, 0, 2 * Math.PI);
ctx.stroke();
}, 200*2)
window.setTimeout(() => {
ctx.beginPath();
ctx.arc(i, i, i, 0, 2 * Math.PI);
ctx.stroke();
}, 200*3)
window.setTimeout(() => {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var i = window.innerWidth/4;
var canvas = document.getElementById("myCanvas");
canvas.width = window.innerWidth/2;
canvas.height = window.innerWidth/2;
}, 200*6)
<canvas id="myCanvas"></canvas>
Here's a much much better and smoother ripple effect than the one you seek:
NOTE: run it on CodePen because for some reason it's not fully functional on stack overflow, but works fine in an HTML document or on CodePen
CodePen: https://codepen.io/Undefined_Variable/pen/dqZpzE
Code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>canvas</title>
</head>
<body>
<canvas id="myCanvas"></canvas>
<script>
var canvas = document.body.querySelector("#myCanvas");
var ctx = canvas.getContext("2d");
canvas.width = window.innerWidth * 0.98;
canvas.height = window.innerHeight * 0.97;
var shapeArr = [];
window.addEventListener('resize', function () {
canvas.width = window.innerWidth * 0.98;
canvas.height = window.innerHeight * 0.98;
CW = canvas.width;
CH = canvas.height;
})
var CW = canvas.width;
var CH = canvas.height;
class circle {
constructor(centerX, centerY, radius) {
this.centerX = centerX;
this.centerY = centerY;
this.radius = radius;
this.opacity = 1;
this.strokeStyle = "rgba(0, 0, 0, " + this.opacity + ")";
}
expandCircle() {
this.radius += 3;
this.opacity -= 0.015;
this.strokeStyle = "rgba(0, 0, 0, " + this.opacity + ")";
if (this.radius > window.innerWidth/4) {
this.radius = 0;
this.opacity = 1;
}
}
}
function createCircle(centerX, centerY, radius) {
shapeArr.push(new circle(centerX, centerY, radius));
}
function drawCircle(centerX, centerY, radius, strokeClr) {
ctx.strokeStyle = strokeClr;
ctx.save();
ctx.translate(centerX, centerY);
ctx.beginPath();
ctx.arc(0, 0, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.stroke();
ctx.restore()
}
createCircle(CW / 2, CH / 2, 0);
createCircle(CW / 2, CH / 2, 0);
createCircle(CW / 2, CH / 2, 0);
function firstWave() {
ctx.clearRect(0, 0, CW, CH);
drawCircle(shapeArr[0].centerX, shapeArr[0].centerY, shapeArr[0].radius, shapeArr[0].strokeStyle);
shapeArr[0].expandCircle();
requestAnimationFrame(firstWave);
};
firstWave();
setTimeout(function secondWave() {
drawCircle(shapeArr[1].centerX, shapeArr[1].centerY, shapeArr[1].radius, shapeArr[1].strokeStyle);
shapeArr[1].expandCircle();
requestAnimationFrame(secondWave);
}, 250);
setTimeout(function thirdWave() {
drawCircle(shapeArr[2].centerX, shapeArr[2].centerY, shapeArr[2].radius, shapeArr[2].strokeStyle);
shapeArr[2].expandCircle();
requestAnimationFrame(thirdWave);
}, 500)
</script>
</body>
</html>
I have an HTML5 canvas where I draw an arc of the circle using the code below:
c = document.querySelector("#myCanvas");
ctx = c.getContext("2d");
var startAngle = 0;
var endAngle = 0.25;
var xPos = 300;
var yPos = 200;
var radius = 100;
ctx.beginPath();
ctx.arc(xPos, yPos, radius, startAngle*Math.PI, endAngle*Math.PI);
ctx.stroke();
ctx.closePath();
How do I compute for the x and y coordinates of the end angle generated by endAngle*Math.PI?
If I understood you correctly, you could achieve this in the following way ...
var c = document.querySelector("#canvas");
var ctx = c.getContext("2d");
var startAngle = 0; //degree
var endAngle = 229; //degree
var xPos = 100;
var yPos = 100;
var radius = 60;
// compute x and y coordinates of the end angle relative to canvas
var x = xPos + Math.cos(endAngle * Math.PI / 180) * radius;
var y = yPos + Math.sin(endAngle * Math.PI / 180) * radius;
ctx.beginPath();
ctx.arc(xPos, yPos, radius, startAngle * Math.PI / 180, endAngle * Math.PI / 180);
ctx.stroke();
console.log('angle ended in position x:', x|0, ', y:', y|0);
canvas {
border: 1px solid lightgrey;
}
<canvas id="canvas" width="200" height="200"></canvas>
On an HTML5 canvas I can't find a method to make colored circles. I've been consulting this as a reference.
Here is my current attempt
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillRect(20, 20, 100, 100);
ctx.lineJoin = "round";
ctx.lineWidth = "cornerRadius";
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
(Also on jsFiddle: http://jsfiddle.net/kvnm21r1/1/)
I've tried using the canvas arc method, which creates a circle, but doesn't color it.
I can't use the border-radius property, because ctx is not an element.
Is there any way, I can transform my squares into circles?
Thanks in advance.
You can use quadratic curves to "round-out" the straight lines of your square until they form a circle.
// change sideCount to the # of poly sides desired
//
var sideCount = 4;
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.lineWidth = 2;
ctx.fillStyle = randomColor();
var PI2 = Math.PI * 2;
var cx = 150;
var cy = 150;
var radius = 100;
var xx = function (a) {
return (cx + radius * Math.cos(a));
}
var yy = function (a) {
return (cy + radius * Math.sin(a));
}
var lerp = function (a, b, x) {
return (a + x * (b - a));
}
var sides = [];
for (var i = 0; i < sideCount; i++) {
sides.push(makeSide(i, sideCount));
}
var percent = 0;
var percentDirection = 0.50;
$("#toShape").click(function () {
percentDirection = -0.50;
})
$("#toCircle").click(function () {
percentDirection = 0.50;
})
animate();
// functions
function animate() {
requestAnimationFrame(animate);
drawSides(percent);
percent += percentDirection;
if (percent > 100) {
percent = 100;
}
if (percent < 0) {
percent = 0;
}
}
function drawSides(pct, color) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (pct == 100) {
ctx.beginPath();
ctx.arc(cx, cy, radius, 0, PI2);
ctx.closePath();
ctx.fill();
} else {
ctx.beginPath();
ctx.moveTo(sides[0].x0, sides[0].y0);
for (var i = 0; i < sideCount; i++) {
var side = sides[i];
var cpx = lerp(side.midX, side.cpX, pct / 100);
var cpy = lerp(side.midY, side.cpY, pct / 100);
ctx.quadraticCurveTo(cpx, cpy, side.x2, side.y2);
}
ctx.fill();
}
}
function makeSide(n, sideCount) {
var sweep = PI2 / sideCount;
var sAngle = sweep * (n - 1);
var eAngle = sweep * n;
var x0 = xx(sAngle);
var y0 = yy(sAngle);
var x1 = xx((eAngle + sAngle) / 2);
var y1 = yy((eAngle + sAngle) / 2);
var x2 = xx(eAngle);
var y2 = yy(eAngle);
var dx = x2 - x1;
var dy = y2 - y1;
var a = Math.atan2(dy, dx);
var midX = lerp(x0, x2, 0.50);
var midY = lerp(y0, y2, 0.50);
var cpX = 2 * x1 - x0 / 2 - x2 / 2;
var cpY = 2 * y1 - y0 / 2 - y2 / 2;
return ({
x0: x0,
y0: y0,
x2: x2,
y2: y2,
midX: midX,
midY: midY,
cpX: cpX,
cpY: cpY,
color: randomColor()
});
}
function randomColor() {
return ('#' + Math.floor(Math.random() * 16777215).toString(16));
}
body{ background-color: ivory; }
canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button id="toShape">Animate to Shape</button>
<button id="toCircle">Animate to Circle</button><br>
<canvas id="canvas" width=300 height=300></canvas>
JSfiddle with a circle
To draw a circle you'll need to draw an arc and have a starting angle and an ending angle. So you'll have to use Pi and define a radius.
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 70;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();
Avoid w3schools.com whenever possible. Refer to sites like MDN instead.
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext("2d");
ctx.beginPath();
var radius = 50; // Arc radius
var startAngle = 0; // Starting point on circle
var endAngle = Math.PI*2; // End point on circle
ctx.arc(150, 75, radius, startAngle, endAngle, true);
ctx.fill();
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
I am trying to add a few more circles in the circular loop using HTML5 canvas but it doesn't seem to work. I want the other circles to kind of trail the circle is already rotating there. I am also wondering how to make the circular motion non-linear (that is, it moves in varying speed like it has easing).
Can you guys help? :/ Thanks heaps. Below is my code.
<canvas id="canvas" width="450" height="450"></canvas>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var w = canvas.width;
var h = canvas.height;
var dd = 4;
var angle = 0;
/*var cx = 197;
var cy = 199;
var radius = 200;*/
var cx = w/2;
var cy = h/2;
var radius = 200;
function draw(x, y) {
ctx.fillStyle = "rgb(38,161,220)";
ctx.strokeStyle = "rgb(38,161,220)";
ctx.clearRect(0, 0, w, h);
ctx.save();
ctx.beginPath();
ctx.beginPath();
//ctx.rect(x - 30 / 2, y - 30 / 2, 50, 30);
// Circle 1
ctx.arc(x-1/2, y-1/2, 10, 0, 2 * Math.PI, false);
ctx.fill();
ctx.stroke();
ctx.restore();
};
/** context.beginPath();
context.fillStyle = 'green';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke(); **/
var fps = 120;
window.requestAnimFrame = (function (callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / fps);
};
})();
function animate() {
setTimeout(function () {
requestAnimFrame(animate);
// increase the angle of rotation
//angle += Math.acos(1-Math.pow(dd/radius,2)/2);
angle += Math.acos(1-Math.pow(dd/radius,2)/2);
// calculate the new ball.x / ball.y
var newX = cx + radius * Math.cos(angle);
var newY = cy + radius * Math.sin(angle);
// draw
draw(newX, newY);
// draw the centerpoint
ctx.beginPath();
ctx.arc(cx, cy, radius, 0, Math.PI * 2, false);
ctx.closePath();
ctx.stroke();
}, 1000 / fps );
}
animate();
</script>
Easing between where and where?
Heres some non-linear angular velocities:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<canvas id="canvas" width="450" height="450"></canvas>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var w = canvas.width;
var h = canvas.height;
var dd = 4;
var angle = 0;
var cx = w/2;
var t = 0;
var velocity = 0.01;
var cy = h/2;
var radius = 200;
function draw(x, y) {
ctx.fillStyle = "rgb(38,161,220)";
ctx.strokeStyle = "rgb(38,161,220)";
ctx.clearRect(0, 0, w, h);
ctx.save();
ctx.beginPath();
ctx.beginPath();
ctx.arc(x-1/2, y-1/2, 10, 0, 2 * Math.PI, false);
ctx.fill();
ctx.stroke();
ctx.restore();
};
var fps = 120;
window.requestAnimFrame = (function (callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / fps);
};
})();
function animate() {
setTimeout(function () {
// increase the angle of rotation
angle += velocity;
//sinusoidal velocity
velocity += 0.005 * (Math.sin(t));
t += 0.1;
// randomzed velocity:
//velocity += 0.001 * (Math.random() - 1);
// draw
// calculate the new ball.x / ball.y
var newX = cx + radius * Math.cos(angle);
var newY = cy + radius * Math.sin(angle);
draw(newX, newY);
// draw the centerpoint
ctx.beginPath();
ctx.arc(cx, cy, radius, 0, Math.PI * 2, false);
ctx.closePath();
ctx.stroke();
requestAnimFrame(animate);
}, 1000 / fps );
}
animate();
</script>
</body>
</html>
You can make a circle class like this:
var Circle = function(radius,velocity,etc){
this.radius = radius
this.velocity = velocity
this.etc = etc
// and whatever other properties you think you need
}
then
var circleArray = []
for(var i = 0; i < circleCount; i++){
circleArray.push(new Circle(2,0.1,"some_property"))
}
then inside animate():
circleArray.forEach(function(circle){
//drawing code
})
Until you ask a more specific question, thats all I can give you