Help fix animation flip timer

Hello everyone, I'm working on a project and I'm having trouble finding a solution. My project is to make an animation of flipping through a page of a book on a Timer (flip timer). To test my animation, I tested it on the seconds. The problem is that the animation isn't synchronized with the change of second, so it runs twice as fast. Here's my code: https://codepen.io/shikamaru098/pen/ZEdvpex
shikamaru
CodePen
flip
...
8 Replies
Chris Bolson
Chris Bolson2mo ago
You are currently initiating the "flip" animation and the counter at two different moments in the code. Whilst JS is fast, that may be causing an issue. You could try moving the animate() function inside of the setInterval code 🤔. I would also look at moving the variables that don't change outside of the setInterval function so that the JS doesn't have to process them again every second. This should also save time and reduce any difference. For example, based on your current code, you could do something like this:
const interval = setInterval( () => {
let now = new Date();
let nowTime = now.getTime();

let days = Math.floor((startTime - nowTime) / DAY_IN_MS);
let hours = Math.floor((startTime - nowTime - days * DAY_IN_MS) / HOUR_IN_MS);
let minutes = Math.floor((startTime -
nowTime -
days * DAY_IN_MS -
hours * HOUR_IN_MS) /
MINUTE_IN_MS
);

let seconds = Math.floor(
(startTime -
nowTime -
days * DAY_IN_MS -
hours * HOUR_IN_MS -
minutes * MINUTE_IN_MS) /
SECOND_IN_MS
);
updateTimer(secondLeftUnite, secondRightUnite, seconds);
updateTimer(minuteLeftUnite, minuteRightUnite, minutes);
updateTimer(hourLeftUnite, hourRightUnite, hours);
}, 1000);

// define static variables outside of the setInterval as they won't change
let inputDate = new Date("2024-10-08");
const startTime = inputDate.getTime();
const SECOND_IN_MS = 1000;
const MINUTE_IN_MS = 60 * SECOND_IN_MS;
const HOUR_IN_MS = 60 * MINUTE_IN_MS;
const DAY_IN_MS = 24 * HOUR_IN_MS;
const interval = setInterval( () => {
let now = new Date();
let nowTime = now.getTime();

let days = Math.floor((startTime - nowTime) / DAY_IN_MS);
let hours = Math.floor((startTime - nowTime - days * DAY_IN_MS) / HOUR_IN_MS);
let minutes = Math.floor((startTime -
nowTime -
days * DAY_IN_MS -
hours * HOUR_IN_MS) /
MINUTE_IN_MS
);

let seconds = Math.floor(
(startTime -
nowTime -
days * DAY_IN_MS -
hours * HOUR_IN_MS -
minutes * MINUTE_IN_MS) /
SECOND_IN_MS
);
updateTimer(secondLeftUnite, secondRightUnite, seconds);
updateTimer(minuteLeftUnite, minuteRightUnite, minutes);
updateTimer(hourLeftUnite, hourRightUnite, hours);
}, 1000);

// define static variables outside of the setInterval as they won't change
let inputDate = new Date("2024-10-08");
const startTime = inputDate.getTime();
const SECOND_IN_MS = 1000;
const MINUTE_IN_MS = 60 * SECOND_IN_MS;
const HOUR_IN_MS = 60 * MINUTE_IN_MS;
const DAY_IN_MS = 24 * HOUR_IN_MS;
You are also updating all of the DOM for every number every time, even though they haven't changed. Again, this is creating unnecessary processing for the JS. I would consider only updating the numbers that have changed. [update] I should add that I am not actually seeing any lag or different timing on your code so, either you have already fixed the issue or it is browser/OS dependent. Another thing that you could do is update the time as soon as the page loads as currently you have to wait a second for the time to make its first change.
const updateClock = () => {
...code to calculate time passed
}

// call the updateClock() function on page load
updateClock();
// set the interval to run every 1 second thereafter
const interval = setInterval(updateClock, 1000);
const updateClock = () => {
...code to calculate time passed
}

// call the updateClock() function on page load
updateClock();
// set the interval to run every 1 second thereafter
const interval = setInterval(updateClock, 1000);
Chris Bolson
Chris Bolson2mo ago
I have forked your pen and made a few changes that I have suggested: https://codepen.io/cbolson/pen/VwJRxPE Take a look and see if they resolve the issue and if what I changed makes any sense.
missymae
missymae2mo ago
The results look functionally the same. If we're all seeing the same thing, the problem is in the design, not the details - the number changes before the "card" flips, breaking the illusion of it being a physical, printed object. The previous value needs to flip.
Chris Bolson
Chris Bolson2mo ago
I think that that is a separate issue. Either that or I miss-understood what the actual problem was. As the OP mentioned it running "twice as fast" I took that to mean that the animation was running faster than the timer so I was concentrating on that issue (admittedly without really getting anywhere as I couldn't reproduce the problem). I must admit that I didn't look too closely at the actual animation itself though clearly that is something that would need to be fixed too. Maybe Rochelin could share a quick video of the issue as they see it to see if we are all seeing the same thing.
Rochelin
Rochelin2mo ago
It's exactly that in the design: the number changes before the card is turned over, which breaks the illusion. In fact, my problem is what myssiemae mentioned in the design: the number change before the card flips
Chris Bolson
Chris Bolson2mo ago
OK, so has nothing to do with the speed. As in your original post you said that "it runs twice as fast" so I took that to mean that the issue was with the speed.
Rochelin
Rochelin2mo ago
Ok but it's possible to fix it?
Chris Bolson
Chris Bolson2mo ago
I think that you will need to delay some of the number changing both on the “flip” numbers and the main numbers. You could also speed up the animation so that it takes less than a second to give you time to see the numbers and less time to see the number swapping. I am working on some changes to my fork of your code but have had to pop out. You can take a look but for now I have only looked at the right-hand number. ah, I have just realized that you had only added the flip to the last number. I thought that I had broken my version 🤪 I think that the timing is pretty good now so I will leave it, at least for now, so you can continue with yours, using my timing adjustments as you feel fit. [update] - the key thing that I was suggesting was to animate the different parts of the number with a slight delay on some parts:
// updatedate right number
setTimeout(() => elementRight[0].innerText = b, 0); // fixed top
setTimeout(() => elementRight[1].innerText = b, 400); // fixed bottom - delay before change
setTimeout(() => elementRight[2].innerText = b, 400); // animated top - delay before change
setTimeout(() => elementRight[3].innerText = b, 0); // animated bottom
// updatedate right number
setTimeout(() => elementRight[0].innerText = b, 0); // fixed top
setTimeout(() => elementRight[1].innerText = b, 400); // fixed bottom - delay before change
setTimeout(() => elementRight[2].innerText = b, 400); // animated top - delay before change
setTimeout(() => elementRight[3].innerText = b, 0); // animated bottom
whilst at the same time speeding up the animation itself to 500ms rather than 1000ms.
Want results from more Discord servers?
Add your server