Files
sune-logo/index.html

145 lines
4.9 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sune ✺</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
:root {
--sune-primary: #ffffff;
--sune-bg: #000000;
}
body {
background-color: var(--sune-bg);
color: var(--sune-primary);
transition: background-color 0.3s ease, color 0.3s ease;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
font-family: ui-sans-serif, system-ui, sans-serif;
}
.inverted {
--sune-primary: #000000;
--sune-bg: #ffffff;
}
@keyframes sune-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@keyframes sune-pulse {
0%, 100% { transform: scale(1); opacity: 1; }
50% { transform: scale(0.75); opacity: 0.4; }
}
.sune-main-group {
transform-origin: center;
animation: sune-spin 16s linear infinite;
}
.is-generating .sune-main-group {
animation: sune-spin 3s linear infinite;
}
.sune-spike {
transform-origin: center;
fill: currentColor;
}
.is-generating .sune-spike {
animation: sune-pulse 1.5s ease-in-out infinite;
}
/* Staggered delays for 16 spikes */
.sune-spike:nth-child(1) { animation-delay: 0.00s; }
.sune-spike:nth-child(2) { animation-delay: 0.09s; }
.sune-spike:nth-child(3) { animation-delay: 0.18s; }
.sune-spike:nth-child(4) { animation-delay: 0.27s; }
.sune-spike:nth-child(5) { animation-delay: 0.36s; }
.sune-spike:nth-child(6) { animation-delay: 0.45s; }
.sune-spike:nth-child(7) { animation-delay: 0.54s; }
.sune-spike:nth-child(8) { animation-delay: 0.63s; }
.sune-spike:nth-child(9) { animation-delay: 0.72s; }
.sune-spike:nth-child(10) { animation-delay: 0.81s; }
.sune-spike:nth-child(11) { animation-delay: 0.90s; }
.sune-spike:nth-child(12) { animation-delay: 0.99s; }
.sune-spike:nth-child(13) { animation-delay: 1.08s; }
.sune-spike:nth-child(14) { animation-delay: 1.17s; }
.sune-spike:nth-child(15) { animation-delay: 1.26s; }
.sune-spike:nth-child(16) { animation-delay: 1.35s; }
.logo-wrapper {
width: 64px;
height: 64px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.2s ease;
}
.logo-wrapper:active {
transform: scale(0.85);
}
</style>
</head>
<body onclick="toggleState()">
<div id="logoWrapper" class="logo-wrapper">
<svg width="64" height="64" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<g class="sune-main-group" id="spikeGroup"></g>
</svg>
</div>
<div class="fixed bottom-6 flex gap-4">
<button onclick="event.stopPropagation(); toggleInvert()" class="text-[10px] uppercase tracking-tighter opacity-40 hover:opacity-100 transition">Invert</button>
</div>
<script>
const spikeGroup = document.getElementById('spikeGroup');
const points = 16;
const outerRadius = 48;
const innerRadius = 18; // Increased for legibility at tiny scales
const centerX = 50;
const centerY = 50;
function generateSune() {
let html = '';
for (let i = 0; i < points; i++) {
const angle = (i * 2 * Math.PI) / points;
const nextAngle = ((i + 1) * 2 * Math.PI) / points;
const midAngle = angle + (Math.PI / points);
const x1 = centerX + innerRadius * Math.cos(angle);
const y1 = centerY + innerRadius * Math.sin(angle);
const xPeak = centerX + outerRadius * Math.cos(midAngle);
const yPeak = centerY + outerRadius * Math.sin(midAngle);
const x2 = centerX + innerRadius * Math.cos(nextAngle);
const y2 = centerY + innerRadius * Math.sin(nextAngle);
html += `<path class="sune-spike" d="M ${centerX} ${centerY} L ${x1} ${y1} L ${xPeak} ${yPeak} L ${x2} ${y2} Z" />`;
}
spikeGroup.innerHTML = html;
}
function toggleInvert() {
document.body.classList.toggle('inverted');
}
function toggleState() {
const wrapper = document.getElementById('logoWrapper');
const isGen = wrapper.classList.toggle('is-generating');
if ('vibrate' in navigator) navigator.vibrate(10);
}
generateSune();
</script>
</body>
</html>