Thea
Thea

Reputation: 27

How can i change the speed of this clock

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

Answers (2)

Thomas
Thomas

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

morriq
morriq

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

Related Questions