// === TIMMY SIGIL === import * as THREE from 'three'; import { scene } from './scene-setup.js'; const SIGIL_CANVAS_SIZE = 512; const SIGIL_RADIUS = 3.8; function drawSigilCanvas() { const canvas = document.createElement('canvas'); canvas.width = SIGIL_CANVAS_SIZE; canvas.height = SIGIL_CANVAS_SIZE; const ctx = canvas.getContext('2d'); const cx = SIGIL_CANVAS_SIZE / 2; const cy = SIGIL_CANVAS_SIZE / 2; const r = cx * 0.88; ctx.clearRect(0, 0, SIGIL_CANVAS_SIZE, SIGIL_CANVAS_SIZE); const bgGrad = ctx.createRadialGradient(cx, cy, 0, cx, cy, r); bgGrad.addColorStop(0, 'rgba(0, 200, 255, 0.10)'); bgGrad.addColorStop(0.5, 'rgba(0, 100, 200, 0.04)'); bgGrad.addColorStop(1, 'rgba(0, 0, 0, 0)'); ctx.fillStyle = bgGrad; ctx.fillRect(0, 0, SIGIL_CANVAS_SIZE, SIGIL_CANVAS_SIZE); function glowCircle(x, y, radius, color, alpha, lineW) { ctx.save(); ctx.globalAlpha = alpha; ctx.strokeStyle = color; ctx.lineWidth = lineW; ctx.shadowColor = color; ctx.shadowBlur = 12; ctx.beginPath(); ctx.arc(x, y, radius, 0, Math.PI * 2); ctx.stroke(); ctx.restore(); } function hexagram(ox, oy, hr, color, alpha) { ctx.save(); ctx.globalAlpha = alpha; ctx.strokeStyle = color; ctx.lineWidth = 1.4; ctx.shadowColor = color; ctx.shadowBlur = 10; ctx.beginPath(); for (let i = 0; i < 3; i++) { const a = (i / 3) * Math.PI * 2 - Math.PI / 2; const px = ox + Math.cos(a) * hr; const py = oy + Math.sin(a) * hr; i === 0 ? ctx.moveTo(px, py) : ctx.lineTo(px, py); } ctx.closePath(); ctx.stroke(); ctx.beginPath(); for (let i = 0; i < 3; i++) { const a = (i / 3) * Math.PI * 2 + Math.PI / 2; const px = ox + Math.cos(a) * hr; const py = oy + Math.sin(a) * hr; i === 0 ? ctx.moveTo(px, py) : ctx.lineTo(px, py); } ctx.closePath(); ctx.stroke(); ctx.restore(); } const petalR = r * 0.32; glowCircle(cx, cy, petalR, '#00ccff', 0.65, 1.0); for (let i = 0; i < 6; i++) { const a = (i / 6) * Math.PI * 2; glowCircle(cx + Math.cos(a) * petalR, cy + Math.sin(a) * petalR, petalR, '#00aadd', 0.50, 0.8); } for (let i = 0; i < 6; i++) { const a = (i / 6) * Math.PI * 2 + Math.PI / 6; glowCircle(cx + Math.cos(a) * petalR * 1.73, cy + Math.sin(a) * petalR * 1.73, petalR, '#0077aa', 0.25, 0.6); } hexagram(cx, cy, r * 0.62, '#ffd700', 0.75); hexagram(cx, cy, r * 0.41, '#ffaa00', 0.50); glowCircle(cx, cy, r * 0.92, '#0055aa', 0.40, 0.8); glowCircle(cx, cy, r * 0.72, '#0099cc', 0.38, 0.8); glowCircle(cx, cy, r * 0.52, '#00ccff', 0.42, 0.9); glowCircle(cx, cy, r * 0.18, '#ffd700', 0.65, 1.2); ctx.save(); ctx.globalAlpha = 0.28; ctx.strokeStyle = '#00aaff'; ctx.lineWidth = 0.6; ctx.shadowColor = '#00aaff'; ctx.shadowBlur = 5; for (let i = 0; i < 12; i++) { const a = (i / 12) * Math.PI * 2; ctx.beginPath(); ctx.moveTo(cx + Math.cos(a) * r * 0.18, cy + Math.sin(a) * r * 0.18); ctx.lineTo(cx + Math.cos(a) * r * 0.91, cy + Math.sin(a) * r * 0.91); ctx.stroke(); } ctx.restore(); ctx.save(); ctx.fillStyle = '#00ffcc'; ctx.shadowColor = '#00ffcc'; ctx.shadowBlur = 9; for (let i = 0; i < 12; i++) { const a = (i / 12) * Math.PI * 2; ctx.globalAlpha = i % 2 === 0 ? 0.80 : 0.50; ctx.beginPath(); ctx.arc(cx + Math.cos(a) * r * 0.91, cy + Math.sin(a) * r * 0.91, i % 2 === 0 ? 4 : 2.5, 0, Math.PI * 2); ctx.fill(); } ctx.restore(); ctx.save(); ctx.globalAlpha = 1.0; ctx.fillStyle = '#ffffff'; ctx.shadowColor = '#88ddff'; ctx.shadowBlur = 18; ctx.beginPath(); ctx.arc(cx, cy, 5, 0, Math.PI * 2); ctx.fill(); ctx.restore(); return canvas; } const sigilTexture = new THREE.CanvasTexture(drawSigilCanvas()); export const sigilMat = new THREE.MeshBasicMaterial({ map: sigilTexture, transparent: true, opacity: 0.80, depthWrite: false, blending: THREE.AdditiveBlending, side: THREE.DoubleSide, }); export const sigilMesh = new THREE.Mesh( new THREE.CircleGeometry(SIGIL_RADIUS, 128), sigilMat ); sigilMesh.rotation.x = -Math.PI / 2; sigilMesh.position.y = 0.010; sigilMesh.userData.zoomLabel = 'Timmy Sigil'; scene.add(sigilMesh); export const sigilRing1Mat = new THREE.MeshBasicMaterial({ color: 0x00ccff, transparent: true, opacity: 0.45, depthWrite: false, blending: THREE.AdditiveBlending, }); export const sigilRing1 = new THREE.Mesh( new THREE.TorusGeometry(SIGIL_RADIUS * 0.965, 0.025, 6, 96), sigilRing1Mat ); sigilRing1.rotation.x = Math.PI / 2; sigilRing1.position.y = 0.012; scene.add(sigilRing1); export const sigilRing2Mat = new THREE.MeshBasicMaterial({ color: 0xffd700, transparent: true, opacity: 0.40, depthWrite: false, blending: THREE.AdditiveBlending, }); export const sigilRing2 = new THREE.Mesh( new THREE.TorusGeometry(SIGIL_RADIUS * 0.62, 0.020, 6, 72), sigilRing2Mat ); sigilRing2.rotation.x = Math.PI / 2; sigilRing2.position.y = 0.013; scene.add(sigilRing2); export const sigilRing3Mat = new THREE.MeshBasicMaterial({ color: 0x00ffcc, transparent: true, opacity: 0.35, depthWrite: false, blending: THREE.AdditiveBlending, }); export const sigilRing3 = new THREE.Mesh( new THREE.TorusGeometry(SIGIL_RADIUS * 0.78, 0.018, 6, 80), sigilRing3Mat ); sigilRing3.rotation.x = Math.PI / 2; sigilRing3.position.y = 0.011; scene.add(sigilRing3); export const sigilLight = new THREE.PointLight(0x0088ff, 0.4, 8); sigilLight.position.set(0, 0.5, 0); scene.add(sigilLight);