| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 |
- import { SpectrumRenderer, SpectrumRenderOptions, buildSpectrumPalette, hslToHex, rgbaFromHex } from './SpectrumRenderer'
- /**
- * 星爆频谱渲染器
- * 从中心向外爆发的星芒线条
- */
- export class StarburstSpectrumRenderer implements SpectrumRenderer {
- private drift: number = 0
- render(ctx: CanvasRenderingContext2D, bands: number[], energy: number,
- width: number, height: number, brandColor: string, options?: SpectrumRenderOptions): void {
- if (bands.length === 0) return
- ctx.clearRect(0, 0, width, height)
- const palette = buildSpectrumPalette(brandColor)
- const centerX: number = width / 2
- const centerY: number = height / 2
- const complexityScale: number = Math.max(0.45, Math.min(1, options?.complexityScale ?? 1))
- const rays: number = Math.max(18, Math.floor(44 * complexityScale))
- const outerMax: number = Math.min(width, height) * 0.46
- const innerRadius: number = Math.min(width, height) * 0.08
- this.drift += 0.015 + energy * 0.01
- for (let i = 0; i < rays; i++) {
- const bandIndex: number = Math.floor((i / rays) * bands.length)
- const value: number = Math.pow(bands[bandIndex], 0.8)
- const angle: number = (Math.PI * 2 * i) / rays + this.drift
- const len: number = innerRadius + value * (outerMax - innerRadius)
- const x1: number = centerX + Math.cos(angle) * innerRadius
- const y1: number = centerY + Math.sin(angle) * innerRadius
- const x2: number = centerX + Math.cos(angle) * len
- const y2: number = centerY + Math.sin(angle) * len
- const hue: number = (palette.warmHue + i * 5) % 360
- ctx.beginPath()
- ctx.moveTo(x1, y1)
- ctx.lineTo(x2, y2)
- ctx.strokeStyle = rgbaFromHex(hslToHex(hue, 0.88, 0.58), 0.20 + value * 0.70)
- ctx.lineWidth = 1 + value * 2.2
- ctx.stroke()
- }
- const coreRadius: number = innerRadius * (0.85 + energy * 0.65)
- ctx.beginPath()
- ctx.arc(centerX, centerY, coreRadius, 0, Math.PI * 2)
- ctx.fillStyle = rgbaFromHex(hslToHex(palette.complementaryHue, 0.82, 0.62), 0.14 + energy * 0.18)
- ctx.fill()
- }
- reset(): void {
- this.drift = 0
- }
- }
|