Reputation: 27
I have this clock that gets the local time. However i would like to change so that 6 hours in real time is equal to 24 hours in the clock. So to summarize the clock should speed up by 4x.
// This function gets the current time and injects it into the DOM
function updateClock() {
// Gets the current time
var now = new Date();
// Get the hours, minutes and seconds from the current time
var hours = now.getHours();
var minutes = now.getMinutes();
var seconds = now.getSeconds();
// Format hours, minutes and seconds
if (hours < 10) {
hours = "0" + hours;
}
if (minutes < 10) {
minutes = "0" + minutes;
}
if (seconds < 10) {
seconds = "0" + seconds;
}
// Gets the element we want to inject the clock into
var elem = document.getElementById('clock');
// Sets the elements inner HTML value to our clock data
elem.innerHTML = hours + ':' + minutes;
}
<body onload="setInterval('updateClock()', 200);">
<h1 id="clock"></h1>
</body>
Upvotes: 1
Views: 326
Reputation: 12637
I've added a class I wrote for that kind of stuff. For this demo I've included the seconds so you see the progress.
/*
a (pausable) linear equation over real time
value = _speed * Date.now() + _offset; //+ pausing logic
so basically a clock, a stopwatch, a countdown, a gauge, ...
since it is only a linear equation over time, it is independant of any interval.
It computes the value (using Date.now()) whenever you ask for it. Wether this is ever frame or every hour.
*/
class Clock {
constructor(value=Date.now(), speed=1){
//state; changes only when YOU set one of the properties (value, paused or speed)
this._offset = +value || 0;
this._speed = +speed || 0;
this._paused = true;
//preparing a simple hook to get notified after the state has been updated (maybe to store the new state in the localStorage)
this.onStateChange = undefined;
}
get value(){
return this._paused? this._offset: this._speed*Date.now() + this._offset
}
set value(arg){
let value = +arg || 0;
let offset = this._paused? value: value - this._speed * Date.now();
if(this._offset !== offset){
this._offset = offset;
if(typeof this.onStateChange === "function")
this.onStateChange(this);
}
}
get speed(){
return this._speed
}
set speed(arg){
let speed = +arg || 0;
if(this._speed !== speed){
if(!this._paused)
this._offset += Date.now() * (this._speed - speed);
this._speed = speed;
if(typeof this.onStateChange === "function")
this.onStateChange(this);
}
}
get paused(){
return this._paused
}
set paused(arg){
let pause = !!arg;
if(this._paused !== pause){
this._offset += (pause? 1: -1) * this._speed * Date.now();
this._paused = pause;
if(typeof this.onStateChange === "function")
this.onStateChange(this);
}
}
time(){
let value = this.value,v = Math.abs(value);
return {
value,
//sign: value < 0? "-": "",
seconds: Math.floor(v/1e3)%60,
minutes: Math.floor(v/6e4)%60,
hours: Math.floor(v/36e5)%24,
days: Math.floor(v/864e5)
}
}
valueOf(){
return this.value;
}
start(){
this.paused = false;
return this;
}
stop(){
this.paused = true;
return this;
}
}
function lz(v){ //leading zero
return String(v).padStart(2, 0);
}
function update(){
let {hours, minutes, seconds} = clock.time();
let node = document.getElementById('clock');
node.textContent = [hours, minutes, seconds].map(lz).join(":");
requestAnimationFrame(update);
//setTimeout(update, 250);
}
let clock = new Clock(Date.now(), 4).start();
update();
<h1 id="clock"></h1>
Thank you this is very good, the problem is that this clock should keep going and not start from local time each load.. How would i add that function?
For stuff like that I've added the onStateChange
hook.
You can use it to store the state of this clock, when it is changed.
let clock = new Clock(Date.now(), 4).start();
//add the hook
clock.onStateChange = function(){
//will be called whenever you change the state of this clock. things like changing the speed or paused state, or when you set the value.
localStorage.setItem("clock", JSON.stringify(this));
}
//check wether there is a stored state for this "clock"
if(localStorage.hasItem("clock")){
//simply overwrite the state of the clock.
Object.assign(clock, JSON.parse(localStorage.getItem("clock")))
}else{
//if there's no current state stored, force storing the current state
clock.onStateChange();
}
I've added this code seperately because I don't have access to localStorage
in these snippets here on SO.
Upvotes: 1
Reputation: 424
It's popular question in every language :). I'm sure you can find it on google, but... Here's sample:
let mydate = new Date();
let mydate_millisec=mydate.getTime();
let offset = 4;
function clock() {
next();
setInterval("next()", 1000 / offset);
}
function next() {
console.log(new Date(mydate_millisec).toString());
mydate_millisec += 1000;
}
clock();
Upvotes: 1