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; From ae818b624f765741d41931009b44f1eeb9ce5c09 Mon Sep 17 00:00:00 2001 From: Matheus Henrique Caiser Barrozo Date: Thu, 27 Nov 2025 00:39:49 -0300 Subject: [PATCH 2/2] chore: remove temporary pr description --- pr_description.md | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 pr_description.md diff --git a/pr_description.md b/pr_description.md deleted file mode 100644 index f57c536..0000000 --- a/pr_description.md +++ /dev/null @@ -1,15 +0,0 @@ -## Description -Adds a festive 3D Flying Santa component to the application. - -## Changes -- Created `FlyingSanta.tsx`: A procedural low-poly 3D Santa model built with React Three Fiber primitives. -- Implemented complex animation logic: - - Santa flies across the screen from right to left. - - Waves "Goodbye" with his right arm. - - Bobbing and weaving flight path (sine wave motion). - - Random appearance intervals (15-45 seconds). -- Integrated `FlyingSanta` into `App.tsx`. -- Cleaned up unused assets and dependencies. - -## Visuals -Santa appears flying across the screen with a red and white low-poly design.