Reputation: 11
I'm relatively new to JavaScript and have spent a lot of time with date and time tutorials in the past few weeks, but there is just one thing I simply cannot figure out for my abstract clock project: having the offsetHeight of my div sync to the current time in seconds.
I'd like the clock to display the current time (give or take a few minutes, the times are in 15 minute increments in .paragraphs).
I have #time and I want the current time to sit in this little window by scrolling up via the offsetHeight. The times are in 15 minute increments, so accuracy isn't the goal here, but no matter when I open the page, I see 'Midnight' and it begins scrolling up from there.
I've tried adding delays for the keyframes * percentage but I still can't seem to figure it out. I've also tried having #progress push up #time but that hasn't been working for me either.
Here is my code:
https://jsfiddle.net/mbgtcLs6/2/
Any help would be MUCH appreciated. Thanks in advance!
The HTML:
// total height of time section
var times = document.getElementById("times")
var timesTotalHeight = times.offsetHeight;
setInterval(function() {
var myDate = new Date;
var hoursInSeconds = myDate.getHours() * 60 * 60;
var minutesInSeconds = myDate.getMinutes() * 60;
var seconds = myDate.getSeconds() + minutesInSeconds + hoursInSeconds;
//time is sped up x10
var percentage = seconds;
console.log(percentage)
times.style.height = Math.round(timesTotalHeight * percentage) + "px";
// times.style.keyframes.animationDelay = (seconds * percentage) + "px";
}, 1000)
body {
background-color: white;
/* overflow: hidden;*/
margin: 0 auto;
}
/*#progress position:fixed or absolute, but doesn't push #times up inside as a child or its own class?
*/
/*
#progress {
width: 200px;
background-color: blue;
position: absolute;
left: 10px;
height: 1px;
top: 0;
}*/
.container2 {
width: 88vw;
background-color: white;
height: 13vw;
position: relative;
margin: 0 auto;
margin-top: 20vw;
}
.container:before {
width: 88vw;
height: 13vw;
border-style: solid;
border-color: black;
border-width: 5px;
margin: 0 auto;
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
box-shadow: inset 0 0 20px black;
pointer-events: none;
}
.container {
clip-path: inset(1% 1% 1% 1%);
clip-path-position: fixed;
width: 91vw;
position: relative;
height: 13.8vw;
margin: 0 auto;
overflow: hidden;
}
#times {
font-family: "Happy Times at the IKOB";
text-align: center;
position: relative;
font-size: 7.8vw;
line-height: 4vw;
margin: 0 auto;
/* -webkit-text-stroke-width: 1px;
-webkit-text-stroke-color: black;*/
color: black;
animation-name: upwards;
animation-duration: 3600s;
animation-delay: ;
z-index: -1;
/*height: 100vw;*/
}
/*.times li { line-height: 50px; width: 100vw;
} */
@keyframes upwards {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-100vw);
}
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="assets/clock2.css">
<title>Clock</title>
</head>
<body>
<div class="container2">
<div class="container">
<div id="times">
<p>Midnight</p>
<p>Twelve fifteen</p>
<p>Half past twelve</p>
<p>Quarter til one</p>
<p>One O'Clock</p>
<p>Quarter past one</p>
<p>One thirty in the morning</p>
<p>Twelve thirty AM</p>
<p>Two in the morning</p>
<p>Quarter past two</p>
<p>Half past two</p>
<p>Two forty-five</p>
<p>Three in the morning</p>
<p>Three fifteen</p>
<p>Three thirty AM</p>
<p>Quarter til four</p>
<p>Four in the morning</p>
<p>Four fifteen</p>
<p>Four thirty AM</p>
<p>Four forty five in the morning</p>
<p>Five AM</p>
<p>Quarter past five</p>
<p>Five thirty</p>
<p>Five forty five AM</p>
<p>Six in the morning</p>
<p>Six fifteen in the morning</p>
<p>Six thirty AM</p>
<p>Quarter til seven</p>
<p>Seven in the morning</p>
<p>Seven fifteen AM</p>
<p>Seven thirty in the morning</p>
<p>Seven forty five</p>
<p>Eight in the morning</p>
<p>Quarter past eight</p>
<p>Eight thirty AM</p>
<p>Quarter til nine</p>
<p>Nine in the morning</p>
<p>Nine fifteen</p>
<p>Half past nine</p>
<p>Nine forty five</p>
<p>Ten in the morning</p>
<p>Quarter past ten</p>
<p>Half past ten</p>
<p>Quarter til eleven</p>
<p>Eleven in the morning</p>
<p>Eleven fifteen</p>
<p>Half past eleven</p>
<p>Quarter til noon</p>
<p>Twelve O'Clock</p>
<p>Twelve fifteen</p>
<p>Half past twelve</p>
<p>Quarter til one</p>
<p>One O'Clock</p>
<p>Quarter past one</p>
<p>One thirty in the afternoon</p>
<p>Twelve thirty PM</p>
<p>Two in the afternoon</p>
<p>Quarter past two</p>
<p>Half past two</p>
<p>Two forty-five</p>
<p>Three in the afternoon</p>
<p>Three fifteen</p>
<p>Three thirty PM</p>
<p>Quarter til four</p>
<p>Four in the afternoon</p>
<p>Four fifteen</p>
<p>Four thirty PM</p>
<p>Half past four</p>
<p>Five PM</p>
<p>Quarter past five</p>
<p>Five thirty</p>
<p>Five forty five PM</p>
<p>Six in the evening</p>
<p>Quarter past six</p>
<p>Six thirty PM</p>
<p>Quarter til seven</p>
<p>Seven in the evening</p>
<p>Seven fifteen</p>
<p>Seven thirty in the evening</p>
<p>Seven forty five</p>
<p>Eight in the evening</p>
<p>Quarter past eight</p>
<p>Eight thirty at night</p>
<p>Quarter til nine</p>
<p>Nine at night</p>
<p>Nine fifteen</p>
<p>Half past nine</p>
<p>Nine forty five</p>
<p>Ten in the evening</p>
<p>Quarter past ten</p>
<p>Ten thirty at night</p>
<p>Quarter til eleven</p>
<p>Eleven O'Clock</p>
<p>Eleven fifteen</p>
<p>Half past eleven</p>
<p>Eleven forty five</p>
</div>
</div>
</div>
<div id="progress"></div>
<script type="text/javascript" src="assets/clock2.js"></script>
</body>
</html>
Upvotes: 0
Views: 228
Reputation: 147383
If you reduce your code to the minimum required to demonstrate the issue, it boils down to adjusting the position of the times container based on the percentage of the day that has elapsed. The offset is:
elapsedSeconds / secondsInDay * containerHeight
Which is used to make the container scroll up. If calculated each time, it should reset at midnight.
One issue is that over a daylight saving boundary, the days aren't 24 hours long so the seconds isn't really a constant and on those two days per year the displayed times won't be correct for the whole day. Anyhow, the following just shows the methodology, I'll leave it to you to adjust your code to suit.
// Generate times
function getTimes(){
let mins = ['00','15','30','45'];
let times = [];
for (let i=0; i<=24; i++) {
for (let j=0; j<mins.length; j++) {
times.push(i + ':' + mins[j]);
}
}
return '<p>' + times.join('<p>') + '<p>00:00';
}
// Insert times into container
let c1 = document.getElementById('container1')
c1.innerHTML = getTimes();
!function() {
// Height of container1
let c1style = window.getComputedStyle(c1);
let c1Height = c1style.getPropertyValue('height');
// console.log(c1Height);
// Seconds in day
const secsInDay = 8.64e4;
let adjust = ()=>{
let secsNow = (new Date() - new Date().setHours(0,0,0,0)) / 1000 | 0;
// Adjust offset by proportion of seconds that have elapsed
let offTop = secsNow / secsInDay * parseInt(c1Height) * -1 | 0;
c1.style.top = offTop + 11 + 'px';
};
adjust();
setInterval(adjust, 10000);
}();
#container0 {
border: 1px solid green;
height: 20px;
overflow: hidden;
}
#container1 {
position: relative;
}
#container1 p {
height: 0;
color: blue;
position: relative;
}
<div id="container0">
<div id="container1">
</div>
</div>
The interval is about 10 seconds, I can't see any reason to run it more often. It's also self–adjusting if setInterval drifts, as it will.
Upvotes: 0
Reputation: 1241
I would rearrange your code where a function can check what time it is vs the p
tags you have in your HTML. Add something like a data-time
attribute to know what to check against, and then get the position of the correct p
tag to use for the transform position of your times
element.
Other items I have here:
times
element from loading on initial load until the changeTime
function had time to fire on page load.let times = document.getElementById("times")
// Delay time loading so it can run time check function first
setTimeout(function() {
times.style.opacity = '1';
}, 100);
// Round time to see what quarter hour we are nearest
let roundTime = (hours, minutes, minutesToRound) => {
// Convert hours and minutes to minutes
time = (hours * 60) + minutes;
let rounded = Math.round(time / minutesToRound) * minutesToRound;
let roundedHours = Math.floor(rounded / 60)
let roundedMinutes = rounded % 60
return (roundedHours + ':' + roundedMinutes)
}
// Checks time, changes 'times' position
let changeTime = () => {
let d = new Date(),
hours = d.getHours(),
minutes = d.getMinutes();
// Round time to 15 minutes using function above
let roundedTime = roundTime(hours, minutes, 15)
// Find element that matches the current time
let currentTime = document.querySelectorAll("[data-time='" + roundedTime + "']")[0]
if (!!currentTime) {
// Get position of current time element
let topPos = currentTime.offsetTop
// Set position of times element from above position
times.style.transform = "translateY(-" + topPos + "px)";
}
}
// Run above on page load
changeTime();
// Create interval to only run every 10 seconds
setInterval(changeTime, 10000);
body {
background-color: white;
margin: 0 auto;
}
.container2 {
width: 88vw;
background-color: white;
height: 13vw;
position: relative;
margin: 0 auto;
margin-top: 20vw;
}
.container:before {
width: 88vw;
height: 13vw;
border-style: solid;
border-color: black;
border-width: 5px;
margin: 0 auto;
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
box-shadow: inset 0 0 20px black;
pointer-events: none;
}
.container {
clip-path: inset(1% 1% 1% 1%);
clip-path-position: fixed;
width: 91vw;
position: relative;
height: 13.8vw;
margin: 0 auto;
overflow: hidden;
}
#times {
font-family: "Happy Times at the IKOB";
text-align: center;
position: relative;
font-size: 7.8vw;
line-height: 4vw;
margin: 0 auto;
color: black;
z-index: -1;
/* *New* Opacity ease */
opacity: 0;
transition: opacity 0.5s ease;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="assets/clock2.css">
<title>Clock</title>
</head>
<body>
<div class="container2">
<div class="container">
<div id="times">
<p data-time="0:0">Midnight</p>
<p data-time="0:15">Twelve fifteen</p>
<p data-time="0:30">Half past twelve</p>
<p data-time="0:45">Quarter til one</p>
<p data-time="1:0">One O'Clock</p>
<p data-time="1:15">Quarter past one</p>
<p data-time="1:30">One thirty in the morning</p>
<p data-time="1:45">One forty-five</p>
<p data-time="2:0">Two in the morning</p>
<p data-time="2:15">Quarter past two</p>
<p data-time="2:30">Half past two</p>
<p data-time="2:45">Two forty-five</p>
<p data-time="3:0">Three in the morning</p>
<p data-time="3:15">Three fifteen</p>
<p data-time="3:30">Three thirty AM</p>
<p data-time="3:45">Quarter til four</p>
<p data-time="4:0">Four in the morning</p>
<p data-time="4:15">Four fifteen</p>
<p data-time="4:30">Four thirty AM</p>
<p data-time="4:45">Four forty five in the morning</p>
<p data-time="5:0">Five AM</p>
<p data-time="5:15">Quarter past five</p>
<p data-time="5:30">Five thirty</p>
<p data-time="5:45">Five forty five AM</p>
<p data-time="6:0">Six in the morning</p>
<p data-time="6:15">Six fifteen in the morning</p>
<p data-time="6:30">Six thirty AM</p>
<p data-time="6:45">Quarter til seven</p>
<p data-time="7:0">Seven in the morning</p>
<p data-time="7:15">Seven fifteen AM</p>
<p data-time="7:30">Seven thirty in the morning</p>
<p data-time="7:45">Seven forty five</p>
<p data-time="8:0">Eight in the morning</p>
<p data-time="8:15">Quarter past eight</p>
<p data-time="8:30">Eight thirty AM</p>
<p data-time="8:45">Quarter til nine</p>
<p data-time="9:0">Nine in the morning</p>
<p data-time="9:15">Nine fifteen</p>
<p data-time="9:30">Half past nine</p>
<p data-time="9:45">Nine forty five</p>
<p data-time="10:0">Ten in the morning</p>
<p data-time="10:15">Quarter past ten</p>
<p data-time="10:30">Half past ten</p>
<p data-time="10:45">Quarter til eleven</p>
<p data-time="11:0">Eleven in the morning</p>
<p data-time="11:15">Eleven fifteen</p>
<p data-time="11:30">Half past eleven</p>
<p data-time="11:45">Quarter til noon</p>
<p data-time="12:0">Twelve O'Clock</p>
<p data-time="12:15">Twelve fifteen</p>
<p data-time="12:30">Half past twelve</p>
<p data-time="12:45">Quarter til one</p>
<p data-time="13:0">One O'Clock</p>
<p data-time="13:15">Quarter past one</p>
<p data-time="13:30">One thirty in the afternoon</p>
<p data-time="13:45">Three forty-five</p>
<p data-time="14:0">Two in the afternoon</p>
<p data-time="14:15">Quarter past two</p>
<p data-time="14:30">Half past two</p>
<p data-time="14:45">Two forty-five</p>
<p data-time="15:0">Three in the afternoon</p>
<p data-time="15:15">Three fifteen</p>
<p data-time="15:30">Three thirty PM</p>
<p data-time="15:45">Quarter til four</p>
<p data-time="16:0">Four in the afternoon</p>
<p data-time="16:15">Four fifteen</p>
<p data-time="16:30">Four thirty PM</p>
<p data-time="16:45">Quarter til five</p>
<p data-time="17:0">Five PM</p>
<p data-time="17:15">Quarter past five</p>
<p data-time="17:30">Five thirty</p>
<p data-time="17:45">Five forty five PM</p>
<p data-time="18:0">Six in the evening</p>
<p data-time="18:15">Quarter past six</p>
<p data-time="18:30">Six thirty PM</p>
<p data-time="18:45">Quarter til seven</p>
<p data-time="19:0">Seven in the evening</p>
<p data-time="19:15">Seven fifteen</p>
<p data-time="19:30">Seven thirty in the evening</p>
<p data-time="19:45">Seven forty five</p>
<p data-time="20:0">Eight in the evening</p>
<p data-time="20:15">Quarter past eight</p>
<p data-time="20:30">Eight thirty at night</p>
<p data-time="20:45">Quarter til nine</p>
<p data-time="21:0">Nine at night</p>
<p data-time="21:15">Nine fifteen</p>
<p data-time="21:30">Half past nine</p>
<p data-time="21:45">Nine forty five</p>
<p data-time="22:0">Ten in the evening</p>
<p data-time="22:15">Quarter past ten</p>
<p data-time="22:30">Ten thirty at night</p>
<p data-time="22:45">Quarter til eleven</p>
<p data-time="23:0">Eleven O'Clock</p>
<p data-time="23:15">Eleven fifteen</p>
<p data-time="23:30">Half past eleven</p>
<p data-time="23:45">Eleven forty five</p>
</div>
</div>
</div>
<div id="progress"></div>
<script type="text/javascript" src="assets/clock2.js"></script>
</body>
</html>
Upvotes: 0