Skip to content

Instantly share code, notes, and snippets.

@ThomasR
Created August 5, 2017 13:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ThomasR/28e6d0bf7a073b35a495e2ada85b3e20 to your computer and use it in GitHub Desktop.
Save ThomasR/28e6d0bf7a073b35a495e2ada85b3e20 to your computer and use it in GitHub Desktop.
Copernicus Theorem visualized
html, body {
color: white;
background: #2581c4;
font-family: sans-serif;
}
body {
animation: fadeIn linear backwards .5s 1.5s;
}
svg {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
}
svg * {
fill: currentColor;
stroke: currentColor;
}
.background {
color: white;
cursor: pointer;
}
.debug svg .background {
stroke: #fcfcfc;
}
.diameter {
stroke-width: .3;
}
body:not(.debug) .diameter {
opacity: 0;
}
.dot {
stroke: none;
/* approximates a sine wave - cf. https://stackoverflow.com/a/45451334/5134084 */
animation: bounce 2s cubic-bezier(.3642124, 0, .6357876, 1) infinite alternate backwards;
}
.background, .diameter, .dot {
transition: all 1s linear;
}
.diameter, .dot {
pointer-events: none;
}
body:not(.debug) .dot {
color: #555;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes bounce {
from {
transform: translateY(-50px);
}
to {
transform: translateY(50px);
}
}
<!doctype html>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Copernicus' Theorem visualized</title>
<script src="copernicus.js" defer></script>
<link rel="stylesheet" href="copernicus.css">
</head>
Click circle to reveal hints
<svg viewBox="-54 -54 108 108">
<circle class="background" cx="0" cy="0" r="50"/>
</svg>
const dotCount = 8;
const dotRadius = 1.2;
const setAttributes = (el, attrs) => {
Object.keys(attrs).forEach(key => {
el.setAttribute(key, attrs[key]);
});
};
const createSVGElement = (name, attrs) => {
let el = document.createElementNS("http://www.w3.org/2000/svg", name);
if (attrs) {
setAttributes(el, attrs);
}
return el;
};
const svg = document.querySelector('svg');
const circle = document.querySelector('circle');
setAttributes(circle, {
'stroke-width': 2 * dotRadius
});
circle.addEventListener('click', () => {
document.body.classList.toggle('debug');
});
for (let i = 0; i < dotCount; i++) {
let group = createSVGElement('g',{
'color': `hsl(${i / dotCount * 360}, 75%, 45%)`
});
Object.assign(group.style, {
transform: `rotate(${i / dotCount / 2}turn)`
});
let diameter = createSVGElement('path', {
'class': 'diameter',
d: `M 0,-${50 - dotRadius} v ${2 * (50 - dotRadius)}`
});
group.appendChild(diameter);
let dot = createSVGElement('circle', {
'class': 'dot',
r: dotRadius,
cx: 0,
cy: 0
});
Object.assign(dot.style, {
animationDelay: `${i / dotCount * 2}s`
});
group.appendChild(dot);
svg.appendChild(group);
}
setTimeout(() => {
document.body.classList.add('loaded');
}, 1800);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment