make a live clock with existing time in div with javascript - javascript

ok lets say we have a website that need a realtime time;
example :
<div id="updatetime">21:12:52</div>
each seconds update hours:m:second.
what i have in minds using the interval function to do long pool and add the sec +1 if to 60 then add + 1 to m and same as hours. but is there a function already solving this problem?
how do you make this 21:12:52 a moving real clock with javascript that updates each seconds?
i have search google, stackoverflow, many of them tells us how to make the current real time datetime from javascript. but none from an existing time. if there is please do insert the link.

It can be as easy as this:
setInterval(function(){
document.getElementById("updatetime").innerHTML = (new Date()).toLocaleTimeString();
}, 1000);
Or use the other Date methods to fine-tune your output.
Update
I only now realized that OP was asking not about incrementing an element with the current time but with a predetermined time.
That's less trivial, but here is a solution that should fit the original question:
function increment_time_element(element, delay) {
var interval, last,
time_pattern = /(\d+):(\d+):(\d+)/,
start = element.innerHTML.match(time_pattern),
then = new Date;
then.setHours (parseInt(start[1], 10) || 0);
then.setMinutes(parseInt(start[2], 10) || 0);
then.setSeconds(parseInt(start[3], 10) || 0);
function now() {
return Date.now ? Date.now() : (new Date).getTime();
}
last = now();
interval = setInterval(function () {
var current = now();
// correct for any interval drift by using actual difference
then.setTime(then.getTime() + current - last)
last = current;
element.innerHTML = then.toString().match(time_pattern)[0];
}, delay || 1000);
return {cancel: function() { clearInterval(interval) }};
}
// Usage:
var incrementing_time =
increment_time_element(document.getElementById("updatetime"));
// Then, if you want to cancel:
incrementing_time.cancel();

If you don't need a very high fidelity, you can use this way:
​var container = document.getElementById("updatetime").firstChild;
var values = container.nodeValue.split(":");
// Because there is only a datetime specified, I assume is the current date
var now = new Date();
var time = new Date(now.getFullYear(), now.getMonth(), now.getDate(),
values[0], values[1], values​[2]).getTime();
setInterval(function() {
time += 1000;
var date = new Date(time);
var values = [date.getHours(), date.getMinutes(), date.getSeconds()];
for (var i = 0; i < 3; i++)
if (values[i] < 10)
values[i] = "0" + values[i];
container.nodeValue = values.join(":");
}, 1000);
If you want to be more in sync with the current computer clock, then I suggest to you to use setTimeout and adjust the delay argument with the proper elapsed time.
Update: due the comments, it seems the elements to update are not only one and multiple, and the code is using jQuery. Here an approach that works for multiple elements using class to identify them:
var containers = $(".updatetime");
var times = [];
var now = new Date();
containers.each(function(index, node) {
var values = $(node).text().split(":");
times[index] = new Date(
now.getFullYear(), now.getMonth(), now.getDate(),
values[0], values[1], values[2]).getTime();
});
setInterval(function() {
containers.each(function(index, node) {
times[index] += 1000;
var date = new Date(times[index]);
var values = [date.getHours(), date.getMinutes(), date.getSeconds()];
for (var i = 0; i < 3; i++)
if (values[i] < 10)
values[i] = "0" + values[i];
$(node).text(values.join(":"));
});
}, 1000);

If your after a realtime clock that ticks along, take a look at the code I used when I created a "flip clock".
I split each digit into a seperate individual digit to use for graphic placement within the clock, but if you strip it down you will have just text that updates.
Javascript Flip Clock

using HTML canvas
code:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var radius = canvas.height / 2;
ctx.translate(radius, radius);
radius = radius * 0.90
setInterval(drawClock, 1000);
function drawClock() {
drawFace(ctx, radius);
drawNumbers(ctx, radius);
drawTime(ctx, radius);
}
function drawFace(ctx, radius) {
var grad;
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI);
ctx.fillStyle = 'white';
ctx.fill();
grad = ctx.createRadialGradient(0, 0, radius * 0.95, 0, 0, radius * 1.05);
grad.addColorStop(0, '#333');
grad.addColorStop(0.5, 'white');
grad.addColorStop(1, '#333');
ctx.strokeStyle = grad;
ctx.lineWidth = radius * 0.1;
ctx.stroke();
ctx.beginPath();
ctx.arc(0, 0, radius * 0.1, 0, 2 * Math.PI);
ctx.fillStyle = '#333';
ctx.fill();
}
function drawNumbers(ctx, radius) {
var ang;
var num;
ctx.font = radius * 0.15 + "px arial";
ctx.textBaseline = "middle";
ctx.textAlign = "center";
for (num = 1; num < 13; num++) {
ang = num * Math.PI / 6;
ctx.rotate(ang);
ctx.translate(0, -radius * 0.85);
ctx.rotate(-ang);
ctx.fillText(num.toString(), 0, 0);
ctx.rotate(ang);
ctx.translate(0, radius * 0.85);
ctx.rotate(-ang);
}
}
function drawTime(ctx, radius) {
var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
//hour
hour = hour % 12;
hour = (hour * Math.PI / 6) +
(minute * Math.PI / (6 * 60)) +
(second * Math.PI / (360 * 60));
drawHand(ctx, hour, radius * 0.5, radius * 0.07);
//minute
minute = (minute * Math.PI / 30) + (second * Math.PI / (30 * 60));
drawHand(ctx, minute, radius * 0.8, radius * 0.07);
// second
second = (second * Math.PI / 30);
drawHand(ctx, second, radius * 0.9, radius * 0.02);
}
function drawHand(ctx, pos, length, width) {
ctx.beginPath();
ctx.lineWidth = width;
ctx.lineCap = "round";
ctx.moveTo(0, 0);
ctx.rotate(pos);
ctx.lineTo(0, -length);
ctx.stroke();
ctx.rotate(-pos);
}
<canvas id="canvas" width="400" height="400" style="background-color:#333">
</canvas>

you can do it with below code
<!DOCTYPE html>
<html>
<head>
<script>
function startTime() {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
m = checkTime(m);
s = checkTime(s);
document.getElementById('txt').innerHTML =
h + ":" + m + ":" + s;
var t = setTimeout(startTime, 500);
}
function checkTime(i) {
if (i < 10) {i = "0" + i}; // add zero in front of numbers < 10
return i;
}
</script>
</head>
<body onload="startTime()">
<div id="txt"></div>
</body>
</html>

Related

Color changing dots in 2D array based on time

I'm new to coding but I have this idea for sort of a visual clock. I would like to represent how much time in the day has elapsed. I decided to create a grid of dots, each represents 10 seconds in the day. So a dot should change color every 10 seconds and this would progress one row at a time. I have managed to create the grid of 120 columns and 72 rows but I'm having issues correctly comparing the index of the grid to the time elapsed.
Here is my code so far,
function startTime() { //Start clock
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
var t = setTimeout(startTime, 1000);
var currentseconds = Math.floor(((h * 3600) + (m * 60) + s) / 10);
change(currentseconds);
document.getElementById('seconds').innerHTML = currentseconds;
}
//------------------
let ctx = canvas.getContext("2d"); //drawing object
var cwidth = 500; //define canvas width
var cols = 120; // define the number of columns
var rows = 72; // define the numnber of rows
canvas.width = cwidth; //set canvas width
canvas.height = cwidth * (rows / cols); //adjust canvas height to be proportional to the number of rows
ctx.fillStyle = "#373737";
ctx.fillRect(0, 0, canvas.width, canvas.height); //draw and fill rectangle full size of canvas
//------------------
setInterval(change, 1000); //run change function every 1 second
function change(seconds) { //create 2d array grid of dots
var currentseconds = seconds;
for (var i = 0; i < cols; i++) {
for (var j = 0; j < rows; j++) {
var x = i * (cwidth / cols) + ((cwidth / cols) / 2); //spacing of columns
var y = j * (cwidth / cols) + ((cwidth / cols) / 2); //spacing of rows
if ([i][j] <= seconds) {
ctx.fillStyle = "red";
} else {
ctx.fillStyle = "blue";
} // change colour of dots as time increases
ctx.beginPath();
ctx.arc(x, y, 2, 0, (2 * Math.PI));
ctx.closePath();
ctx.fill(); // draw dots
}
}
}
body {
background-color: #424949;
font-family: 'Roboto';
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-51%, -51%)
}
<body onload="startTime(), change()">
<div id="seconds"></div>
<br>
<canvas id="canvas"></canvas>
</body>
Thanks for any help you can provide.
The script determines whether a given dot should be red with the comparison if ([i][j] <= seconds). I am surprised that it works at all. The corresponding value of each dot if you are counting left to right, then top to bottom from the top left corner would be i + j * cols.
function startTime() { //Start clock
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
var t = setTimeout(startTime, 10000);
var currentseconds = Math.floor(((h * 3600) + (m * 60) + s) / 10);
change(currentseconds);
document.getElementById('seconds').innerHTML = currentseconds;
}
//------------------
let ctx = canvas.getContext("2d"); //drawing object
var cwidth = 500; //define canvas width
var cols = 120; // define the number of columns
var rows = 72; // define the numnber of rows
canvas.width = cwidth; //set canvas width
canvas.height = cwidth * (rows / cols); //adjust canvas height to be proportional to the number of rows
ctx.fillStyle = "#373737";
ctx.fillRect(0, 0, canvas.width, canvas.height); //draw and fill rectangle full size of canvas
//------------------
function change(seconds) { //create 2d array grid of dots
var currentseconds = seconds;
ctx.fillStyle = "#373737";
ctx.fillRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < cols; i++) {
for (var j = 0; j < rows; j++) {
var x = i * (cwidth / cols) + ((cwidth / cols) / 2); //spacing of columns
var y = j * (cwidth / cols) + ((cwidth / cols) / 2); //spacing of rows
if (i+j*cols <= seconds) {
ctx.fillStyle = "red";
} else {
ctx.fillStyle = "blue";
} // change colour of dots as time increases
ctx.beginPath();
ctx.arc(x, y, 2, 0, (2 * Math.PI));
ctx.closePath();
ctx.fill(); // draw dots
}
}
}
body {
background-color: #424949;
font-family: 'Roboto';
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-51%, -51%)
}
<body onload="startTime()">
<div id="seconds"></div>
<br>
<canvas id="canvas"></canvas>
</body>
EDIT after comment:
I have edited the script to fix the blinking. These are the problems that caused it:
The change function was called several times. It got called from the startTime (which is correct, as you are passing the time), then immediately from the following html command (incorrect, no time was passed), then form the setInterval (again incorrect, no time was passed).
The setInterval was not necessary. You have a call to change from startTime every 10 seconds.
I have also cleared the rectangle in every iteration of change. If you paint on top of the previous paint, you will see small changes in color and thickness.

How can we stop this HTML5 Canvas wheel at exact points after spin?

In the Below code link HTML5 canvas spin wheel game. I want to stop this canvas at a user-defined position as if the user wants to stop always at 200 texts or 100 texts like that.
Currently, it is stopping at random points I want to control where to stop as in if I want to stop circle at 100 or 200 or 0 whenever I want.
How can we achieve that??? Can anyone Help!!!!!
Attached Codepen link also.
Html file
<div>
<canvas class="spin-wheel" id="canvas" width="300" height="300"></canvas>
</div>
JS file
var color = ['#ca7','#7ac','#77c','#aac','#a7c','#ac7', "#caa"];
var label = ['10', '200','50','100','5','500',"0"];
var slices = color.length;
var sliceDeg = 360/slices;
var deg = 270;
var speed = 5;
var slowDownRand = 0;
var ctx = canvas.getContext('2d');
var width = canvas.width; // size
var center = width/2; // center
var isStopped = false;
var lock = false;
function rand(min, max) {
return Math.random() * (max - min) + min;
}
function deg2rad(deg){ return deg * Math.PI/180; }
function drawSlice(deg, color){
ctx.beginPath();
ctx.fillStyle = color;
ctx.moveTo(center, center);
ctx.arc(center, center, width/2, deg2rad(deg), deg2rad(deg+sliceDeg));
console.log(center, center, width/2, deg2rad(deg), deg2rad(deg+sliceDeg))
ctx.lineTo(center, center);
ctx.fill();
}
function drawText(deg, text) {
ctx.save();
ctx.translate(center, center);
ctx.rotate(deg2rad(deg));
ctx.textAlign = "right";
ctx.fillStyle = "#fff";
ctx.font = 'bold 30px sans-serif';
ctx.fillText(text, 130, 10);
ctx.restore();
}
function drawImg() {
ctx.clearRect(0, 0, width, width);
for(var i=0; i<slices; i++){
drawSlice(deg, color[i]);
drawText(deg+sliceDeg/2, label[i]);
deg += sliceDeg;
}
}
// ctx.rotate(360);
function anim() {
isStopped = true;
deg += speed;
deg %= 360;
// Increment speed
if(!isStopped && speed<3){
speed = speed+1 * 0.1;
}
// Decrement Speed
if(isStopped){
if(!lock){
lock = true;
slowDownRand = rand(0.994, 0.998);
}
speed = speed>0.2 ? speed*=slowDownRand : 0;
}
// Stopped!
if(lock && !speed){
var ai = Math.floor(((360 - deg - 90) % 360) / sliceDeg); // deg 2 Array Index
console.log(slices)
ai = (slices+ai)%slices; // Fix negative index
return alert("You got:\n"+ label[ai] ); // Get Array Item from end Degree
// ctx.arc(150,150,150,8.302780584487312,9.200378485512967);
// ctx.fill();
}
drawImg();
window.requestAnimationFrame(anim);
}
function start() {
anim()
}
drawImg();
Spin wheel codepen
Ease curves
If you where to plot the wheel position over time as it slows to a stop you would see a curve, a curve that looks like half a parabola.
You can get the very same curve if you plot the value of x squared in the range 0 to 1 as in the next snippet, the red line shows the plot of f(x) => x * x where 0 <= x <= 1
Unfortunately the plot is the wrong way round and needs to be mirrored in x and y. That is simple by changing the function to f(x) => 1 - (1 - x) ** 2 (Click the canvas to get the yellow line)
const size = 200;
const ctx = Object.assign(document.createElement("canvas"),{width: size, height: size / 2}).getContext("2d");
document.body.appendChild(ctx.canvas);
ctx.canvas.style.border = "2px solid black";
plot(getData());
plot(unitCurve(x => x * x), "#F00");
ctx.canvas.addEventListener("click",()=>plot(unitCurve(x => 1 - (1 - x) ** 2), "#FF0"), {once: true});
function getData(chart = []) {
var pos = 0, speed = 9, deceleration = 0.1;
while(speed > 0) {
chart.push(pos);
pos += speed;
speed -= deceleration;
}
return chart;
}
function unitCurve(f,chart = []) {
const step = 1 / 100;
var x = 0;
while(x <= 1) {
chart.push(f(x));
x += step
}
return chart;
}
function plot(chart, col = "#000") {
const xScale = size / chart.length, yScale = size / 2 / Math.max(...chart);
ctx.setTransform(xScale, 0, 0, yScale, 0, 0);
ctx.strokeStyle = col;
ctx.beginPath();
chart.forEach((y,x) => ctx.lineTo(x,y));
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.stroke();
}
In animation this curve is an ease in.
We can create function that uses the ease function, takes the time and returns the position of the wheel. We can provide some additional values that controls how long the wheel will take to stop, the starting position and the all important stop position.
function wheelPos(currentTime, startTime, endTime, startPos, endPos) {
// first scale the current time to a value from 0 to 1
const x = (currentTime - startTime) / (endTime - startTime);
// rather than the square, we will use the square root (this flips the curve)
const xx = x ** (1 / 2);
// convert the value to a wheel position
return xx * (endPos - startPos) + startPos;
}
Demo
The demo puts it in action. Rather than using the square root the function in the demo defines the root as the constant slowDownRate = 2.6. The smaller this value the greater start speed and the slower the end speed. A value of 1 means it will move at a constant speed and then stop. The value must be > 0 and < 1
requestAnimationFrame(mainLoop);
Math.TAU = Math.PI * 2;
const size = 160;
const ctx = Object.assign(document.createElement("canvas"),{width: size, height: size}).getContext("2d");
document.body.appendChild(ctx.canvas);
const stopAt = document.createElement("div")
document.body.appendChild(stopAt);
ctx.canvas.style.border = "2px solid black";
var gTime; // global time
const colors = ["#F00","#F80","#FF0","#0C0","#08F","#00F","#F0F"];
const wheelSteps = 12;
const minSpins = 3 * Math.TAU; // min number of spins before stopping
const spinTime = 6000; // in ms
const slowDownRate = 1 / 1.8; // smaller this value the greater the ease in.
// Must be > 0
var startSpin = false;
var readyTime = 0;
ctx.canvas.addEventListener("click",() => { startSpin = !wheel.spinning });
stopAt.textContent = "Click wheel to spin";
const wheel = { // hold wheel related variables
img: createWheel(wheelSteps),
endTime: performance.now() - 2000,
startPos: 0,
endPos: 0,
speed: 0,
pos: 0,
spinning: false,
set currentPos(val) {
this.speed = (val - this.pos) / 2; // for the wobble at stop
this.pos = val;
},
set endAt(pos) {
this.endPos = (Math.TAU - (pos / wheelSteps) * Math.TAU) + minSpins;
this.endTime = gTime + spinTime;
this.startTime = gTime;
stopAt.textContent = "Spin to: "+(pos + 1);
}
};
function wheelPos(currentTime, startTime, endTime, startPos, endPos) {
const x = ((currentTime - startTime) / (endTime - startTime)) ** slowDownRate;
return x * (endPos - startPos) + startPos;
}
function mainLoop(time) {
gTime = time;
ctx.setTransform(1,0,0,1,0,0);
ctx.clearRect(0, 0, size, size);
if (startSpin && !wheel.spinning) {
startSpin = false;
wheel.spinning = true;
wheel.startPos = (wheel.pos % Math.TAU + Math.TAU) % Math.TAU;
wheel.endAt = Math.random() * wheelSteps | 0;
} else if (gTime <= wheel.endTime) { // wheel is spinning get pos
wheel.currentPos = wheelPos(gTime, wheel.startTime, wheel.endTime, wheel.startPos, wheel.endPos);
readyTime = gTime + 1500;
} else { // wobble at stop
wheel.speed += (wheel.endPos - wheel.pos) * 0.0125;
wheel.speed *= 0.95;
wheel.pos += wheel.speed;
if (wheel.spinning && gTime > readyTime) {
wheel.spinning = false;
stopAt.textContent = "Click wheel to spin";
}
}
// draw wheel
ctx.setTransform(1,0,0,1,size / 2, size / 2);
ctx.rotate(wheel.pos);
ctx.drawImage(wheel.img, -size / 2 , - size / 2);
// draw marker shadow
ctx.setTransform(1,0,0,1,1,4);
ctx.fillStyle = "#0004";
ctx.beginPath();
ctx.lineTo(size - 13, size / 2);
ctx.lineTo(size, size / 2 - 7);
ctx.lineTo(size, size / 2 + 7);
ctx.fill();
// draw marker
ctx.setTransform(1,0,0,1,0,0);
ctx.fillStyle = "#F00";
ctx.beginPath();
ctx.lineTo(size - 13, size / 2);
ctx.lineTo(size, size / 2 - 7);
ctx.lineTo(size, size / 2 + 7);
ctx.fill();
requestAnimationFrame(mainLoop);
}
function createWheel(steps) {
const ctx = Object.assign(document.createElement("canvas"),{width: size, height: size}).getContext("2d");
const s = size, s2 = s / 2, r = s2 - 4;
var colIdx = 0;
for (let a = 0; a < Math.TAU; a += Math.TAU / steps) {
const aa = a - Math.PI / steps;
ctx.fillStyle = colors[colIdx++ % colors.length];
ctx.beginPath();
ctx.moveTo(s2, s2);
ctx.arc(s2, s2, r, aa, aa + Math.TAU / steps);
ctx.fill();
}
ctx.fillStyle = "#FFF";
ctx.beginPath();
ctx.arc(s2, s2, 12, 0, Math.TAU);
ctx.fill();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.arc(s2, s2, r, 0, Math.TAU);
ctx.moveTo(s2 + 12, s2);
ctx.arc(s2, s2, 12, 0, Math.TAU);
for (let a = 0; a < Math.TAU; a += Math.TAU / steps) {
const aa = a - Math.PI / steps;
ctx.moveTo(Math.cos(aa) * 12 + s2, Math.sin(aa) * 12 + s2);
ctx.lineTo(Math.cos(aa) * r + s2, Math.sin(aa) * r + s2);
}
//ctx.fill("evenodd");
ctx.stroke();
ctx.fillStyle = "#000";
ctx.font = "13px arial black";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
const tr = r - 8;
var idx = 1;
for (let a = 0; a < Math.TAU; a += Math.TAU / steps) {
const dx = Math.cos(a);
const dy = Math.sin(a);
ctx.setTransform(dy, -dx, dx, dy, dx * (tr - 4) + s2, dy * (tr - 4) + s2);
ctx.fillText(""+ (idx ++), 0, 0);
}
return ctx.canvas;
}
body { font-family: arial }

How to assemble the following code base in the Canvas based analog clock with Clockface having 28 hours and 112 minutes

The hours will shift when the minute hand hits 56 minutes in the 112 minute clock.(the position on 56 will be 14th hour as per the following code.
We tried many solutions through many days and finally had a breakthrough with the help of Kaiido from Stackoverflow community. It has become a complete solution for the first part of our clock system for Moon.
We currently blocked in the step of assembling the digital values into the analog Canvas clock system. The purpose of this clocks work is to fulfill an ambition of helping & joining hands with the scientific community. Your contribution with our efforts is highly respected.
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var radius = canvas.height / 2;
ctx.translate(radius, radius);
radius = radius * 0.90
setInterval(drawClock, 1000);
function drawClock() {
drawFace(ctx, radius);
drawNumbers(ctx, radius);
drawTime(ctx, radius);
}
function drawFace(ctx, radius) {
var grad;
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI);
ctx.fillStyle = 'white';
ctx.fill();
grad = ctx.createRadialGradient(0, 0, radius * 0.95, 0, 0, radius * 1.05);
grad.addColorStop(0, '#333');
grad.addColorStop(0.5, 'white');
grad.addColorStop(1, '#333');
ctx.strokeStyle = grad;
ctx.lineWidth = radius * 0.1;
ctx.stroke();
ctx.beginPath();
ctx.arc(0, 0, radius * 0.1, 0, 2 * Math.PI);
ctx.fillStyle = '#333';
ctx.fill();
}
function drawNumbers(ctx, radius) {
var ang;
var num;
ctx.font = radius * 0.08 + "px arial";
ctx.textBaseline = "middle";
ctx.textAlign = "center";
for (num = 1; num < 29; num++) {
ang = num * Math.PI / 14;
ctx.rotate(ang);
ctx.translate(0, -radius * 0.85);
ctx.rotate(-ang);
ctx.fillText(num.toString(), 0, 0);
ctx.rotate(ang);
ctx.translate(0, radius * 0.85);
ctx.rotate(-ang);
}
}
function drawTime(ctx, radius) {
var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
//hour
hour = hour % 12;
hour = (hour * Math.PI / 6) +
(minute * Math.PI / (6 * 60)) +
(second * Math.PI / (360 * 60));
drawHand(ctx, hour, radius * 0.5, radius * 0.07);
//minute
minute = (minute * Math.PI / 30) + (second * Math.PI / (30 * 60));
drawHand(ctx, minute, radius * 0.8, radius * 0.07);
// second
second = (second * Math.PI / 30);
drawHand(ctx, second, radius * 0.9, radius * 0.02);
}
function drawHand(ctx, pos, length, width) {
ctx.beginPath();
ctx.lineWidth = width;
ctx.lineCap = "round";
ctx.moveTo(0, 0);
ctx.rotate(pos);
ctx.lineTo(0, -length);
ctx.stroke();
ctx.rotate(-pos);
}
<html>
<body>
<canvas id="canvas" width="400" height="400" style="background-color:#333">
</canvas>
</body>
</html>
The values are to be inserted from the following code base, where the
minutes seconds and hours run using the following format,
28 hours = 1 day
56 mins = 1 hour
56 seconds = 1 minute
// our constants
var ms_per_sec = 1000; // 1000
var sec_per_min = 56; // 55.54920598892;
var min_per_hr = 56; // 55.54920598892;
var hrs_per_day = 28;
// let's make our target date at some fixed distance in our own time system
var countDownDate = new Date().getTime() +
(1 * hrs_per_day * min_per_hr * sec_per_min * ms_per_sec) + // 1 day
(2 * min_per_hr * sec_per_min * ms_per_sec) + // two hours
(1 * sec_per_min * ms_per_sec) + // 1 minutes
(5 * ms_per_sec); // 5 seconds
// Update the count down every frame
function loop() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var total_ms = (countDownDate + now);
// from here our values are based on our own time system
var total_seconds = (total_ms / ms_per_sec);
var total_minutes = (total_seconds/ sec_per_min);
var total_hours = (total_minutes / min_per_hr);
var total_days = (total_hours / hrs_per_day);
var days = Math.floor(total_days);
var hours = Math.floor(total_hours % hrs_per_day);
var minutes = Math.floor(total_minutes % 112);
var seconds = Math.floor(total_seconds % sec_per_min);
// Output the result in an element with id="demo"
document.getElementById("demo").textContent = days + "d " + hours + "h "
+ minutes + "m " + seconds + "s ";
// If the count down is over, write some text
if (total_ms < 0) {
document.getElementById("demo").innerHTML = "EXPIRED";
return;
}
requestAnimationFrame(loop);
}
loop();
<html>
<body>
<div id="demo"></div>
</body>
</html>
The problem faced is that the analog clock has a settimeInterval that
makes the looped code execute at a faster rate, messing with the time of
the clock. Is there a way to execute the analog clock in a cleaner way.
We are happy to have arrived at the solution for the digital clock with
the help of the stackoverflow community. The hours assembled in the
digital clock are running perfectly as expected. We are looking forward
to the solution on the analog clock. Your help towards our Research work
with ourmoonlife is highly respected. We consider our work to be the
common property of this planet, we welcome you to join hands with us.
Thanks for the wonderful opportunity.
You already have the correct logic to get your time in Hour:Minutes:Seconds format.
To draw it as an analogous clock, you just have to convert these values to angle.
On 12h clocks, we do ((Math.PI * 2) / 12) * (hour % 12), or more literally, (full_circle / number_of_hours_per_circle) * (hour % number_of_hours_per_circle).
In your project, you have 28 hours per day, so you could try to make a 14hrs clock to keep AM/PM format, but you're not forced to.
Now, your rounded 56 minutes per hours maps pretty well with the 28 hours per day (4 minutes pet tick on a AM/PM clock, or 2 minutes per tick on a 28H clock), but beware that your original
55.54920598892 wouldn't map so well.
// our constants
var ms_per_sec = 1000; // 1000
var sec_per_min = 56; // 55.54920598892;
var min_per_hr = 56; // 55.54920598892;
var hrs_per_day = 28;
// let's make our target date at some fixed distance in our own time system
var countDownDate = new Date().getTime() +
(1 * hrs_per_day * min_per_hr * sec_per_min * ms_per_sec) + // 1 day
(2 * min_per_hr * sec_per_min * ms_per_sec) + // two hours
(1 * sec_per_min * ms_per_sec) + // 1 minutes
(5 * ms_per_sec); // 5 seconds
// Update the count down every frame
function loop() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var total_ms = (countDownDate + now);
// from here our values are based on our own time system
var total_seconds = (total_ms / ms_per_sec);
var total_minutes = (total_seconds/ sec_per_min);
var total_hours = (total_minutes / min_per_hr);
var total_days = (total_hours / hrs_per_day);
var days = Math.floor(total_days);
var hours = Math.floor(total_hours % hrs_per_day);
var minutes = Math.floor(total_minutes % 112);
var seconds = Math.floor(total_seconds % sec_per_min);
// Output the result in an element with id="demo"
draw(hours, minutes, seconds);
// If the count down is over, write some text
if (total_ms < 0) {
document.getElementById("demo").innerHTML = "EXPIRED";
return;
}
requestAnimationFrame(loop);
}
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var radius = canvas.height / 2;
radius = radius * 0.90
function draw(hours, minutes, seconds) {
ctx.setTransform(1,0,0,1,0,0);
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.translate(canvas.height / 2, canvas.height / 2);
drawFace(ctx, radius);
drawNumbers(ctx, radius);
drawTime(ctx, radius, hours, minutes, seconds);
}
function drawFace(ctx, radius) {
var grad;
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI);
ctx.fillStyle = 'white';
ctx.fill();
grad = ctx.createRadialGradient(0, 0, radius * 0.95, 0, 0, radius * 1.05);
grad.addColorStop(0, '#333');
grad.addColorStop(0.5, 'white');
grad.addColorStop(1, '#333');
ctx.strokeStyle = grad;
ctx.lineWidth = radius * 0.1;
ctx.stroke();
ctx.beginPath();
ctx.arc(0, 0, radius * 0.1, 0, 2 * Math.PI);
ctx.fillStyle = '#333';
ctx.fill();
}
function drawNumbers(ctx, radius) {
var ang;
var num;
ctx.font = radius * 0.08 + "px arial";
ctx.textBaseline = "middle";
ctx.textAlign = "center";
for (num = 1; num < 29; num++) {
ang = num * Math.PI / 14;
ctx.rotate(ang);
ctx.translate(0, -radius * 0.85);
ctx.rotate(-ang);
ctx.fillText(num.toString(), 0, 0);
ctx.rotate(ang);
ctx.translate(0, radius * 0.85);
ctx.rotate(-ang);
}
}
function drawTime(ctx, radius, hours, minutes, seconds) {
const angle_hours = getAngle(hours, hrs_per_day);
drawHand(ctx, angle_hours, radius * 0.5, radius * 0.07);
//minute
const angle_minutes = getAngle(minutes, min_per_hr);
drawHand(ctx, angle_minutes, radius * 0.8, radius * 0.07);
// second
const angle_seconds = getAngle(seconds, sec_per_min);
drawHand(ctx, angle_seconds, radius * 0.9, radius * 0.02);
}
function getAngle(value, max) {
return (Math.PI*2 / max) * value;
}
function drawHand(ctx, pos, length, width) {
ctx.beginPath();
ctx.lineWidth = width;
ctx.lineCap = "round";
ctx.moveTo(0, 0);
ctx.rotate(pos);
ctx.lineTo(0, -length);
ctx.stroke();
ctx.rotate(-pos);
}
loop();
<html>
<body>
<canvas id="canvas" width="400" height="400" style="background-color:#333">
</canvas>
</body>
</html>
And if you want the 14H AM/PM variant:
// our constants
var ms_per_sec = 1000; // 1000
var sec_per_min = 56; // 55.54920598892;
var min_per_hr = 56; // 55.54920598892;
var hrs_per_day = 28;
// let's make our target date at some fixed distance in our own time system
var countDownDate = new Date().getTime() +
(1 * hrs_per_day * min_per_hr * sec_per_min * ms_per_sec) + // 1 day
(2 * min_per_hr * sec_per_min * ms_per_sec) + // two hours
(1 * sec_per_min * ms_per_sec) + // 1 minutes
(5 * ms_per_sec); // 5 seconds
// Update the count down every frame
function loop() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var total_ms = (countDownDate + now);
// from here our values are based on our own time system
var total_seconds = (total_ms / ms_per_sec);
var total_minutes = (total_seconds/ sec_per_min);
var total_hours = (total_minutes / min_per_hr);
var total_days = (total_hours / hrs_per_day);
var days = Math.floor(total_days);
var hours = Math.floor(total_hours % hrs_per_day);
var minutes = Math.floor(total_minutes % 112);
var seconds = Math.floor(total_seconds % sec_per_min);
// Output the result in an element with id="demo"
draw(hours, minutes, seconds);
// If the count down is over, write some text
if (total_ms < 0) {
document.getElementById("demo").innerHTML = "EXPIRED";
return;
}
requestAnimationFrame(loop);
}
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var radius = canvas.height / 2;
radius = radius * 0.90
function draw(hours, minutes, seconds) {
ctx.setTransform(1,0,0,1,0,0);
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.translate(canvas.height / 2, canvas.height / 2);
drawFace(ctx, radius);
drawNumbers(ctx, radius);
drawTime(ctx, radius, hours, minutes, seconds);
}
function drawFace(ctx, radius) {
var grad;
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI);
ctx.fillStyle = 'white';
ctx.fill();
grad = ctx.createRadialGradient(0, 0, radius * 0.95, 0, 0, radius * 1.05);
grad.addColorStop(0, '#333');
grad.addColorStop(0.5, 'white');
grad.addColorStop(1, '#333');
ctx.strokeStyle = grad;
ctx.lineWidth = radius * 0.1;
ctx.stroke();
ctx.beginPath();
ctx.arc(0, 0, radius * 0.1, 0, 2 * Math.PI);
ctx.fillStyle = '#333';
ctx.fill();
}
function drawNumbers(ctx, radius) {
var ang;
var num;
ctx.font = radius * 0.08 + "px arial";
ctx.textBaseline = "middle";
ctx.textAlign = "center";
for (num = 1; num < 15; num++) {
ang = num * Math.PI / (14/2);
ctx.rotate(ang);
ctx.translate(0, -radius * 0.85);
ctx.rotate(-ang);
ctx.fillText(num.toString(), 0, 0);
ctx.rotate(ang);
ctx.translate(0, radius * 0.85);
ctx.rotate(-ang);
}
}
function drawTime(ctx, radius, hours, minutes, seconds) {
const angle_hours = getAngle(hours % hrs_per_day/2, hrs_per_day/2);
drawHand(ctx, angle_hours, radius * 0.5, radius * 0.07);
//minute
const angle_minutes = getAngle(minutes, min_per_hr);
drawHand(ctx, angle_minutes, radius * 0.8, radius * 0.07);
// second
const angle_seconds = getAngle(seconds, sec_per_min);
drawHand(ctx, angle_seconds, radius * 0.9, radius * 0.02);
}
function getAngle(value, max) {
return (Math.PI*2 / max) * value;
}
function drawHand(ctx, pos, length, width) {
ctx.beginPath();
ctx.lineWidth = width;
ctx.lineCap = "round";
ctx.moveTo(0, 0);
ctx.rotate(pos);
ctx.lineTo(0, -length);
ctx.stroke();
ctx.rotate(-pos);
}
loop();
<html>
<body>
<canvas id="canvas" width="400" height="400" style="background-color:#333">
</canvas>
</body>
</html>

Requesting Solution for a problem when clock hand jumps 1 hour every 2 hours. Would like it to run smoothly though the clock face

Good Afternoon,
We have created an analog clock that runs in the following format
28 hours = 1 day
56 minutes = 1 hour
56 seconds = 1 minute
Where in the analog 28 hour clock, the seconds run through the entire clock face for 112 ticks. Where the minute shifts when the seconds hit 56 and 112. Similarly the hour shifts gradually through a 56 hour period. We notice that the hour hand shifts abnormally every 2 hours when the minute crosses 56 minute mark at 14.
Can anyone help us with a solution in the solving the blocker we are going through.
We are creating the above clock for our Research work in "Our Moon Life" organisation. The intentions of this Research work is to help the Science Community in creating a living condition on the Moon. We consider the entire Research work is a common property. Your help in our Research work is being accepted with the utmost respect.
Thank you very much,
Kind Regards.
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var radius = canvas.height / 2;
ctx.translate(radius, radius);
radius = radius * 0.90
setInterval(drawClock, 1000);
var ms_per_sec = 0.984; // 1000
var sec_per_min = 56; // 55.54920598892;
var min_per_hr = 56; // 55.54920598892;
var hrs_per_day = 28;
// let's make our target date at some fixed distance in our own time system
const countDownDate = 1555157555171; // 5 seconds
function loop() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var total_ms = (countDownDate + now);
// from here our values are based on our own time system
var total_seconds = (total_ms / ms_per_sec);
var total_minutes = (total_seconds/ sec_per_min);
var total_hours = (total_minutes / min_per_hr);
var total_days = (total_hours / hrs_per_day);
var days = Math.floor(total_days);
var hours = Math.floor(total_hours % hrs_per_day);
var minutes = Math.floor(total_minutes % 112);
var seconds = Math.floor(total_seconds % 112);
// Output the result in an element with id="demo"
document.getElementById("demo").textContent = hours + "h "
+ minutes + "m " + seconds + "s ";
drawFace(ctx, radius);
drawNumbers(ctx, radius);
drawTime(ctx, radius, days, hours, minutes, seconds);
// If the count down is over, write some text
if (total_ms < 0) {
document.getElementById("demo").innerHTML = "EXPIRED";
return;
}
requestAnimationFrame(loop);
}
loop();
function drawClock() {
}
function drawFace(ctx, radius) {
var grad;
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2*Math.PI);
ctx.fillStyle = 'white';
ctx.fill();
grad = ctx.createRadialGradient(0,0,radius*0.95, 0,0,radius*1.05);
grad.addColorStop(0, '#333');
grad.addColorStop(0.5, 'white');
grad.addColorStop(1, '#333');
ctx.strokeStyle = grad;
ctx.lineWidth = radius*0.1;
ctx.stroke();
ctx.beginPath();
ctx.arc(0, 0, radius*0.1, 0, 2*Math.PI);
ctx.fillStyle = '#333';
ctx.fill();
}
function drawNumbers(ctx, radius) {
var ang;
var num;
ctx.font = radius*0.08 + "px arial";
ctx.textBaseline="middle";
ctx.textAlign="center";
for(num = 1; num < 29; num++){
ang = num * Math.PI / 14;
ctx.rotate(ang);
ctx.translate(0, -radius*0.85);
ctx.rotate(-ang);
ctx.fillText(num.toString(), 0, 0);
ctx.rotate(ang);
ctx.translate(0, radius*0.85);
ctx.rotate(-ang);
}
}
function drawTime(ctx, radius, days, hours, minutes, seconds){
var hour = hours;
var minute = minutes;
var second = seconds;
//hour
hour=hours%28;
hour=(hours*Math.PI/14)+
(minutes*Math.PI/(14*112))+
(seconds*Math.PI/(1568*112));
drawHand(ctx, hour, radius*0.5, radius*0.07);
//minute
minute=(minutes*Math.PI/56)+(seconds*Math.PI/(224*112));
drawHand(ctx, minute, radius*0.8, radius*0.07);
// second
second=(seconds*Math.PI/56);
drawHand(ctx, second, radius*0.9, radius*0.02);
}
function drawHand(ctx, pos, length, width) {
ctx.beginPath();
ctx.lineWidth = width;
ctx.lineCap = "round";
ctx.moveTo(0,0);
ctx.rotate(pos);
ctx.lineTo(0, -length);
ctx.stroke();
ctx.rotate(-pos);
}
<html>
<body>
<p id="demo"></p>
<canvas id="canvas" width="400" height="400"
style="background-color:#333">
</canvas>
</body>
</html>
The problem lies in the way you calculate minutes and seconds using either 56 or 112 depending on how you are going to use them. I fixed it in this fiddle: https://jsfiddle.net/1kx3scug/
The only change is:
hour = ((second / sec_per_min + minute) / min_per_hr + hour) / hrs_per_day * 2 * Math.PI;
inside drawTime

How to spin wheel after specified time is reached?

I am working on small project of lucky draw number, am able to spin the wheel after user clicks button but not able to do it automatically, means I want to show count Down after time is reached wheel spins. I have used set Interval method but its not working.
window.onload = function () {
var fiveMinutes = 10 * 1,
display = document.querySelector('#count');
startTimer(fiveMinutes, display);
};
function startTimer(duration, display) {
var timer = duration, minutes, seconds;
setInterval(function ()
{
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = "Wheel Will Spin After: "+minutes + ":" + seconds;
if (--timer < 0) {
//timer = duration;
spin();
if(timer<=-1)
{
display.textContent = "Wheel Will Spin After: ";
}
}
}, 1000);
var colors = ["#B8D430", "#3AB745", "#029990", "#3501CB",
"#2E2C75", "#673A7E", "#CC0071", "#F80120",
"#F35B20", "#FB9A00", "#FFCC00", "#FEF200","#FEFAAA","#FEFA1A"];
var restaraunts = ["1", "2", "3", "4","5", "6", "7", "8","9", "10", "11", "12","13","14"];
var startAngle = 0;
var arc = Math.PI / 7;
var spinTimeout = null;
var spinArcStart = 10;
var spinTime = 0;
var spinTimeTotal = 0;
var ctx;
function draw() {
drawRouletteWheel();
}
function drawRouletteWheel() {
var canvas = document.getElementById("wheelcanvas");
if (canvas.getContext) {
var outsideRadius = 200;
var textRadius = 160;
var insideRadius = 125;
ctx = canvas.getContext("2d");
ctx.clearRect(0,0,500,500);
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.font = 'bold 20px Times New Roman';
for(var i = 0; i < 14; i++) {
var angle = startAngle + i * arc;
ctx.fillStyle = colors[i];
ctx.beginPath();
ctx.arc(250, 250, outsideRadius, angle, angle + arc, false);
ctx.arc(250, 250, insideRadius, angle + arc, angle, true);
ctx.stroke();
ctx.fill();
ctx.save();
ctx.shadowOffsetX = -1;
ctx.shadowOffsetY = -1;
ctx.shadowBlur = 0;
ctx.shadowColor = "rgb(220,220,220)";
ctx.fillStyle = "black";
ctx.translate(250 + Math.cos(angle + arc / 2) * textRadius, 250 + Math.sin(angle + arc / 2) * textRadius);
ctx.rotate(angle + arc / 2 + Math.PI / 2);
var text = restaraunts[i];
ctx.fillText(text, -ctx.measureText(text).width / 2, 0);
ctx.restore();
}
//Arrow
ctx.fillStyle = "black";
ctx.beginPath();
ctx.moveTo(250 - 4, 250 - (outsideRadius + 5));
ctx.lineTo(250 + 4, 250 - (outsideRadius + 5));
ctx.lineTo(250 + 4, 250 - (outsideRadius - 5));
ctx.lineTo(250 + 9, 250 - (outsideRadius - 5));
ctx.lineTo(250 + 0, 250 - (outsideRadius - 13));
ctx.lineTo(250 - 9, 250 - (outsideRadius - 5));
ctx.lineTo(250 - 4, 250 - (outsideRadius - 5));
ctx.lineTo(250 - 4, 250 - (outsideRadius + 5));
ctx.fill();
}
}
function spin() {
spinAngleStart = Math.random() * 10 + 10;
spinTime = 5;
spinTimeTotal = Math.random() * 3 + 4 * 2000;
rotateWheel();
}
function rotateWheel() {
spinTime += 20;
if(spinTime >= spinTimeTotal) {
stopRotateWheel();
return;
}
var spinAngle = spinAngleStart - easeOut(spinTime, 0, spinAngleStart, spinTimeTotal);
startAngle += (spinAngle * Math.PI / 180);
drawRouletteWheel();
spinTimeout = setTimeout('rotateWheel()', 10);
}
function stopRotateWheel() {
clearTimeout(spinTimeout);
var degrees = startAngle * 180 / Math.PI + 90;
var arcd = arc * 180 / Math.PI;
var index = Math.floor((360 - degrees % 360) / arcd);
ctx.save();
ctx.font = 'bold 12px sans-serif';
var text = restaraunts[index]
//ctx.fillText(text, 250 - ctx.measureText(text).width / 2, 250 + 10);
//window.location = "navto://"+restaraunts[index]+"_stack";
//alert(text);
document.getElementById("msg").innerHTML=text;
ctx.restore();
}
function easeOut(t, b, c, d) {
var ts = (t/=d)*t;
var tc = ts*t;
return b+c*(tc + -3*ts + 3*t);
}
draw();
}
<html>
<body>
<div id= "count" class="category_heading" >Wheel Will Spin After: </div>
<div id= "msg" class="category_heading" >LUCKY NUMBER IS : </div>
<canvas id="wheelcanvas" width="500" height="500"></canvas>
</body>
</html>
First the solution. Replace
spinTimeout = setTimeout('rotateWheel()', 10);
with
spinTimeout = setTimeout( rotateWheel, 10);
The reason the error occurs is because rotateWheel is a nested function within the startTimer function and not in global scope. The code snippet "rotateWheel()" which is passed to setTimeout as text is compiled into a function in global scope which when executed can't find the rotateWheel function. Replacing the text with a function reference (which is in scope) removes the need to compile the source text in the first place.
In general avoid using JavaScript source snippets within code unless it is a quick and dirty solution to something no-one else is going to see :-).
I take it this is work in progress and there may be more bugs before the code is complete. Good luck.
In response to comment, the wheel continues to rotate because spin() is being called during each interval timer callback after timer goes negative.
var timerId = setInterval(function ()
{
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = "Wheel Will Spin After: "+minutes + ":" + seconds;
if (--timer < 0) {
//timer = duration;
spin();
clearInterval( timerId)
display.textContent = "Wheel Will Spin After: ";
}`
}, 1000);
The solution above is to call spin once and then stop the interval timer. Notice that if( --timer < 0) followed by if(timer<=-1) effectively test the same condition for integers which means the second test is not required.

Categories

Resources