import type { DrawContext } from '../types'; import { getSceneColors } from '../colors'; export function drawForestTrees(dc: DrawContext): void { const { ctx, width, height, state } = dc; const colors = getSceneColors(state); const parallax = state.mouseX * 0.8 + state.scrollY * 0.5; const drawPineTree = (x: number, y: number, scale: number, dark: boolean) => { ctx.fillStyle = dark ? '#3E2723' : '#5D4037'; ctx.fillRect(x - 6 * scale + parallax, y, 12 * scale, 35 * scale); const foliageColor = dark ? colors.treeDark : colors.treeLight; ctx.fillStyle = foliageColor; for (let layer = 0; layer < 4; layer++) { const layerY = y + 5 * scale - layer * 22 * scale; const layerWidth = (35 - layer * 5) * scale; ctx.beginPath(); ctx.moveTo(x + parallax, layerY - 25 * scale); ctx.lineTo(x - layerWidth + parallax, layerY); ctx.lineTo(x + layerWidth + parallax, layerY); ctx.closePath(); ctx.fill(); } }; const treePositions = [ { x: width * 0.05, y: height * 0.68, scale: 0.7, dark: true }, { x: width * 0.15, y: height * 0.66, scale: 0.8, dark: true }, { x: width * 0.28, y: height * 0.67, scale: 0.6, dark: true }, { x: width * 0.42, y: height * 0.65, scale: 0.75, dark: true }, { x: width * 0.58, y: height * 0.68, scale: 0.65, dark: true }, { x: width * 0.72, y: height * 0.66, scale: 0.7, dark: true }, { x: width * 0.88, y: height * 0.67, scale: 0.8, dark: true }, { x: width * 0.95, y: height * 0.68, scale: 0.6, dark: true }, { x: width * 0.08, y: height * 0.76, scale: 1.4, dark: false }, { x: width * 0.22, y: height * 0.78, scale: 1.2, dark: false }, { x: width * 0.38, y: height * 0.74, scale: 1.6, dark: false }, { x: width * 0.52, y: height * 0.77, scale: 1.3, dark: false }, { x: width * 0.68, y: height * 0.75, scale: 1.5, dark: false }, { x: width * 0.82, y: height * 0.78, scale: 1.1, dark: false }, { x: width * 0.94, y: height * 0.76, scale: 1.4, dark: false }, ]; treePositions.forEach((t) => drawPineTree(t.x, t.y, t.scale, t.dark)); } export function drawMushrooms(dc: DrawContext): void { const { ctx, width, height, state } = dc; const parallax = state.mouseX * 0.9 + state.scrollY * 0.6; const drawMushroom = (x: number, y: number, scale: number, isRed: boolean) => { ctx.fillStyle = '#F5F5DC'; ctx.beginPath(); ctx.ellipse(x + parallax, y + 8 * scale, 6 * scale, 10 * scale, 0, 0, Math.PI * 2); ctx.fill(); ctx.fillStyle = isRed ? '#D32F2F' : '#8D6E63'; ctx.beginPath(); ctx.ellipse(x + parallax, y - 2 * scale, 12 * scale, 8 * scale, 0, Math.PI, Math.PI * 2); ctx.fill(); if (isRed) { ctx.fillStyle = '#FFFFFF'; ctx.beginPath(); ctx.arc(x + parallax - 4, y - 4 * scale, 2 * scale, 0, Math.PI * 2); ctx.arc(x + parallax + 5, y - 3 * scale, 1.5 * scale, 0, Math.PI * 2); ctx.fill(); } }; drawMushroom(width * 0.15, height * 0.84, 1.0, true); drawMushroom(width * 0.35, height * 0.86, 0.8, false); drawMushroom(width * 0.52, height * 0.83, 1.2, true); drawMushroom(width * 0.78, height * 0.85, 0.9, false); drawMushroom(width * 0.88, height * 0.84, 1.1, true); } export function drawDeer(dc: DrawContext): void { const { ctx, width, height, state } = dc; const time = Date.now() * 0.001; const parallax = state.mouseX * 0.5; const x = width * 0.6 + parallax; const y = height * 0.72; const headBob = Math.sin(time * 2) * 3; ctx.fillStyle = '#8D6E63'; ctx.beginPath(); ctx.ellipse(x, y, 35, 25, 0, 0, Math.PI * 2); ctx.fill(); ctx.fillStyle = '#6D4C41'; ctx.fillRect(x - 20, y + 15, 8, 30); ctx.fillRect(x - 5, y + 18, 8, 28); ctx.fillRect(x + 10, y + 15, 8, 30); ctx.fillRect(x + 25, y + 18, 8, 28); ctx.fillStyle = '#8D6E63'; ctx.beginPath(); ctx.ellipse(x + 40, y - 15 + headBob, 12, 18, 0.3, 0, Math.PI * 2); ctx.fill(); ctx.beginPath(); ctx.ellipse(x + 55, y - 25 + headBob, 10, 12, 0.2, 0, Math.PI * 2); ctx.fill(); ctx.strokeStyle = '#5D4037'; ctx.lineWidth = 3; ctx.lineCap = 'round'; ctx.beginPath(); ctx.moveTo(x + 50, y - 35 + headBob); ctx.lineTo(x + 45, y - 50 + headBob); ctx.lineTo(x + 40, y - 45 + headBob); ctx.moveTo(x + 45, y - 50 + headBob); ctx.lineTo(x + 50, y - 55 + headBob); ctx.stroke(); ctx.beginPath(); ctx.moveTo(x + 60, y - 35 + headBob); ctx.lineTo(x + 65, y - 50 + headBob); ctx.lineTo(x + 70, y - 45 + headBob); ctx.moveTo(x + 65, y - 50 + headBob); ctx.lineTo(x + 60, y - 55 + headBob); ctx.stroke(); ctx.fillStyle = '#1a1a1a'; ctx.beginPath(); ctx.arc(x + 60, y - 25 + headBob, 3, 0, Math.PI * 2); ctx.fill(); } export function drawLightRays(dc: DrawContext): void { const { ctx, width, height, state } = dc; const time = Date.now() * 0.0005; ctx.save(); ctx.globalAlpha = 0.15 + Math.sin(time) * 0.05; const gradient = ctx.createLinearGradient(width * 0.7, 0, width * 0.5, height * 0.7); gradient.addColorStop(0, 'rgba(255, 255, 200, 0.8)'); gradient.addColorStop(1, 'rgba(255, 255, 200, 0)'); ctx.fillStyle = gradient; ctx.beginPath(); ctx.moveTo(width * 0.75, 0); ctx.lineTo(width * 0.85, 0); ctx.lineTo(width * 0.55, height * 0.7); ctx.lineTo(width * 0.45, height * 0.7); ctx.closePath(); ctx.fill(); ctx.beginPath(); ctx.moveTo(width * 0.55, 0); ctx.lineTo(width * 0.62, 0); ctx.lineTo(width * 0.35, height * 0.65); ctx.lineTo(width * 0.28, height * 0.65); ctx.closePath(); ctx.fill(); ctx.restore(); } export function drawForestScene(dc: DrawContext): void { drawLightRays(dc); drawForestTrees(dc); drawMushrooms(dc); drawDeer(dc); }