diff --git a/src/components/FlyingSanta.tsx b/src/components/FlyingSanta.tsx new file mode 100644 index 0000000..e8b9d6f --- /dev/null +++ b/src/components/FlyingSanta.tsx @@ -0,0 +1,275 @@ +/* eslint-disable react/no-unknown-property */ +import { useRef, useEffect } from "react"; +import { Canvas, useFrame } from "@react-three/fiber"; +import { Group } from "three"; + +// Cores +const COLORS = { + red: "#D42426", + white: "#F2F2F2", + skin: "#FFCCAA", + black: "#1A1A1A", + gold: "#FFD700", +}; + +const SantaModel = () => { + const group = useRef(null!); + const rightArmRef = useRef(null!); + const leftArmRef = useRef(null!); + const rightLegRef = useRef(null!); + const leftLegRef = useRef(null!); + const headRef = useRef(null!); + + useFrame(({ clock }) => { + const t = clock.getElapsedTime(); + + // Animação de "Tchau" (Braço Direito) + if (rightArmRef.current) { + // Levanta o braço e acena + rightArmRef.current.rotation.z = Math.PI * 0.7; // Levanta + rightArmRef.current.rotation.x = Math.sin(t * 8) * 0.3; // Acena rápido + } + + // Animação de Voo (Braço Esquerdo - Superman style ou relaxado) + if (leftArmRef.current) { + leftArmRef.current.rotation.z = -Math.PI * 0.2; + leftArmRef.current.rotation.x = Math.sin(t * 2) * 0.1; + } + + // Pernas balançando suavemente + if (rightLegRef.current && leftLegRef.current) { + rightLegRef.current.rotation.x = Math.sin(t * 3) * 0.2; + leftLegRef.current.rotation.x = Math.cos(t * 3) * 0.2; + } + + // Cabeça virando levemente + if (headRef.current) { + headRef.current.rotation.y = Math.sin(t * 1) * 0.2; + } + + // Corpo flutuando (bobbing) + if (group.current) { + group.current.position.y = Math.sin(t * 2) * 0.1; + // Leve inclinação para frente (voo) + group.current.rotation.x = 0.2; + } + }); + + return ( + + {/* Tronco */} + + + + + + {/* Cinto */} + + + + + + + + + + {/* Botões */} + + + + + + + + + + {/* Cabeça Group */} + + {/* Rosto */} + + + + + {/* Barba */} + + + + + + + + + {/* Olhos */} + + + + + + + + + {/* Nariz */} + + + + + + {/* Gorro */} + + + + + + + + + + + + + + + + + {/* Braço Direito (Acenando) */} + + + + + + + + + + + + + + + + {/* Braço Esquerdo */} + + + + + + + + + + + + + + + + {/* Perna Direita */} + + + + + + + + + + + + {/* Perna Esquerda */} + + + + + + + + + + + + ); +}; + +const FlyingPath = () => { + const groupRef = useRef(null!); + + // Estado para controlar a trajetória + const offsetRef = useRef(0); + + useEffect(() => { + offsetRef.current = Math.random() * 100; + }, []); + + useFrame(({ clock }) => { + if (!groupRef.current) return; + + const t = clock.getElapsedTime(); + const offset = offsetRef.current; + + // Movimento no eixo X (da direita para esquerda) + // Começa em 15 (fora da tela direita) e vai até -15 (fora da tela esquerda) + // O ciclo total leva cerca de 20 segundos + + const cycleDuration = 20; // segundos + const progress = (t + offset) % cycleDuration; + + let xPos = 15; + + if (progress < 12) { + // Fase de voo (12 segundos para cruzar) + // De 15 até -15 + xPos = 15 - (progress / 12) * 30; + } else { + // Fase de espera (fora da tela) + xPos = -20; + } + + // Movimento Y (Senoide para subir e descer) + const yPos = Math.sin(t * 0.5 + offset) * 2 + 1; // Oscila entre -1 e 3 + + // Movimento Z (Profundidade) + // Aproxima e afasta + const zPos = Math.sin(t * 0.3 + offset) * 3 - 2; // Oscila entre -5 e 1 + + groupRef.current.position.set(xPos, yPos, zPos); + + // Rotação para olhar levemente para a direção do movimento e para a câmera + // Quando xPos está diminuindo (voando para esquerda), ele olha para esquerda/frente + // Ajustado para ficar mais de frente (-Math.PI / 4 = 45 graus) + groupRef.current.rotation.y = -Math.PI / 4; + + // Inclinação dinâmica baseada na altura (sobe = empina, desce = mergulha) + groupRef.current.rotation.z = Math.cos(t * 0.5 + offset) * 0.1; + }); + + return ( + + + + ); +}; + +const FlyingSanta = () => { + return ( +
+ + + + + + +
+ ); +}; + +export default FlyingSanta;