SH‑1 Molecule — Cosmetic Morphology (Animated)
Legend
Core carbons (graphite)
Hydration fins (ice blue)
Anchor α — Coconut tether (amber)
Anchor β — Botanical plume (green)
Anchor γ — Caffeine emblem (slate)
Controls
Declaration: SH‑1 is a cosmetic morphology for branding, visualization, and mythic serialization. It is non‑biological and non‑hormonal.
}
ctx.closePath();
ctx.strokeStyle = color;
ctx.lineWidth = 2;
ctx.stroke();
}
function drawPulseNode(x, y, label, color, t) {
const r = 10 + 3 * Math.sin(t);
ctx.beginPath();
ctx.arc(x, y, r, 0, 2 * Math.PI);
ctx.fillStyle = color;
ctx.shadowColor = color;
ctx.shadowBlur = 12;
ctx.fill();
ctx.shadowBlur = 0;
ctx.fillStyle = '#fff';
ctx.font = '12px system-ui, sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(label, x, y);
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(center.x, center.y);
ctx.rotate(angle);
const rHex = scale;
const rPent = scale * 0.9;
// Rings
drawPolygon(6, -rHex * 2.2, 0, rHex, 0, colors.graphite); // A
drawPolygon(6, -rHex, 0, rHex, 0, colors.graphite); // B
drawPolygon(6, 0, 0, rHex, 0, colors.graphite); // C
drawPolygon(5, rHex * 1.25, 0, rPent, Math.PI / 5, colors.graphite); // D
const t = angle * 2;
// Substituents
drawPulseNode(rHex * 1.25 + 35, -20, 'CO', colors.amber, t); // Coconut
drawPulseNode(-rHex * 2.2 - rHex * 0.6, rHex * 0.6, 'B', colors.green, t); // Botanical
drawPulseNode(0, -rHex * 1.6, 'CAF', colors.slate, t); // Caffeine
drawPulseNode(-rHex * 1.5, -rHex * 1.2, 'H₂O', colors.iceBlue, t);
drawPulseNode(rHex * 0.5, rHex * 1.3, 'H₂O', colors.iceBlue, t);
drawPulseNode(rHex * 1.9, -rHex * 1.1, 'H₂O', colors.iceBlue, t);
ctx.restore();
angle += 0.01;
requestAnimationFrame(draw);
}
draw();
})();
ctx.lineWidth = 2;
ctx.stroke();
}
function drawPulseNode(x, y, label, color, t) {
const r = 10 + 3 * Math.sin(t);
ctx.beginPath();
ctx.arc(x, y, r, 0, 2 * Math.PI);
ctx.fillStyle = color;
ctx.shadowColor = color;
ctx.shadowBlur = 12;
ctx.fill();
ctx.shadowBlur = 0;
ctx.fillStyle = '#fff';
ctx.font = '12px system-ui, sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(label, x, y);
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(center.x, center.y);
ctx.rotate(angle);
const rHex = scale;
const rPent = scale * 0.9;
// Rings
drawPolygon(6, -rHex * 2.2, 0, rHex, 0, colors.graphite); // A
drawPolygon(6, -rHex, 0, rHex, 0, colors.graphite); // B
drawPolygon(6, 0, 0, rHex, 0, colors.graphite); // C
drawPolygon(5, rHex * 1.25, 0, rPent, Math.PI / 5, colors.graphite); // D
const t = angle * 2;
// Substituents
drawPulseNode(rHex * 1.25 + 35, -20, 'CO', colors.amber, t); // Coconut
drawPulseNode(-rHex * 2.2 - rHex * 0.6, rHex * 0.6, 'B', colors.green, t); // Botanical
drawPulseNode(0, -rHex * 1.6, 'CAF', colors.slate, t); // Caffeine
drawPulseNode(-rHex * 1.5, -rHex * 1.2, 'H₂O', colors.iceBlue, t);
drawPulseNode(rHex * 0.5, rHex * 1.3, 'H₂O', colors.iceBlue, t);
drawPulseNode(rHex * 1.9, -rHex * 1.1, 'H₂O', colors.iceBlue, t);
ctx.restore();
angle += 0.01;
requestAnimationFrame(draw);
}
draw();
})();
ctx.lineWidth = 2;
ctx.stroke();
}
function drawPulseNode(x, y, label, color, t) {
const r = 10 + 3 * Math.sin(t);
ctx.beginPath();
ctx.arc(x, y, r, 0, 2 * Math.PI);
ctx.fillStyle = color;
ctx.shadowColor = color;
ctx.shadowBlur = 12;
ctx.fill();
ctx.shadowBlur = 0;
ctx.fillStyle = '#fff';
ctx.font = '12px system-ui, sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(label, x, y);
}
function drawAngleTicks(x, y, baseAngle, count, spread, color) {
ctx.strokeStyle = color;
ctx.lineWidth = 1.5;
for (let i = 0; i < count; i++) {
const theta = baseAngle + (i - (count - 1) / 2) * spread;
const r1 = 12, r2 = 22;
const x1 = x + r1 * Math.cos(theta);
const y1 = y + r1 * Math.sin(theta);
const x2 = x + r2 * Math.cos(theta);
const y2 = y + r2 * Math.sin(theta);
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
}
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(center.x, center.y);
ctx.rotate(angle);
const rHex = scale;
const rPent = scale * 0.9;
// Rings
drawPolygon(6, -rHex * 2.2, 0, rHex, 0, colors.graphite); // A
drawPolygon(6, -rHex, 0, rHex, 0, colors.graphite); // B
drawPolygon(6, 0, 0, rHex, 0, colors.graphite); // C
drawPolygon(5, rHex * 1.25, 0, rPent, Math.PI / 5, colors.graphite); // D
// Angle cues
drawAngleTicks(-rHex * 2.2, -rHex, -Math.PI / 2, 3, (120 * Math.PI/180)/2, '#666');
drawAngleTicks(-rHex, rHex, Math.PI / 2, 3, (109.5 * Math.PI/180)/2, '#666');
drawAngleTicks(0, -rHex, -Math.PI / 2, 3, (109.5 * Math.PI/180)/2, '#666');
const t = angle * 2;
// Substituents
const dApexX = rHex * 1.25 + rPent * Math.cos(Math.PI / 5);
const dApexY = rPent * Math.sin(Math.PI / 5);
drawPulseNode(dApexX + 35, dApexY - 20, 'CO', colors.amber, t); // Coconut
const aEqX = -rHex * 2.2 - rHex * 0.6;
const aEqY = rHex * 0.6;
drawPulseNode(aEqX, aEqY, 'B', colors.green, t); // Botanical
drawPulseNode(0, -rHex * 1.6, 'CAF', colors.slate, t); // Caffeine
drawPulseNode(-rHex * 1.5, -rHex * 1.2, 'H₂O', colors.iceBlue, t);
drawPulseNode(rHex * 0.5, rHex * 1.3, 'H₂O', colors.iceBlue, t);
drawPulseNode(rHex * 1.9, -rHex * 1.1, 'H₂O', colors.iceBlue, t);
ctx.restore();
angle += 0.01;
requestAnimationFrame(draw);
}
draw();
})();
Add comment
Comments