Issue
This is Cube clock on html/css/javascript. How to make the seconds on the secondCube updating on the left side of the cube, and on the remaining sides of the cube these updated seconds are frozen? Here is an example to make my idea clear to you: the seconds is updated on the left invisible side of the cube, the cube makes a full circle around its axis - at this time the current seconds is frozen, then the seconds is updated again on the left invisible side (see gif image example)GIF image
function updateClock() {
var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
// Extract the last digit of the hour, minute, and second
document.getElementById("hourCube").querySelector(".front").innerText = (hour < 10 ? '0' : '') + hour;
document.getElementById("hourCube").querySelector(".back").innerText = (hour < 10 ? '0' : '') + hour;
document.getElementById("hourCube").querySelector(".top").innerText = (hour < 10 ? '0' : '') + hour;
document.getElementById("hourCube").querySelector(".bottom").innerText = (hour < 10 ? '0' : '') + hour;
document.getElementById("hourCube").querySelector(".left").innerText = (hour < 10 ? '0' : '') + hour;
document.getElementById("hourCube").querySelector(".right").innerText = (hour < 10 ? '0' : '') + hour;
document.getElementById("minuteCube").querySelector(".front").innerText = (minute < 10 ? '0' : '') + minute;
document.getElementById("minuteCube").querySelector(".back").innerText = (minute < 10 ? '0' : '') + minute;
document.getElementById("minuteCube").querySelector(".top").innerText = (minute < 10 ? '0' : '') + minute;
document.getElementById("minuteCube").querySelector(".bottom").innerText = (minute < 10 ? '0' : '') + minute;
document.getElementById("minuteCube").querySelector(".left").innerText = (minute < 10 ? '0' : '') + minute;
document.getElementById("minuteCube").querySelector(".right").innerText = (minute < 10 ? '0' : '') + minute;
document.getElementById("secondCube").querySelector(".front").innerText = (second < 10 ? '0' : '') + second;
document.getElementById("secondCube").querySelector(".back").innerText = (second < 10 ? '0' : '') + second;
document.getElementById("secondCube").querySelector(".top").innerText = (second < 10 ? '0' : '') + second;
document.getElementById("secondCube").querySelector(".bottom").innerText = (second < 10 ? '0' : '') + second;
document.getElementById("secondCube").querySelector(".left").innerText = (second < 10 ? '0' : '') + second;
document.getElementById("secondCube").querySelector(".right").innerText = (second < 10 ? '0' : '') + second;
}
// Initial call to display the time when the page loads
updateClock();
// Update the clock every second
setInterval(updateClock, 1000);
body {
background-color: black;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
}
.clock-container {
perspective: 800px;
}
.cube {
position: relative;
width: 100px;
height: 100px;
transform-style: preserve-3d;
transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg);
animation-duration: 3.5s;
/* Adjust the value for the desired rotation speed */
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.face {
position: absolute;
width: 100px;
height: 100px;
display: flex;
align-items: center;
justify-content: center;
font-size: 75px;
/* Adjust the font size */
font-family: 'Your Chosen Font', sans-serif;
/* Specify the desired font */
color: rgb(0, 0, 0);
background-color: rgb(223, 223, 223);
border: 1px solid rgb(223, 223, 223);
border-radius: 8px;
filter: blur(0.7px);
text-shadow: 5px 5px 5px rgba(255, 255, 255, 0.5), 2px 2px 2px rgba(0, 0, 0, 0.5);
}
#hourCube {
animation-name: rotateHour;
left: -130%;
height: 0%;
}
#minuteCube {
animation-name: rotateMinute;
}
#secondCube {
animation-name: rotateSecond;
left: 130%;
top: -100px;
}
.face.front {
transform: translateZ(50px);
border: -1px solid rgb(255, 255, 255);
/* Edge color */
}
.face.back {
transform: rotateY(180deg) translateZ(50px);
}
.face.top {
transform: rotateX(90deg) translateZ(50px);
}
.face.bottom {
transform: rotateX(-90deg) translateZ(50px);
}
.face.left {
transform: rotateY(-90deg) translateZ(50px);
}
.face.right {
transform: rotateY(90deg) translateZ(50px);
}
@keyframes rotateHour {
from {
transform: rotateY(360deg);
}
to {
transform: rotateY(0deg);
}
}
@keyframes rotateMinute {
from {
transform: rotateX(360deg);
}
to {
transform: rotateX(0deg);
}
}
@keyframes rotateSecond {
from {
transform: rotateY(-360deg);
}
to {
transform: rotateY(0deg);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<title>3D Digital Clock</title>
</head>
<body>
<div class="clock-container">
<div class="cube" id="hourCube">
<div class="face front">0</div>
<div class="face back">0</div>
<div class="face top">0</div>
<div class="face bottom">0</div>
<div class="face left">0</div>
<div class="face right">0</div>
</div>
<div class="cube" id="minuteCube">
<div class="face front">0</div>
<div class="face back">0</div>
<div class="face top">0</div>
<div class="face bottom">0</div>
<div class="face left">0</div>
<div class="face right">0</div>
</div>
<div class="cube" id="secondCube">
<div class="face front">0</div>
<div class="face back">0</div>
<div class="face top">0</div>
<div class="face bottom">0</div>
<div class="face left">0</div>
<div class="face right">0</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
There is also one bug here: on the die that shows the minutes, sometimes the numbers are shown upside down, is there a way to fix this? enter image description here
I want to update the seconds on the sides of secondCube only when the rotation angle is (for example) exactly -90 degrees and freeze the update until it reaches -90 degrees again. I tried this code but it is not working:
function updateClock() {
var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
// Function to get the current rotation angle of the secondCube
function getRotationAngle(cubeId) {
var cube = document.getElementById(cubeId);
var st = window.getComputedStyle(cube, null);
var tr = st.getPropertyValue("transform");
var values = tr.split("(")[1].split(")")[0].split(",");
var a = values[0];
var b = values[1];
var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));
return (angle < 0 ? angle + 360 : angle); // Convert negative angles to positive
}
// Update the clock content only when the rotation angle is precisely -90 degrees
var rotationAngle = getRotationAngle("secondCube");
if (rotationAngle == 90) {
document.getElementById("secondCube").querySelector(".front").innerText = (second < 10 ? '0' : '') + second;
document.getElementById("secondCube").querySelector(".front").innerText = (second < 10 ? '0' : '') + second;
document.getElementById("secondCube").querySelector(".back").innerText = (second < 10 ? '0' : '') + second;
document.getElementById("secondCube").querySelector(".left").innerText = (second < 10 ? '0' : '') + second;
document.getElementById("secondCube").querySelector(".right").innerText = (second < 10 ? '0' : '') + second;
}
document.getElementById("hourCube").querySelector(".front").innerText = (hour < 10 ? '0' : '') + hour;
document.getElementById("hourCube").querySelector(".back").innerText = (hour < 10 ? '0' : '') + hour;
document.getElementById("hourCube").querySelector(".top").innerText = (hour < 10 ? '0' : '') + hour;
document.getElementById("hourCube").querySelector(".bottom").innerText = (hour < 10 ? '0' : '') + hour;
document.getElementById("hourCube").querySelector(".left").innerText = (hour < 10 ? '0' : '') + hour;
document.getElementById("hourCube").querySelector(".right").innerText = (hour < 10 ? '0' : '') + hour;
document.getElementById("minuteCube").querySelector(".front").innerText = (minute < 10 ? '0' : '') + minute;
document.getElementById("minuteCube").querySelector(".back").innerText = (minute < 10 ? '0' : '') + minute;
document.getElementById("minuteCube").querySelector(".top").innerText = (minute < 10 ? '0' : '') + minute;
document.getElementById("minuteCube").querySelector(".bottom").innerText = (minute < 10 ? '0' : '') + minute;
document.getElementById("minuteCube").querySelector(".left").innerText = (minute < 10 ? '0' : '') + minute;
document.getElementById("minuteCube").querySelector(".right").innerText = (minute < 10 ? '0' : '') + minute;
}
// Initial call to display the time when the page loads
updateClock();
// Update the clock every second
setInterval(updateClock, 1000);
Solution
To make things easier to see, I added a green background color to the front face and red and yellow colors to the back faces. As mentioned in the comments, the back face of the minute cube is rotated, so this has been fixed with:
#minuteCube .face.back {
transform: rotateY(180deg) rotateZ(180deg) translateZ(50px);
}
To achieve changing the seconds sequentially on the third cube (i.e. the "seconds" cube), I added if
statements before rendering each face, so that each face will only be rendered every fourth call to the updateClock()
function.
I also changed the length of the animation from 3.5 seconds to 4.0 seconds. This means that the cubes are rotating in 4.0 seconds.
With these changes, it is now possible to achieve the effect you wanted. However, it appears to be dependent on when exactly you start the animation. Most of the time (about 90 percent of the time), the seconds will change on the back face and so the actual change will not be noticeable, however, occasionally, the change occurs on the third cube on the rightmost face and is noticeable.
The same problem occurs with synchronizing the changing of the minutes from 59
to 00
, so I added appropriate if
statements there too.
I suspect that the above synchronization problem may be connected with the way that setInterval
works, but hopefully this solution can give you some more ideas to work from.
As mentioned in the comments, the code could be refactored (i.e. DRY) but I have not done this.
function updateClock(firstTime = false) {
var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
// Extract the last digit of the hour, minute, and second
document.getElementById("hourCube").querySelector(".front").innerText = (hour < 10 ? '0' : '') + hour;
document.getElementById("hourCube").querySelector(".back").innerText = (hour < 10 ? '0' : '') + hour;
document.getElementById("hourCube").querySelector(".left").innerText = (hour < 10 ? '0' : '') + hour;
document.getElementById("hourCube").querySelector(".right").innerText = (hour < 10 ? '0' : '') + hour;
if (firstTime) {
document.getElementById("minuteCube").querySelector(".front").innerText = (minute < 10 ? '0' : '') + minute;
document.getElementById("minuteCube").querySelector(".back").innerText = (minute < 10 ? '0' : '') + minute;
document.getElementById("minuteCube").querySelector(".top").innerText = (minute < 10 ? '0' : '') + minute;
document.getElementById("minuteCube").querySelector(".bottom").innerText = (minute < 10 ? '0' : '') + minute;
}
if (second % 4 === 0)
document.getElementById("minuteCube").querySelector(".front").innerText = (minute < 10 ? '0' : '') + minute;
if (second % 4 === 1)
document.getElementById("minuteCube").querySelector(".top").innerText = (minute < 10 ? '0' : '') + minute;
if (second % 4 === 2)
document.getElementById("minuteCube").querySelector(".back").innerText = (minute < 10 ? '0' : '') + minute;
if (second % 4 === 3)
document.getElementById("minuteCube").querySelector(".bottom").innerText = (minute < 10 ? '0' : '') + minute;
if (firstTime) {
document.getElementById("secondCube").querySelector(".front").innerText = (second < 10 ? '0' : '') + second;
document.getElementById("secondCube").querySelector(".back").innerText = (second < 10 ? '0' : '') + second;
document.getElementById("secondCube").querySelector(".left").innerText = (second < 10 ? '0' : '') + second;
document.getElementById("secondCube").querySelector(".right").innerText = (second < 10 ? '0' : '') + second;
}
if (second % 4 === 0)
document.getElementById("secondCube").querySelector(".front").innerText = (second < 10 ? '0' : '') + second;
if (second % 4 === 1)
document.getElementById("secondCube").querySelector(".left").innerText = (second < 10 ? '0' : '') + second;
if (second % 4 === 2)
document.getElementById("secondCube").querySelector(".back").innerText = (second < 10 ? '0' : '') + second;
if (second % 4 === 3)
document.getElementById("secondCube").querySelector(".right").innerText = (second < 10 ? '0' : '') + second;
}
// Initial call to display the time when the page loads
updateClock(true);
// Update the clock every second
setInterval(updateClock, 1000);
body {
background-color: black;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
}
.clock-container {
perspective: 800px;
}
.cube {
position: relative;
width: 100px;
height: 100px;
transform-style: preserve-3d;
transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg);
animation-duration: 4.0s;
/* Adjust the value for the desired rotation speed */
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.face {
position: absolute;
width: 100px;
height: 100px;
display: flex;
align-items: center;
justify-content: center;
font-size: 75px;
/* Adjust the font size */
font-family: 'Your Chosen Font', sans-serif;
/* Specify the desired font */
color: rgb(0, 0, 0);
background-color: rgb(223, 223, 223);
border: 1px solid rgb(223, 223, 223);
border-radius: 8px;
filter: blur(0.7px);
text-shadow: 5px 5px 5px rgba(255, 255, 255, 0.5), 2px 2px 2px rgba(0, 0, 0, 0.5);
}
#hourCube {
animation-name: rotateHour;
left: -130%;
height: 0%;
}
#minuteCube {
animation-name: rotateMinute;
}
#secondCube {
animation-name: rotateSecond;
left: 130%;
top: -100px;
}
.face.front {
transform: translateZ(50px);
border: -1px solid rgb(255, 255, 255);
background: green;
/* Edge color */
}
.face.back {
transform: rotateY(180deg) translateZ(50px);
background: yellow;
}
#minuteCube .face.back {
transform: rotateY(180deg) rotateZ(180deg) translateZ(50px);
background: red;
}
.face.top {
transform: rotateX(90deg) translateZ(50px);
}
.face.bottom {
transform: rotateX(-90deg) translateZ(50px);
}
.face.left {
transform: rotateY(-90deg) translateZ(50px);
}
.face.right {
transform: rotateY(90deg) translateZ(50px);
}
@keyframes rotateHour {
from {
transform: rotateY(360deg);
}
to {
transform: rotateY(0deg);
}
}
@keyframes rotateMinute {
from {
transform: rotateX(360deg);
}
to {
transform: rotateX(0deg);
}
}
@keyframes rotateSecond {
from {
transform: rotateY(-360deg);
}
to {
transform: rotateY(0deg);
}
}
<div class="clock-container">
<div class="cube" id="hourCube">
<div class="face front">0</div>
<div class="face back">0</div>
<div class="face top">0</div>
<div class="face bottom">0</div>
<div class="face left">0</div>
<div class="face right">0</div>
</div>
<div class="cube" id="minuteCube">
<div class="face front">0</div>
<div class="face back">0</div>
<div class="face top">0</div>
<div class="face bottom">0</div>
<div class="face left">0</div>
<div class="face right">0</div>
</div>
<div class="cube" id="secondCube">
<div class="face front">0</div>
<div class="face back">0</div>
<div class="face top">0</div>
<div class="face bottom">0</div>
<div class="face left">0</div>
<div class="face right">0</div>
</div>
</div>
Answered By - PeterJames
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.