Skip to content

Instantly share code, notes, and snippets.

@daveknights
Created December 3, 2023 15:17
Show Gist options
  • Save daveknights/3aeda77ae8201e779a81416671c2eed6 to your computer and use it in GitHub Desktop.
Save daveknights/3aeda77ae8201e779a81416671c2eed6 to your computer and use it in GitHub Desktop.
Representing the time using the first chemical element atomic numbers
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chemical Element Clock</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header>
<h1>Chemical element clock</h1>
</header>
<main>
<div class="elements">
<div class="hours element">
<span class="atomic-number"></span>
<span class="h symbol"></span>
<span class="name"></span>
<span class="group"></span>
</div>
<div class="minutes element">
<span class="atomic-number"></span>
<span class="m symbol"></span>
<span class="name"></span>
<span class="group"></span>
</div>
<div class="seconds element">
<span class="atomic-number"></span>
<span class="s symbol"></span>
<span class="name"></span>
<span class="group"></span>
</div>
<span class="date"></span>
</div>
<form class="options">
<label class="option" for="show-number">
<input type="checkbox" id="show-number">
Atomic number
</label>
<label class="option" for="show-group">
<input type="checkbox" id="show-group">
Chemical group
</label>
<label class="option" for="show-date">
<input type="checkbox" id="show-date">
Border colour
</label>
</form>
</main>
<script src="script.js" type="module"></script>
</body>
</html>
import elements from "./the-element-data.js";
let hours, minutes, seconds, date;
let oneSecond = 0;
let lastTime = 0;
const selector = (parent, className) => parent.querySelector(`.${className}`);
const setOption = e => {
switch (e.target.id) {
case 'show-number':
for (const aN of document.querySelectorAll('.atomic-number')) {
window.getComputedStyle(aN).getPropertyValue('opacity') === '0' ? aN.style.opacity = '1' : aN.style.opacity = '0';
}
break;
case 'show-group':
for (const g of document.querySelectorAll('.group')) {
window.getComputedStyle(g).getPropertyValue('opacity') === '0' ? g.style.opacity = '1' : g.style.opacity = '0';
}
break;
case 'show-date':
window.getComputedStyle(date).getPropertyValue('display') === 'none' ? date.style.display = 'block' : date.style.display = 'none';
break;
}
};
const updateTime = time => {
const now = new Date();
oneSecond += time - lastTime;
if (oneSecond > 1000) {
hours.classList = `hours element ${elements[now.getHours()].group}`;
selector(hours, 'h').textContent = elements[now.getHours()].symbol;
selector(hours, 'atomic-number').textContent = now.getHours();
selector(hours, 'group').textContent = elements[now.getHours()].group;
selector(hours, 'name').textContent = elements[now.getHours()].name;
minutes.classList = `minutes element ${elements[now.getMinutes()].group}`;
selector(minutes, 'm').textContent = elements[now.getMinutes()].symbol;
selector(minutes, 'atomic-number').textContent = now.getMinutes();
selector(minutes, 'group').textContent = elements[now.getMinutes()].group;
selector(minutes, 'name').textContent = elements[now.getMinutes()].name;
seconds.classList = `seconds element ${elements[now.getSeconds()].group}`;
selector(seconds, 's').textContent = elements[now.getSeconds()].symbol;
selector(seconds, 'atomic-number').textContent = now.getSeconds();
selector(seconds, 'group').textContent = elements[now.getSeconds()].group;
selector(seconds, 'name').textContent = elements[now.getSeconds()].name;
oneSecond = 0;
}
lastTime = time;
requestAnimationFrame(updateTime);
};
const init = () => {
const today = new Date();
const dateValue = ('0' + today.getDate()).slice(-2) + ('0' + (today.getMonth() + 1)).slice(-2) + today.getFullYear().toString().slice(-2);
hours = selector(document, 'hours');
minutes = selector(document, 'minutes');
seconds = selector(document, 'seconds');
date = selector(document, 'date');
selector(document, 'options').addEventListener('change', setOption);
document.querySelector(':root').style.setProperty('--date-colour', `#${dateValue}`);
date.textContent = `Hex colour: #${dateValue}`;
requestAnimationFrame(updateTime);
};
window.addEventListener('load', init);
:root {
--date-colour: #011223;
}
* {
box-sizing: border-box;
font-family: Arial, Helvetica, sans-serif;
}
h1 {
text-align: center;
}
.non-metal { background: #feffd0; }
.noble-gas { background: #ffe7cd; }
.alkali-metal { background: #ffcbcd; }
.alkaline-earth-metal { background: #d2d3ff; }
.metalloid { background: #e4f0c9; }
.post-transition-metal { background: #c6ffc7; }
.transition-metal { background: #c5e1ff; }
.lanthanide { background: #bcfffe; }
.elements {
border: solid 30px;
border-color: var(--date-colour);
border-radius: 4px 4px 0 0;
display: flex;
gap: 10px;
margin: auto;
padding: 10px;
position: relative;
width: fit-content;
}
.date {
bottom: -23px;
color: white;
display: none;
font-size: 0.875rem;
letter-spacing: 1px;
position: absolute;
right: 0;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
}
.element {
align-items: center;
border: solid 1px grey;
border-radius: 2px;
display: flex;
flex-direction: column;
height: 200px;
justify-content: center;
padding: 5px;
width: 200px;
}
.atomic-number {
font-size: 2rem;
opacity: 0;
}
.symbol {
font-size: 4rem;
margin-top: auto;
}
.name {
font-size: 1rem;
}
.group {
font-size: 0.875rem;
margin-top: auto;
opacity: 0;
}
form {
background: #eee;
border-radius: 0 0 4px 4px;
display: flex;
justify-content: space-between;
margin: 0 auto;
padding: 20px 40px;
width: 700px;
}
.option {
background: #ccc;
border-radius: 4px;
box-shadow: 0 2px 0 2px #888;
cursor: pointer;
height: 36px;
line-height: 36px;
position: relative;
text-align: center;
width: 190px;
}
.option input {
display: none;
}
.option:has(input:checked) {
background: #5eeda6;
background: var(--date-colour);
box-shadow: none;
color: #d2d3ff;
}
const elements = {
'0': { symbol: 'Nu', name: 'Neutronium', goup: '' },
'1': { symbol: 'H', name: 'Hydrogen', group: 'non-metal' },
'2': { symbol: 'He', name: 'Helium', group: 'noble-gas' },
'3': { symbol: 'Li', name: 'Lithium', group: 'alkali-metal' },
'4': { symbol: 'Be', name: 'Beryllium', group: 'alkaline-earth-metal' },
'5': { symbol: 'B', name: 'Boron', group: 'metalloid' },
'6': { symbol: 'C', name: 'Carbon', group: 'non-metal' },
'7': { symbol: 'N', name: 'Nitrogen', group: 'non-metal' },
'8': { symbol: 'O', name: 'Oxygen', group: 'non-metal' },
'9': { symbol: 'F', name: 'Fluorine', group: 'non-metal' },
'10': { symbol: 'Ne', name: 'Neon', group: 'noble-gas' },
'11': { symbol: 'Na', name: 'Sodium', group: 'alkali-metal' },
'12': { symbol: 'Mg', name: 'Magnesium', group: 'alkaline-earth-metal' },
'13': { symbol: 'Al', name: 'Aluminum', group: 'post-transition-metal' },
'14': { symbol: 'Si', name: 'Silicon', group: 'metalloid' },
'15': { symbol: 'P', name: 'Phosphorus', group: 'non-metal' },
'16': { symbol: 'S', name: 'Sulfur', group: 'non-metal' },
'17': { symbol: 'Cl', name: 'Chlorine', group: 'non-metal' },
'18': { symbol: 'Ar', name: 'Argon', group: 'noble-gas' },
'19': { symbol: 'K', name: 'Potassium', group: 'alkali-metal' },
'20': { symbol: 'Ca', name: 'Calcium', group: 'alkaline-earth-metal' },
'21': { symbol: 'Sc', name: 'Scandium', group: 'transition-metal' },
'22': { symbol: 'Ti', name: 'Titanium', group: 'transition-metal' },
'23': { symbol: 'V', name: 'Vanadium', group: 'transition-metal' },
'24': { symbol: 'Cr', name: 'Chromium', group: 'transition-metal' },
'25': { symbol: 'Mn', name: 'Manganese', group: 'transition-metal' },
'26': { symbol: 'Fe', name: 'Iron', group: 'transition-metal' },
'27': { symbol: 'Co', name: 'Cobalt', group: 'transition-metal' },
'28': { symbol: 'Ni', name: 'Nickel', group: 'transition-metal' },
'29': { symbol: 'Cu', name: 'Copper', group: 'transition-metal' },
'30': { symbol: 'Zn', name: 'Zinc', group: 'transition-metal' },
'31': { symbol: 'Ga', name: 'Gallium', group: 'post-transition-metal' },
'32': { symbol: 'Ge', name: 'Germanium', group: 'metalloid' },
'33': { symbol: 'As', name: 'Arsenic', group: 'metalloid' },
'34': { symbol: 'Se', name: 'Selenium', group: 'non-metal' },
'35': { symbol: 'Br', name: 'Bromine', group: 'non-metal' },
'36': { symbol: 'Kr', name: 'Krypton', group: 'noble-gas' },
'37': { symbol: 'Rb', name: 'Rubidium', group: 'alkali-metal' },
'38': { symbol: 'Sr', name: 'Strontium', group: 'alkaline-earth-metal' },
'39': { symbol: 'Y', name: 'Yttrium', group: 'transition-metal' },
'40': { symbol: 'Zr', name: 'Zirconium', group: 'transition-metal' },
'41': { symbol: 'Nb', name: 'Niobium', group: 'transition-metal' },
'42': { symbol: 'Mo', name: 'Molybdenum', group: 'transition-metal' },
'43': { symbol: 'Tc', name: 'Technetium', group: 'transition-metal' },
'44': { symbol: 'Ru', name: 'Ruthenium', group: 'transition-metal' },
'45': { symbol: 'Rh', name: 'Rhodium', group: 'transition-metal' },
'46': { symbol: 'Pd', name: 'Palladium', group: 'transition-metal' },
'47': { symbol: 'Ag', name: 'Silver', group: 'transition-metal' },
'48': { symbol: 'Cd', name: 'Cadmium', group: 'transition-metal' },
'49': { symbol: 'In', name: 'Indium', group: 'post-transition-metal' },
'50': { symbol: 'Sn', name: 'Tin', group: 'post-transition-metal' },
'51': { symbol: 'Sb', name: 'Antimony', group: 'metalloid' },
'52': { symbol: 'Te', name: 'Tellurium', group: 'metalloid' },
'53': { symbol: 'I', name: 'Iodine', group: 'non-metal' },
'54': { symbol: 'Xe', name: 'Xenon', group: 'noble-gas' },
'55': { symbol: 'Cs', name: 'Cesium', group: 'alkali-metal' },
'56': { symbol: 'Ba', name: 'Barium', group: 'alkaline-earth-metal' },
'57': { symbol: 'La', name: 'Lanthanum', group: 'lanthanide' },
'58': { symbol: 'Ce', name: 'Cerium', group: 'lanthanide' },
'59': { symbol: 'Pr', name: 'Praseodymium', group: 'lanthanide' },
}
export default elements;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment