console
let eyel, eyer, mouth;
let standardInterval;
let currentMood = 'dead';
const faceEl = document.querySelector('.face');
moods(currentMood);
function cycleChar(eid, charPairs) {
const element = document.getElementById(eid);
if (!element) return;
if (element.timeoutId) {
clearTimeout(element.timeoutId)
}
if (!element.generation) {
element.generation = 0
}
element.generation++;
const generation = element.generation;
let index = 0;
function updateChar() {
if (element.generation !== generation) return;
const [char, duration] = charPairs[index];
element.textContent = char;
index = (index + 1) % charPairs.length;
if (duration != 0) {
element.timeoutId = setTimeout(updateChar, duration * 1000)
} else { element.timeoutId = null }
} updateChar()
}
function clearCharCycles() {
['eyel', 'eyer', 'mouth']
.forEach((id) => {
const element = document.getElementById(id);
if (element && element.timeoutId) {
clearTimeout(element.timeoutId);
element.timeoutId = null
}
if (element && element.generation) { element.generation++ }
})
} function moods(mood) { clearCharCycles(); if (mood === 'dead') { eyel = [['x', 0]]; eyer = [['x', 0]]; mouth = [['-', 0]] } if (mood === 'awake') { eyel = [['.', 4], ['', 0.3], ['\u{2027}', 7], ['', 0.3],]; eyer = [['.', 4], ['', 0.3], ['\u{2027}', 7], ['', 0.3],]; mouth = [['.', 0]] } if (mood === 'happy') { eyel = [['.', 4], ['', 0.3], ['\u{2027}', 7], ['', 0.3],]; eyer = [['.', 4], ['', 0.3], ['\u{2027}', 7], ['', 0.3],]; mouth = [['\u{02d8}', 0]] } if (mood === 'excited') { eyel = [['O', 3], ['\u{002a}', 0.4], ['O', 1.6], ['>', 2],]; eyer = [['O', 5], ['<', 2],]; mouth = [['\u{02d8}', 5], ['\u{25bd}', 2],] } if (mood === 'concerned') { eyel = [['.', 4], ['', 0.3], ['\u{2027}', 7], ['', 0.3],]; eyer = [['.', 4], ['', 0.3], ['\u{2027}', 7], ['', 0.3],]; mouth = [['\u{00ba}', 0]] } if (mood === 'sleeping') { eyel = [['-', 4]]; eyer = [['-', 4]]; mouth = [['\u{2027}', 4], ['\u{00ba}', 1],]; faceEl.classList.add('sleeping') } else if (faceEl.classList.contains('sleeping')) { faceEl.classList.remove('sleeping') } cycleChar('eyel', eyel); cycleChar('eyer', eyer); cycleChar('mouth', mouth) } let power = 0; const maxPower = 100; const decayRate = 1; const increment = 2; const holdDuration = 16180; let isHolding = false; let isDropping = false; let lastPower = power; let accumulatedDrop = 0; const powerBtn = document.querySelector('.pwr-btn'); function updatePower() { if (!isHolding) { power = Math.max(0, power - decayRate); checkPowerDrop(); updatePowerHeight() } let newMood = currentMood; if (power === 0) { powerBtn.classList.add('empty'); powerBtn.classList.remove('full'); powerBtn.innerHTML = 'Generate' } else if (power >= 100) { powerBtn.innerHTML = '~ FULL ~'; powerBtn.classList.add('full'); powerBtn.classList.remove('empty') } else { powerBtn.classList.remove('full'); powerBtn.classList.remove('empty'); powerBtn.innerHTML = 'Generate' } if (power === 0) { newMood = 'dead' } else if (power > 0 && power < 20) { newMood = 'concerned' } else if (isDropping && power > 30 && power < 70) { newMood = 'sleeping' } else if (power >= 20 && power < 50) { newMood = 'awake' } else if (power >= 50 && power < 90) { newMood = 'happy' } else if (power >= 90 && power <= 100) { newMood = 'excited' } const moodList = ['dead', 'excited', 'awake', 'concerned', 'happy', 'sleeping',]; if (newMood !== currentMood) { currentMood = newMood; if (moodList.includes(newMood)) { moods(newMood) } else { clearCharCycles() } } } function checkPowerDrop() { if (power < lastPower) { accumulatedDrop += lastPower - power } else if (power > lastPower) { accumulatedDrop = 0 } if (accumulatedDrop >= 20) { isDropping = true } else { isDropping = false } lastPower = power } function increasePower() { accumulatedDrop = 0; if (!isHolding) { power = Math.min(maxPower, power + increment); if (power === maxPower && !isHolding) { startHold() } updatePowerHeight() } } function updatePowerHeight() { powerBtn.style.setProperty('--power', power) } function startHold() { isHolding = true; powerBtn.classList.add('full'); powerBtn.innerHTML = '~ FULL ~'; setTimeout(() => { isHolding = false }, holdDuration) } powerBtn.addEventListener('click', increasePower); standardInterval = setInterval(updatePower, 1000); updatePowerHeight(); const ct = document.querySelector('.face'); ct.addEventListener('mousemove', function (e) { const rect = ct.getBoundingClientRect(); const se = 42; const x = e.clientX - rect.left; const y = e.clientY - rect.top; const rotateX = (y / rect.height - 0.5) * -se; const rotateY = (x / rect.width - 0.5) * se; ct.style.transform = `rotateX(${rotateX}deg)rotateY(${rotateY}deg)`; ct.style.setProperty('--xv', rotateX); ct.style.setProperty('--yv', rotateY) }); ct.addEventListener('mouseleave', function () { ct.style.transform = 'rotateX(0deg) rotateY(0deg)'; ct.style.setProperty('--xv', 0); ct.style.setProperty('--yv', 0) });
<div class="power-line"></div><div class="face"><div id="eyel">x</div><div id="mouth">-</div><div id="eyer">x</div><div class="zzz"><span>Z</span><span>z</span><span>z</span></div></div><div class="pwr-btn empty">Generate</div>
* {
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
scroll-behavior: smooth;
}
html,
body {
height: 100%;
overflow: hidden;
}
body {
font-family: Departure Mono;
background: #1e1e1e;
background: linear-gradient(28deg, #111, #272727);
color: #fff;
position: relative;
height: 100%;
}
.face {
--xv: 0;
--yv: 0;
background: #141414;
background: #fff1;
background-image: radial-gradient(transparent 1px, #111 0);
background-size: 3px 3px;
font-weight: 1000;
position: absolute;
margin: auto;
left: 0;
right: 0;
top: 0;
bottom: 3em;
width: 3em;
height: 3em;
border-radius: 10px;
border: 1px solid #fff2;
display: flex;
justify-content: center;
align-items: center;
padding-top: 1em;
overflow: hidden;
user-select: none;
box-shadow: 0px 0px 0px 2px #0005, 0px 0px 0px 1px #fff3, -2px 2px 2px -1px #000, 0px 0px 12px 0px #fff0, inset -2px 2px 3px -2px #fffa;
cursor: pointer;
transition: all 0.4s ease-out;
backdrop-filter: blur(10px);
perspective: 1000px;
}
.face #eyel {
translate: 0 -1em;
}
.face #eyer {
translate: 0 -1em;
}
body:has(.pwr-btn:not(.empty)) .face {
box-shadow: 0px 0px 0px 2px #0005, 0px 0px 0px 1px #fff3, -2px 2px 2px -1px #000, 0px 0px 12px 0px #fff2, inset -2px 2px 3px -2px #fffa;
}
.face > * {
text-shadow: -3px 3px 3px #000c, 0 1px 12px #fffa, 0 0 5px #fff;
}
body:has(.pwr-btn:not(.empty)) .face:hover > * {
transform: translateX(calc(var(--yv) * 0.2px)) translateY(calc(var(--xv) * -0.2px));
transition: all 0.4s ease-out;
}
body:has(.pwr-btn.empty) .face > * {
opacity: 0.2;
}
.face::before {
content: '';
display: block;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
box-shadow: inset -2px 2px 2px 0px #fff5, inset 2px -2px 2px 1px #1118;
scale: 1.1;
border-radius: 12px;
transform: translateX(calc(var(--yv) * 0.2px)) translateY(calc(var(--xv) * -0.2px));
transition: all 0.4s ease-out;
}
.face::after {
content: '';
display: block;
width: 200%;
height: 0.6em;
background: #fff2;
position: absolute;
rotate: 24deg;
top: -50%;
transition: all 0.4s ease-in-out;
}
.face:hover {
scale: 2;
box-shadow: -24px 33px 8px -10px #0005, 0px 0px 0px 1px #fff3, -2px 2px 2px -1px #000, 0px 0px 12px 0px #fff0, inset -2px 2px 3px -2px #fffc !important;
}
.face:hover::after {
top: 150%;
rotate: 42deg;
}
.pwr-btn {
position: absolute;
left: 0;
right: 0;
top: 2em;
bottom: 0;
margin: auto;
translate: 0 min(10em, 30vh);
background: #141414;
background: #5478ad85;
background-image: radial-gradient(transparent 1px, #111 0);
background-size: 3px 3px;
width: fit-content;
height: fit-content;
padding: 0.4em 1.6em;
border: 1px solid #fff4;
border-radius: 6px;
cursor: pointer;
box-shadow: 0px 0px 0px 2px #0005, 0px 0px 0px 1px #fff3, 0px 0px 0px 1px #fff3, -2px 2px 2px -1px #000, 0px 0px 12px 0px #fff2, inset -2px 2px 3px -2px #fffa;
text-shadow: 0 1px 12px #fffa, 0 0 5px #fff;
user-select: none;
transition: all 0.4s ease-in-out;
}
.pwr-btn::before {
content: '';
display: block;
position: absolute;
left: 0;
bottom: 0;
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
background: #fff;
mix-blend-mode: difference;
filter: blur(1px);
height: calc(var(--power, 0) * 1%);
width: 100%;
transition: all 0.4s ease-in-out;
}
.pwr-btn.full::before {
border-radius: 6px;
}
.pwr-btn.full {
filter: brightness(1.2);
box-shadow: 0px 0px 0px 2px #0005, 0px 0px 6px 1px #fff3, 0px 0px 12px 1px #fff3, -2px 2px 2px -1px #000, 0px 0px 12px 0px #fff2, inset -2px 2px 3px -2px #fffa;
}
.pwr-btn.empty {
filter: brightness(0.5);
}
.power-line {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
translate: 0 calc(min(10em, 30vh) / 2);
width: 1.6px;
height: min(10em, 30vh);
transition: all 0.4s ease-in-out;
background: repeating-linear-gradient( transparent, transparent 4px, #fff1 4px, #fff1 8px);
filter: drop-shadow(0 0 2px #fff);
overflow: hidden;
}
.power-line::before {
content: '';
display: block;
position: absolute;
bottom: 0;
width: 100%;
height: 40%;
background: linear-gradient(transparent 0%, #fff 50%, transparent 100%);
animation: generation 1.618s ease-out infinite;
opacity: 0;
}
@keyframes generation {
0% {
translate: 0 100%;
}
100% {
translate: 0 calc(-1 * min(10em, 30vh));
}
}
.power-line::after {
content: '';
display: block;
position: absolute;
bottom: 0;
left: -2.5em;
width: 5em;
height: 100%;
box-shadow: inset 0 0 2em 1em #fff6;
opacity: 0;
}
body:has(.pwr-btn:not(.empty)) .power-line::before,
body:has(.pwr-btn:not(.empty)) .power-line::after {
opacity: 0.6;
transition: all 1.618s ease-in-out;
}
body:has(.pwr-btn:not(.empty)) .power-line {
background: repeating-linear-gradient( transparent, transparent 4px, #fff4 4px, #fff4 8px);
}
.face .zzz {
display: none;
}
.face.sleeping .zzz {
display: block;
color: #fff;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: 100%;
height: 100%;
}
.face .zzz span {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
position: absolute;
left: 20%;
right: 0;
top: 20%;
bottom: 0;
scale: 0;
font-size: 1em;
animation: zzzs 1.5s linear infinite;
}
.face .zzz span:nth-child(2) {
animation-delay: 0.5s;
}
.face .zzz span:nth-child(3) {
animation-delay: 1s;
}
@keyframes zzzs {
0% {
scale: 0;
translate: 0;
rotate: 0;
}
100% {
scale: 1;
translate: 1em -2em;
rotate: -45deg;
}
}