<div class="nueclock-wrap">
<div class="outer-ring"></div>
<div class="inner-outer-ring"></div>
<div class="mid-ring"></div>
<div class="hour"><div class="shimmer"><div></div><div></div><div></div></div></div>
<div class="outer-inner-ring"></div>
<div class="inner-inner-ring"></div>
</div>
<div class="minihud ">
<div class="metal-ring"></div>
<div class="scene">
<div class="sky"></div>
<div id="timeContainer" ></div>
<div class="clouds"></div>
<div class="clouds sec"></div>
</div>
</div>
<svg>
<filter id="cloud1" x="-50%" y="-50%" width="200%" height="200%">
<feTurbulence baseFrequency="0.9" numOctaves="4" seed="2"><animate attributeName="baseFrequency" dur="20s" values="0.05;0.02" keyTimes="0; 1" repeatCount="indefinite"/></feTurbulence>
<feOffset dx="200" dy="100" /><feDisplacementMap in="SourceGraphic" scale="20" />
</filter>
<filter id="cloud2" x="-50%" y="-50%" width="200%" height="200%">
<feTurbulence baseFrequency="0.9" numOctaves="3" seed="4"><animate attributeName="baseFrequency" dur="33s" values="0.05;0.02" keyTimes="0; 1" repeatCount="indefinite"/></feTurbulence>
<feOffset dx="200" dy="100" /><feDisplacementMap in="SourceGraphic" scale="20" />
</filter>
</svg>
@import url('https://fonts.cdnfonts.com/css/digital-7-mono');
*{ box-sizing: border-box; font-smoothing: antialiased; text-rendering: optimizeLegibility; scroll-behavior: smooth;}
html, body { height: 100%; overflow: hidden;}
html {
filter: grayscale(1) brightness(0.5) contrast(4) brightness(1.6);
}
body {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
align-items: center;
margin: 0;
--clr-d: #c2d1e3; /* midday */
--clr-n: #35373a; /* midnight */
--clr: var(--clr-d);
--clr-dark: lch(from var(--clr) calc(l - 16) c h);
background: var(--clr);
background: linear-gradient(225deg, var(--clr), var(--clr-dark));
font-size: calc(var(--_size) * 0.02);
--_factor: min(600px, 100vh);
--_size: min(var(--_factor), 100vw);
--rotate-hour: 0;
--pecentage-of-day: 0;
}
svg {
height: 0; width: 0;
overflow: hidden;
max-width: 0px;
max-height: 0;
}
.nueclock-wrap {
width: 50em; height: 50em;
border-radius: 50%;
position: relative;
--fox: calc( sin( ( var(--rotate-hour) + 135 ) * 1deg ) );
--foy: calc( sin( ( var(--rotate-hour) + 45 )* 1deg ) );
--sox: 1; --soy: 1;
rotate: 90deg;
}
#timeContainer {
font-family: 'Digital-7 Mono', sans-serif;
font-size: 4.2em;
font-weight: 1000;
filter: blur(3px);
opacity: 0.3;
transition: opacity 0s;
text-align: center;
position: absolute;
color: #fff;
top: 32%;
transition: all 0.2s ease-in-out;
}
body:has( .hour.dragging ) #timeContainer {
opacity: 0;
}
.scene * { pointer-events: none; }
.scene:hover #timeContainer {
opacity: 0.6;
filter: blur(1px);
}
.nueclock-wrap * { transition: transform 0.2s ease-out; }
.nueclock-wrap > * { position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto; }
.hour {
width: 90%;
height: 3%;
transform-origin: 50% 50%;
clip-path: polygon(-10% -400%, 50% -400%, 50% 400%, -10% 400%);
transform: rotate(calc( 1deg * var(--rotate-hour)));
filter: grayscale(0.2) contrast(1.6);
--sox: 0.5; --soy: 0.5;
transition: width 0.2s ease-out;
}
.hour.hovered {
width: 88%;
}
.hour, .hour::before {
background: var(--clr-dark);
box-shadow:
calc(0.4em * var(--soy) * var(--foy)) calc(0.4em * var(--sox) * var(--fox)) 0.2em -0.2em #000,
calc(1em * var(--soy) * var(--foy)) calc(1em * var(--sox) * var(--fox)) 0.8em -0.2em #0005,
inset calc(-0.4em * var(--soy) * var(--foy)) calc(-1em * var(--sox) * var(--fox)) 1em -0.6em #232323,
inset calc(0.4em * var(--soy) * var(--foy)) calc(0.6em * var(--sox) * var(--fox)) 0.6em -0.5em #000a,
inset calc(0.8em * var(--soy) * var(--foy)) calc(2em * var(--sox) * var(--fox)) 1em -0.6em #eee,
inset calc(0.8em * var(--soy) * var(--foy)) calc(2em * var(--sox) * var(--fox)) 1em -0.1em #eee,
inset calc(-0.8em * var(--soy) * var(--foy)) calc(-2em * var(--sox) * var(--fox)) 2em -0.1em #232323;
}
.hour::before {
content: ''; display: block;
width: 11%;
height: 400%;
position: absolute;
bottom: -150%;
left: -2%;
border-radius: 1.2em;
--sox: 1;
--soy: 1;
cursor: grab;
}
.hour.dragging::before {
cursor: grabbing;
}
.hour::after {
content: ''; display: block;
width: 1.2%; height: 200%;
position: absolute;
left: 8.8%; top: -50%;
background: var(--clr-dark);
font-size: 0.6em;
box-shadow:
inset calc((2em * var(--foy)) + 1em) 0 1em -2em #000c,
inset calc(-0.4em * var(--soy) * var(--foy)) calc(-1em * var(--sox) * var(--fox)) 1em -0.6em #232323,
inset calc(0.4em * var(--soy) * var(--foy)) calc(0.6em * var(--sox) * var(--fox)) 0.6em -0.5em #000a,
inset calc(0.8em * var(--soy) * var(--foy)) calc(2em * var(--sox) * var(--fox)) 1em -0.6em #eee,
inset calc(0.8em * var(--soy) * var(--foy)) calc(2em * var(--sox) * var(--fox)) 1em -0.1em #eee,
inset calc(-0.8em * var(--soy) * var(--foy)) calc(-2em * var(--sox) * var(--fox)) 2em -0.1em #232323;
}
.shimmer {
position: absolute; left: 0; top: 0; z-index: 3;
transform: translate(0, 0); transition: transform 2s ease, opacity 2s ease, scale 2s ease;
animation: positionShimmer 1s linear infinite; animation-delay: calc((var(--rotate-hour) / 360) * -1s); animation-play-state: paused;
opacity: 0.8;
pointer-events: none;
}
@keyframes positionShimmer {
0% { opacity: 1; transform: translate(-4.2em, -1.6em); /* top right corner */ }
12.5% { opacity: 1; transform: translate(-4.8em, 0.5em); /* top middle */ }
25% { opacity: 1; transform: translate(-4.2em, 3.6em); /* top left corner */ }
37.5% { opacity: 1; transform: translate(-2.2em, 3.7em); /* left middle */ }
50% { opacity: 0.6; transform: translate(-0.4em, 3.3em); /* bottom left corner */ }
62.5% { opacity: 0.2; transform: translate(-0.2em, 0.8em); /* bottom middle */ }
75% { opacity: 0.6; transform: translate(-0.4em, -1.6em); /* bottom right corner */ }
87.5% { opacity: 1; transform: translate(-2.2em, -2em); /* right middle */ }
100% { opacity: 1; transform: translate(-4.2em, -1.6em); /* back to top right corner */ }
}
.shimmer > div, .shimmer > div::before {
--shimmer-size: 4em;
position:absolute; left:0; right: 0; top: 0; bottom: 0; margin: auto; z-index: 100;
width: var(--shimmer-size); height: var(--shimmer-size);
}
.shimmer > div {
--ani-speed: 12s; aspect-ratio: 1;
width: calc( 2 * var(--shimmer-size));
animation: flicker-spin var(--ani-speed) linear infinite;
}
.shimmer > div + div { animation-delay: calc( -1 * var(--ani-speed) / 3); }
.shimmer > div + div + div { animation-delay: calc( -2 * var(--ani-speed) / 3); }
.shimmer > div::before {
content:''; display: block; width: 1em; height: 1em;
background: #fff; filter: blur(4px);
animation: flicker-spin calc(var(--ani-speed)/2) linear reverse infinite;
}
@keyframes flicker-spin {
0% { border-image: radial-gradient(#fff 69%,#0000 70%) 2%/45%; rotate:0deg; }
50% { border-image: radial-gradient(#fff 69%,#0000 70%) 0%/42%; }
100% { border-image: radial-gradient(#fff 69%,#0000 70%) 2%/45%; rotate:360deg; }
}
.outer-ring {
width: 63%; height: 63%;
border-radius: 100%;
box-shadow:
-0.4em -0.4em 0.8em -0.8em #fff,
1.4em 1.4em 1.4em 0.2em #0005,
0.2em 0.2em 0.3em -0.1em #0005,
inset 1.2em 1.2em 0.8em -1.2em #fff,
inset -0.6em -0.6em 0.8em -0.2em #0005,
inset 0em 0em 1em -0.2em #000a;
background: #fff1;
}
.inner-outer-ring {
width: 51%; height: 51%;
border-radius: 100%;
box-shadow:
-0.1em -0.1em 0.2em -0.1em #000,
inset -0.1em -0.1em 0.4em -0.1em #fff,
inset 1em 1em 4em -1em #000;
}
.mid-ring {
width: 46%; height: 46%;
border-radius: 100%;
background: var(--clr);
box-shadow:
1em 1em 1.2em -0.6em #fff5,
-0.3em -0.3em 0.4em -0.6em #0005,
-0.2em -0.2em 1em 0em #0004,
inset -0.3em -0.3em 0.6em -0.2em #fff3,
inset -1.2em -1.2em 1.2em -1.4em #fff3,
inset 0.1em 0.1em 0.2em -0.1em #0003,
inset 1em 1em 2em 0em #0007;
}
.mid-ring::before {
content: ''; display: block;
position: absolute;
width: 100%; height: 100%;
border-radius: 100%;
background: repeating-conic-gradient(
var(--clr) 0%,
var(--clr) calc((100%)*( 1 / 12)),
#0001 calc((100%)*( 1 / 12)),
#0001 calc((100%)*( 2 / 12))
);
mix-blend-mode: multiply;
opacity: 0.5;
}
.outer-inner-ring {
background: var(--clr);
width: 36%; height: 36%;
border-radius: 100%;
box-shadow:
-1em -1em 3em -1em #fff3,
1em 1em 3em -1em #000a,
0.2em 0.2em 0.3em -0.1em #0001,
0.2em 0.2em 2em -1em #000,
inset 0.4em 0.4em 1em -0.2em #fffa,
inset 1em 1em 1.6em -0.5em #fff2,
inset 0em 0em 1em 0.6em #0005
;
}
.inner-inner-ring {
background: var(--clr);
width: 24%; height: 24%;
border-radius: 100%;
box-shadow:
inset 0em 0em 0.6em -0.1em #fff4,
inset -2em -2em 2em -2em #fff2,
inset 2em 2em 2em -2em #0002,
-0.1em -0.1em 1em 0em #fffa,
-1em -1em 3em 1em #fff4,
0.1em 0.1em 1em 0em #000a,
1em 1em 3em 1em #0004;
}
.minihud, .minhud * {
position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto;
}
.minihud {
width: 12em; height: 12em;
border-radius: 100%;
}
.minihud{
background: linear-gradient(-45deg, #111 0%, #444 100%);
filter: blur(0.1px);
box-shadow: inset 1em 1em 3em 0em #0a0a0a;
}
.minihud *:not(.metal-ring) {
transition: opacity 3s ease-in-out;
}
.metal-ring {
width: 100%; height: 100%;
border-radius: 100%;
box-shadow:
-0.2em -0.2em 0.3em 0em #fff7,
0.1em 0.1em 0.3em 0em #000a,
0em 0em 0em 0.04em #2c2c2c,
inset 0em 0em 0.1em 0.02em #0007,
inset 0.1em 0.1em 0.1em 0em #fffc,
inset -0.1em -0.1em 0.1em 0em #0005,
inset 0 0 0.1em 0.3em #777,
inset 0.2em 0.2em 0.4em 0.2em #0005,
inset -0.2em -0.2em 0.1em 0.1em #fffa,
inset 0 0 0 0.4em #777;
rotate: 90deg;
filter: contrast(1.4) blur(0.1px);
}
.minihud .scene {
width: 94%; height: 94%;
border-radius: 10em;
overflow: hidden;
}
.minihud .scene,
.minihud .scene *{
position: absolute; margin: auto;
top: 0; bottom: 0; left: 0; right: 0;
}
.minihud .scene .sky {
width: 100%;
height: 100%;
bottom: unset;
transition: --clr1 1s, --clr2 1s, --clr3 1s, --clr4 1s;
background: linear-gradient(170deg, var(--clr1), var(--clr2), var(--clr3), var(--clr4));
animation: daynight 1s linear infinite alternate;
animation-play-state: paused;
animation-delay: calc(( var(--percentage-of-day) ) * -1s);
}
@property --clr1 { syntax: '<color>'; inherits: false; initial-value: #fff; }
@property --clr2 { syntax: '<color>'; inherits: false; initial-value: #fff; }
@property --clr3 { syntax: '<color>'; inherits: false; initial-value: #fff; }
@property --clr4 { syntax: '<color>'; inherits: false; initial-value: #fff; }
@keyframes daynight {
0% { --clr1:#061420; --clr2:#18354e; --clr3:#41698b; --clr4:#73add0; }
15% { --clr1:#061420; --clr2:#18354e; --clr3:#41698b; --clr4:#73add0; }
30% { --clr1:#8f5a6c; --clr2:#d58078; --clr3:#fbe280; --clr4:#fdfdc6; }
50% { --clr1:#0180b9; --clr2:#3399c9; --clr3:#8ce2de; --clr4:#e2f9f8; }
65% { --clr1:#0180b9; --clr2:#3399c9; --clr3:#8ce2de; --clr4:#e2f9f8; }
80% { --clr1:#8f5a6c; --clr2:#d58078; --clr3:#fbe280; --clr4:#fdfdc6; }
90% { --clr1:#061420; --clr2:#18354e; --clr3:#41698b; --clr4:#73add0; }
100% { --clr1:#061420; --clr2:#18354e; --clr3:#41698b; --clr4:#73add0; }
}
.minihud .scene .clouds {
background: #aaa;
width: 100%;
min-width: 150px;
min-height: 24px;
height: 28%;
top: unset;
z-index: 3;
border: 1px solid #fff;
padding: 2%;
rotate: 0deg;
scale: 2.4;
translate: 0 40%;
filter: url(#cloud1) blur(1.2px);
filter: url(#cloud1) blur(1.2px);
animation: clouds 20s linear infinite;
}
.minihud .scene .clouds::before {
content: ""; display: block;
position: absolute;
width: 100%; height: 64%;
margin: 0;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
border: 0.1em solid #fff;
box-shadow: 0 0 3em #fff;
filter: url(#cloud1) blur(2px);
filter: url(#cloud1) blur(2px);
z-index: -2;
}
@keyframes clouds {
0% { opacity: 0;}
5% { opacity: 1;}
95% { opacity: 1;}
100% { opacity: 0;}
}
.minihud .scene .clouds.sec {
height: 24%;
filter: url(#cloud2) blur(1.2px);
filter: url(#cloud2) blur(1.2px);
animation: clouds 33s linear infinite;
}
.minihud .scene .clouds.sec::before {
filter: url(#cloud2) blur(2px);
filter: url(#cloud2) blur(2px);
}
document.addEventListener('DOMContentLoaded', function() {
document.documentElement.style.transition = 'filter 3s ease-out';
document.documentElement.style.filter = 'grayscale(0) brightness(1) contrast(1) brightness(1)';
});
function getTime() {
const now = new Date();
const hours = now.getHours();
const minutes = now.getMinutes();
const seconds = now.getSeconds();
const hours12 = hours % 12;
return { hours, hours12, minutes, seconds };
}
function getClockRotation() {
const { hours, minutes } = getTime();
const thr = hours + ( minutes / 60 );
const totalRotation = 720 * thr /24;
return totalRotation;
}
function getPercentageOfDay() {
const pod = getClockRotation() / 720;
return pod.toFixed(2);
}
document.body.style.setProperty('--rotate-hour', getClockRotation()+90 );
document.body.style.setProperty('--pecentage-of-day', getPercentageOfDay());
document.body.querySelector('.minihud .scene .sky').style.animationDelay = `calc(${ getPercentageOfDay()} * -1s)`;
function showCurrentTime() {
const { hours12, minutes } = getTime();
let disHour = hours12
const timeContainer = document.getElementById('timeContainer');
if (disHour == 0 ){ disHour = 12; }
timeContainer.textContent = `${String(disHour)}:${String(minutes).padStart(2, '0')}`;
updateBgColor(getPercentageOfDay());
document.body.style.setProperty('--rotate-hour', getClockRotation() );
}
showCurrentTime();
setTimeout(function() {
showCurrentTime();
setInterval(showCurrentTime, 1000 * 60);
}, (60 - getTime().seconds) * 1000);
function smoothCurve(val) {
return (1 - Math.cos(2 * Math.PI * val + Math.PI)) / 2;
}
function updateBgColor(percentage) {
percentage = smoothCurve(percentage);
const dayColor = getComputedStyle(document.querySelector('body')).getPropertyValue('--clr-d').trim().slice(1).match(/.{2}/g).map(hex => parseInt(hex, 16));
const nightColor = getComputedStyle(document.querySelector('body')).getPropertyValue('--clr-n').trim().slice(1).match(/.{2}/g).map(hex => parseInt(hex, 16));
const currentColor = dayColor.map((start, index) => {
const end = nightColor[index];
return Math.round(start + percentage * (end - start));
});
const currentColorHex = `#${currentColor.map(c => c.toString(16).padStart(2, '0')).join('')}`;
document.querySelector('body').style.setProperty('--clr', currentColorHex);
}
updateBgColor(getPercentageOfDay());
document.querySelectorAll('.hour').forEach(hour => {
let isDragging = false;
let lastAngle = null;
let cumulativeRotation = 0;
let initialRotation = 0;
hour.addEventListener('mouseenter', () => {
hour.classList.add('hovered');
});
hour.addEventListener('mouseleave', () => {
hour.classList.remove('hovered');
});
hour.addEventListener('mousedown', (e) => {
isDragging = true;
hour.classList.add('dragging');
e.preventDefault();
const centerX = window.innerWidth / 2;
const centerY = window.innerHeight / 2;
const deltaX = e.clientX - centerX;
const deltaY = e.clientY - centerY;
const angleInRadians = Math.atan2(deltaY, deltaX);
let angleInDegrees = (angleInRadians * (180 / Math.PI)) + 180;
initialRotation = parseFloat(getComputedStyle(document.body).getPropertyValue('--rotate-hour').replace('deg', ''));
lastAngle = angleInDegrees;
cumulativeRotation = initialRotation;
});
window.addEventListener('mousemove', (e) => {
if (isDragging) {
const centerX = window.innerWidth / 2;
const centerY = window.innerHeight / 2;
const deltaX = e.clientX - centerX;
const deltaY = e.clientY - centerY;
const angleInRadians = Math.atan2(deltaY, deltaX);
let angleInDegrees = (angleInRadians * (180 / Math.PI)) + 180;
if (lastAngle === null) {
lastAngle = angleInDegrees;
}
let angleDifference = angleInDegrees - lastAngle;
if (angleDifference > 180) {
angleDifference -= 360;
} else if (angleDifference < -180) {
angleDifference += 360;
}
cumulativeRotation += angleDifference;
if (cumulativeRotation < 0) {
cumulativeRotation += 720;
} else if (cumulativeRotation >= 720) {
cumulativeRotation -= 720;
}
lastAngle = angleInDegrees;
let percentage = (cumulativeRotation / 720).toFixed(3);
document.body.style.setProperty('--rotate-hour', cumulativeRotation.toFixed(2));
document.body.style.setProperty('--percentage-of-day', percentage);
updateBgColor(percentage);
document.body.querySelector('.minihud .scene .sky').style.animationDelay = `calc(${(cumulativeRotation / 720).toFixed(2)} * -1s)`;
}
});
window.addEventListener('mouseup', () => {
if (isDragging) {
setTimeout(function (){
isDragging = false;
}, 100);
hour.classList.remove('dragging');
const currentRotation = parseFloat(getComputedStyle(document.body).getPropertyValue('--rotate-hour').replace('deg', ''));
const degreeIncrement = (getClockRotation()) - currentRotation;
smoothRotateClock(degreeIncrement, 1000);
}
});
});
function smoothRotateClock(degreeIncrement, duration) {
const startRotation = parseFloat(getComputedStyle(document.body).getPropertyValue('--rotate-hour').replace('deg', ''));
const frameRate = 60;
const totalFrames = (duration / 1000) * frameRate;
let currentFrame = 0;
function rotate() {
currentFrame++;
const progress = currentFrame / totalFrames;
const currentRotation = startRotation + degreeIncrement * easeInOutCubic(progress);
document.body.style.setProperty('--rotate-hour', `${currentRotation}`);
updateBgColor(currentRotation/720);
document.body.querySelector('.minihud .scene .sky').style.animationDelay = `calc(${currentRotation/720} * -1s)`;
if (currentFrame < totalFrames) {
requestAnimationFrame(rotate);
}
}
rotate();
}
function easeInOutCubic(t) {
return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.