Javascript creating a clock - javascript

HTML
<!DOCTYPE html>
<html>
<head>
<title>Clock</title>
</head>
<body>
<canvas id="canvas" width="500" height="500">
This text is displayed if your browser does not support HTML5 Canvas.
</canvas>
<script type='text/javascript' src='Clock.js'></script>
</body>
</html>
JavaScript
var canvas = document.getElementById("canvas"),
c = canvas.getContext("2d"),
Margin = 35,
NumbersRadius = canvas.width/2 - Margin,
ClockRadius = NumbersRadius - 30;
//draw the circle that bound the clock
function drawCircle() {
c.arc(canvas.width/2, canvas.height/2, ClockRadius, 0, 2*Math.PI);
c.stroke();}
//draw the numbers, which lie on the circle with radius: NumbersRadius
function drawNumbers(){
c.font = "25px Verdana";
var numbers = [1,2,3,4,5,6,7,8,9,10,11,12],
angle;
numbers.forEach(function(numbers){
angle = Math.PI/6 * (numbers - 3);
c.fillText(numbers, canvas.width/2 + Math.cos(angle)*NumbersRadius, canvas.height/2 + Math.sin(angle)*NumbersRadius)
});}
//draw the hands
//length of each hand
var SecondHand = ClockRadius - 0.25*ClockRadius,
MinuteHand = SecondHand-0.25*SecondHand,
HourHand = MinuteHand-0.25*MinuteHand;
//Assume that we start at 3:00. i is the number of seconds
function drawHands() {
var i = 0,
angle = -1/30*Math.PI*i;
//draw the SecondHand
c.moveTo(canvas.width/2, canvas.height/2);
c.lineTo(canvas.width/2 + Math.cos(angle)*ClockRadius, canvas.height/2 + Math.sin(angle)*ClockRadius);
c.stroke();
//draw the MinuteHand
c.moveTo(canvas.width/2, canvas.height/2);
c.lineTo(canvas.width/2 + Math.cos(-1/60*angle)*ClockRadius, canvas.height/2 + Math.sin(-1/60*angle)*ClockRadius);
c.stroke;
//draw the HourHand
c.moveTo(canvas.width/2, canvas.height/2);
c.lineTo(canvas.width/2 + Math.cos(-1/Math.pow(60,2)*angle)*ClockRadius, canvas.height/2 + Math.sin(-1/Math.pow(60,2)*angle*ClockRadius));
c.stroke();
i++;
}
function drawClock() {
c.clearRect(0,0,canvas.width,canvas.height);
drawCircle();
drawNumbers();
drawHands();
}
loop = setInterval(drawClock, 1000);
I don't know why my clock is not running. All the hands point and stay still at 3:00. The NumbersRadius is the radius of the circle that the coordinate of the numbers are on. The ClockRadius, which is smaller than NumbersRadius, is the radius of the circle that bound the hands.

In drawHands, you're resetting i to 0 every time. Move var i = 0 outside that function.
var i = 0;
function drawHands() {
var angle = -1/30*Math.PI*i;
//draw the SecondHand
c.moveTo(canvas.width/2, canvas.height/2);
...
http://jsfiddle.net/trevordixon/bW73Y/

Related

javascript my arc is not showing up or moving across the screen

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>

how to animate 100 circles using canvas and javascript?

I am trying to create a blackhole simulation that will display a blackhole and 100 circles travelling away from it at a speed that would be decreasing because of gravity. Here is my code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>test trou noir</title>
<script>
var canvas = document.getElementById ("space");
var ctx = canvas.getContext ('2d');
var blackhole;
var circle = new Array();
window.onload = init;
function init (){
var G = 6.67e-11, //gravitational constant
c = 3e8, //speed of light (m/s)
M = 12e31, // masseof the blackhole in kg (60 solar masses)
Rs = (2 * G * M) / 9e16, //Schwarzchild radius
pixel_Rs = Rs / 1e3;// scaled radius
blackhole = new Ball (pixel_Rs, 700, 400, "black");
blackhole.draw ();
};
function Ball (radius, posX, posY, color){
this.radius = radius;
this.posX = posX;
this.posY = posY;
this.color = color;
}
Ball.prototype.draw = function (ctx){
var ctx = canvas.getContext ('2d');
ctx.fillStyle = this.color;
ctx.beginPath ();
ctx.arc (this.posX, this.posY, this.radius, 0, 2*Math.PI);
ctx.closePath ();
ctx.fill();
};
</script>
<style>
body {
background-color:#021c36 ;
margin: 0px;}
</style>
</head>
<body>
<canvas id ="space", width = "1400", height = "800">
</canvas>
</body>
</html>
Can someone tell me why I can't make the canvas draw the blackhole and how to create those 100 circles and animate them, I have literally tried everything and I can't make it work
Thanks a lot
You're missing the canvas from your html:
<canvas id="space"/>
You need to pass ctx to your draw function:
blackhole.draw(ctx);
Though it still doesn't draw, but that might be because of the sizes/colors.
update:
Here's a version that you can see: https://jsfiddle.net/gjwh33mq/2/ From here you can gradually change the numbers. (There's some strange bug, the window.onload is not getting called, so I added a call at the end of the js)

Is clearing canvas [ 2D Context ] in HTML5 necessary for good performance?

I have a 2D canvas and drawing circle indefinitely one above the other.
Take this example : http://jsfiddle.net/umaar/fnMvf/
<html>
<head>
</head>
<body>
<canvas id="canvas1" width="500" height="500"></canvas>
</body>
</html>
JavaScript :
var currentEndAngle = 0
var currentStartAngle = 0;
var currentColor = 'black';
var lineRadius = 75;
var lineWidth = 15;
setInterval(draw, 50);
function draw() {
var can = document.getElementById('canvas1'); // GET LE CANVAS
var canvas = document.getElementById("canvas1");
var context = canvas.getContext("2d");
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius;
var width;
var startAngle = currentStartAngle * Math.PI;
var endAngle = (currentEndAngle) * Math.PI;
currentStartAngle = currentEndAngle - 0.01;
currentEndAngle = currentEndAngle + 0.01;
if (Math.floor(currentStartAngle / 2) % 2) {
currentColor = "white";
radius = lineRadius - 1;
width = lineWidth + 3;
} else {
currentColor = "black";
radius = lineRadius;
width = lineWidth;
}
var counterClockwise = false;
context.beginPath();
context.arc(x, y, radius, startAngle, endAngle, counterClockwise);
context.lineWidth = width;
context.lineCap = "round";
// line color
context.strokeStyle = currentColor;
context.stroke();
}
Do I really need to clear canvas at some specific interval ?
How does canvas work in that case ? As it is '2D' context, does it still store previous data ? If yes, What should be approach to achieve smoothness for drawing circle keeping performance in mind ?
Canvas is a drawing surface. When you draw an element (e.g. call fill method), you are just changing the color of some pixels on the drawing surface. The canvas does not store any information about the element being drawn. In your example, there is no need to clear the canvas.

My Line Color is overlapping. What to do?

I'm following the JS tutorial in W3schools and make some improve for the code.
Now My code is as follows:
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="600" height="600"></canvas>
<script>
function getAngle(x, y, angle, h) {
var radians = angle * (Math.PI / 180);
return { x: x + h * Math.cos(radians), y: y + h * Math.sin(radians) };
}
var canvas = document.getElementById('myCanvas');
var lineWidth = 250;
var centerx = canvas.width/2;
var centery = canvas.height/2;
var axisx = canvas.getContext('2d');
var axisy = canvas.getContext('2d');
var L1 = canvas.getContext('2d');
var L2 = canvas.getContext('2d');
var L3 = canvas.getContext('2d');
axisy.beginPath();
axisy.moveTo(centerx, 10);
axisy.lineTo(centerx, 590);
axisy.strokeStyle = '#000000';
axisy.stroke();
axisx.beginPath();
axisx.moveTo(10, centery);
axisx.lineTo(590, centery);
axisx.strokeStyle = '#000000';
axisx.stroke();
L1pos = getAngle(centerx, centery, 25, lineWidth);
L1.moveTo(centerx, centery);
L1.lineTo(L1pos.x, L1pos.y);
L1.strokeStyle = '#ff0000';
L1.stroke();
L2pos = getAngle(centerx, centery, 125, lineWidth);
L2.moveTo(centerx, centery);
L2.lineTo(L2pos.x, L2pos.y);
L2.strokeStyle = '#00ff00';
L2.stroke();
L3pos = getAngle(centerx, centery, 225, lineWidth);
L3.moveTo(centerx, centery);
L3.lineTo(L3pos.x, L3pos.y);
L3.strokeStyle = '#0000ff';
L3.stroke();
</script>
</body>
The result show that all 3 diagonals line (L1, L2, L3) were blue coloured (#0000ff). How to put different color on each line?
Before beginning to draw, you have to call beginPath, to flush the previous line. (see beginPath on w3schools)
L1.beginPath()
see the fiddle: http://jsfiddle.net/UX4gC/

Executing function onclick when function is in document.ready

I'm fairly new to Javascript so I was hoping for a bit of help. I've been playing with animating a graph using canvas and javascript. I have it so that when the page loads, it will fill up the graph to a pre-determined percentage.
I also have some buttons that have an onclick on them, and the aim is for clicking these buttons to execute the animating function again but with a different percentage. However, clicking on them doesn't so a thing.
Any help you could give me on this would be great.
Code:
window.onload = function(){
//canvas initialization
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
//dimensions
var W = canvas.width;
var H = canvas.height;
//Variables
var degrees = 0;
var new_degrees = 0;
var difference = 0;
var color = "#c70505"; //green looks better to me
var bgcolor = "#222";
var text;
var animation_loop, redraw_loop;
function init()
{
//Clear the canvas everytime a chart is drawn
ctx.clearRect(0, 0, W, H);
//Background 360 degree arc
ctx.beginPath();
ctx.strokeStyle = bgcolor;
ctx.lineWidth = 30;
ctx.arc(W/2, H/2, 100, 0, Math.PI*2, false); //you can see the arc now
ctx.stroke();
//gauge will be a simple arc
//Angle in radians = angle in degrees * PI / 180
var radians = degrees * Math.PI / 180;
ctx.beginPath();
ctx.strokeStyle = color;
ctx.lineWidth = 30;
//The arc starts from the rightmost end. If we deduct 90 degrees from the angles
//the arc will start from the topmost end
ctx.arc(W/2, H/2, 100, 0 - 90*Math.PI/180, radians - 90*Math.PI/180, false);
//you can see the arc now
ctx.stroke();
//Lets add the text
ctx.fillStyle = color;
ctx.font = "50px bebas";
text = Math.floor(degrees/360*100) + "%";
//Lets center the text
//deducting half of text width from position x
text_width = ctx.measureText(text).width;
//adding manual value to position y since the height of the text cannot
//be measured easily. There are hacks but we will keep it manual for now.
ctx.fillText(text, W/2 - text_width/2, H/2 + 15);
}
function draw(percent)
{
//Cancel any movement animation if a new chart is requested
if(typeof animation_loop != undefined) clearInterval(animation_loop);
//random degree from 0 to 360
new_degrees = percent
difference = new_degrees - degrees;
//This will animate the gauge to new positions
//The animation will take 1 second
//time for each frame is 1sec / difference in degrees
animation_loop = setInterval(animate_to, 1000/difference);
}
//function to make the chart move to new degrees
function animate_to()
{
//clear animation loop if degrees reaches to new_degrees
if(degrees == new_degrees)
clearInterval(animation_loop);
if(degrees < new_degrees)
degrees++;
else
degrees--;
init();
}
draw(100);
}
<canvas id="canvas" width="300" height="300"></canvas>
<button onclick="draw(360)">100%</button>
<button onclick="draw(270)">75%</button>
The draw function is out of scope as soon as the anonymous function you have assigned to window.onload finishes executing. If you declare the functions in the global scope instead, you'll be able to call them anywhere. Here's a working fiddle.
Try my update:
<script>
//canvas initialization
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
//dimensions
var W = canvas.width;
var H = canvas.height;
//Variables
var degrees = 0;
var new_degrees = 0;
var difference = 0;
var color = "#c70505"; //green looks better to me
var bgcolor = "#222";
var text;
var animation_loop, redraw_loop;
function init()
{
//Clear the canvas everytime a chart is drawn
ctx.clearRect(0, 0, W, H);
//Background 360 degree arc
ctx.beginPath();
ctx.strokeStyle = bgcolor;
ctx.lineWidth = 30;
ctx.arc(W/2, H/2, 100, 0, Math.PI*2, false); //you can see the arc now
ctx.stroke();
//gauge will be a simple arc
//Angle in radians = angle in degrees * PI / 180
var radians = degrees * Math.PI / 180;
ctx.beginPath();
ctx.strokeStyle = color;
ctx.lineWidth = 30;
//The arc starts from the rightmost end. If we deduct 90 degrees from the angles
//the arc will start from the topmost end
ctx.arc(W/2, H/2, 100, 0 - 90*Math.PI/180, radians - 90*Math.PI/180, false);
//you can see the arc now
ctx.stroke();
//Lets add the text
ctx.fillStyle = color;
ctx.font = "50px bebas";
text = Math.floor(degrees/360*100) + "%";
//Lets center the text
//deducting half of text width from position x
text_width = ctx.measureText(text).width;
//adding manual value to position y since the height of the text cannot
//be measured easily. There are hacks but we will keep it manual for now.
ctx.fillText(text, W/2 - text_width/2, H/2 + 15);
}
function draw(percent)
{
//Cancel any movement animation if a new chart is requested
if(typeof animation_loop != undefined) clearInterval(animation_loop);
//random degree from 0 to 360
new_degrees = percent
difference = new_degrees - degrees;
//This will animate the gauge to new positions
//The animation will take 1 second
//time for each frame is 1sec / difference in degrees
animation_loop = setInterval(animate_to, 1000/difference);
}
//function to make the chart move to new degrees
function animate_to()
{
//clear animation loop if degrees reaches to new_degrees
if(degrees == new_degrees)
clearInterval(animation_loop);
if(degrees < new_degrees)
degrees++;
else
degrees--;
init();
}
draw(100);
</script>
<canvas id="canvas" width="300" height="300"></canvas>
<button onclick="draw(360)">100%</button>
<button onclick="draw(270)">75%</button>

Categories