Frontend 3D — Sites 3D com Rolagem
Crie páginas HTML imersivas em um único arquivo onde a rolagem guia o usuário por uma cena 3D construída com Three.js. O conteúdo (títulos, texto, imagens, CTAs) é sobreposto ou incorporado ao mundo 3D. Cada página DreamWalk é um artefato .html autocontido — sem ferramentas de build, npm ou React.
Stack Tecnológica
Todas as saídas são artefatos HTML de arquivo único. Sem ferramentas de build, npm ou React — apenas um arquivo .html autocontido.
| Biblioteca | CDN | Propósito |
|---|---|---|
| Three.js r128 | https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js | Motor de renderização 3D |
| GSAP 3.12.5 | https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js | Motor de animação |
| ScrollTrigger 3.12.5 | https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js | Vinculação rolagem-animação |
Por que essa stack? Three.js é o framework WebGL dominante com o maior ecossistema. GSAP ScrollTrigger é o padrão da indústria para mapear posição de rolagem a timelines de animação. Juntos, eles alimentam a maioria dos sites 3D premiados (veja Awwwards, FWA). Essa combinação funciona em um único arquivo HTML sem etapa de build, perfeita para artefatos.
Importante: Restrições da API Three.js r128. Esta NÃO é a versão mais recente do Three.js. Os seguintes elementos NÃO existem no r128 e nunca devem ser usados:
CapsuleGeometry,RoundedBoxGeometry,THREE.MathUtils.seededRandom,WebGPURenderer,THREE.ColorManagement. Sempre use primitivasBufferGeometry(BoxBufferGeometry,SphereBufferGeometry, etc.) ou seus aliases (BoxGeometry,SphereGeometry).
Padrão de Arquitetura
┌─────────────────────────────────────────┐
│ Página HTML │
│ ┌───────────────────────────────────┐ │
│ │ <canvas> - Cena Three.js (fixo) │ │
│ │ • Câmera em um caminho/spline │ │
│ │ • Objetos 3D (geometria/partículas) │
│ │ • Iluminação e névoa │ │
│ └───────────────────────────────────┘ │
│ ┌───────────────────────────────────┐ │
│ │ <div class="scroll-container"> │ │
│ │ height: 500vh+ (rolável) │ │
│ │ Seções com texto/conteúdo │ │
│ │ sobrepostas via position:fixed ou│ │
│ │ fade de opacidade em gatilhos │ │
│ └───────────────────────────────────┘ │
│ │
│ GSAP ScrollTrigger mapeia scroll% → │
│ camera.position / camera.lookAt / │
│ transformações de objeto / parâmetros │
│ de material │
└─────────────────────────────────────────┘
Como Construir uma Página 3D com Rolagem
Leia references/PATTERNS.md para padrões de código detalhados e prontos para copiar e colar antes de escrever código. Ele contém mais de 40 padrões prontos para produção para animação de câmera, iluminação, shaders, partículas, geometria procedural e otimização de desempenho — todos compatíveis com Three.js r128.
Etapa 1: Design da Cena
Decida o tipo de experiência com base na intenção do usuário:
| Tipo | Comportamento da Câmera | Melhor para |
|---|---|---|
| Túnel / Corredor | Voar para frente ao longo do eixo Z | Revelação de produtos, narrativa |
| Órbita / Vitrine | Girar em torno de um objeto central | Páginas de produto, portfólios |
| Sobrevoo de Paisagem | Varrer sobre terreno/urbano | Landing pages, introduções |
| Passeio por Sala | Mover-se por espaços conectados | Tours virtuais, apresentações |
| Descida Vertical | Câmera desce no eixo Y | Linha do tempo, revelações de camadas |
| Caminho Spline | Câmera segue um caminho 3D curvo | Cinematográfico, editorial |
Etapa 2: Estrutura HTML
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Experiência 3D</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { overflow-x: hidden; }
canvas { position: fixed; top: 0; left: 0; z-index: 0; }
.scroll-container { position: relative; z-index: 1; pointer-events: none; }
.section { height: 100vh; display: flex; align-items: center; justify-content: center; }
.content { pointer-events: auto; /* reativar para elementos interativos */ }
</style>
</head>
<body>
<!-- O canvas Three.js é criado programaticamente -->
<div class="scroll-container">
<!-- Seções geram altura de rolagem; o conteúdo sobrepõe a cena 3D -->
<div class="section" id="section-1">...</div>
<div class="section" id="section-2">...</div>
<!-- Mais seções = mais distância de rolagem = jornada de câmera mais longa -->
</div>
<script src="THREE_CDN"></script>
<script src="GSAP_CDN"></script>
<script src="SCROLLTRIGGER_CDN"></script>
<script>
// Configuração da cena, animação, vínculos ScrollTrigger
</script>
</body>
</html>
Etapa 3: Configuração Principal do Three.js
Sempre inclua estes fundamentos:
- Cena + Câmera + Renderizador — Use
PerspectiveCameracom FOV 60-75 para sensação imersiva - Iluminação — No mínimo: um
AmbientLight+ umDirectionalLight. AdicionePointLightouSpotLightpara dramaticidade - Névoa —
scene.fog = new THREE.FogExp2(color, density)adiciona profundidade e esconde objetos que aparecem repentinamente - Manipulador de redimensionamento — Sempre trate
window.resize - Loop de renderização —
requestAnimationFramecomrenderer.render(scene, camera)
Etapa 4: Animação Rolagem → Câmera com GSAP
O padrão de vinculação crítico:
gsap.registerPlugin(ScrollTrigger);
// Armazena alvos de animação da câmera como um objeto simples
const camAnim = { x: 0, y: 2, z: 10, lookX: 0, lookY: 0, lookZ: 0 };
const tl = gsap.timeline({
scrollTrigger: {
trigger: ".scroll-container",
start: "top top",
end: "bottom bottom",
scrub: 1, // 1 segundo de suavização
}
});
// Encadeia keyframes da câmera
tl.to(camAnim, { x: 0, y: 2, z: 5, lookX: 0, lookY: 0, lookZ: 0, duration: 1 })
.to(camAnim, { x: 3, y: 1, z: 0, lookX: 2, lookY: 0, lookZ: -5, duration: 1 })
.to(camAnim, { x: 0, y: 5, z: -10, lookX: 0, lookY: 0, lookZ: -15, duration: 1 });
// No loop de renderização, aplique os valores animados
function animate() {
requestAnimationFrame(animate);
camera.position.set(camAnim.x, camAnim.y, camAnim.z);
camera.lookAt(camAnim.lookX, camAnim.lookY, camAnim.lookZ);
renderer.render(scene, camera);
}
Etapa 5: Sobreposição de Conteúdo
Sobreponha conteúdo HTML que aparece/desaparece em posições de rolagem:
// Aparece uma seção quando a câmera atinge um ponto de passagem
gsap.fromTo("#section-2 .content",
{ opacity: 0, y: 50 },
{ opacity: 1, y: 0,
scrollTrigger: {
trigger: "#section-2",
start: "top center",
end: "top 20%",
scrub: true
}
}
);
Etapa 6: Polimento Visual
Aplique estes para elevar do básico ao impressionante:
- Partículas —
THREE.PointscomTHREE.BufferGeometrypara poeira/estrelas flutuantes - Brilho pós-processamento — Use materiais emissivos + cores brilhantes tipo bloom
- Transições de cor — Anime
scene.backgroundescene.fog.colorao longo da rolagem - Revelações de objetos — Objetos escalam de 0 ou aparecem conforme a câmera se aproxima
- Camadas de paralaxe — Objetos em diferentes distâncias se movem em taxas diferentes
- Rotação sutil — Gire lentamente objetos decorativos no loop de renderização (independente da rolagem)
- Paralaxe do mouse — Pequeno deslocamento da câmera baseado na posição do mouse para sensação de profundidade
Princípios de Design
- Desempenho primeiro — Mantenha a geometria simples. Use
BufferGeometry, limite chamadas de desenho, usefogpara esconder objetos distantes. Mire em 60fps - Rolagem suave —
scrub: 1ouscrub: 2no ScrollTrigger para movimento suave. Nunca usescrub: true(instantâneo, irregular) - Conteúdo legível — Sobreposições de texto precisam de contraste. Use painéis escuros semitransparentes atrás de texto claro, ou garanta que o fundo 3D seja escuro/desfocado atrás das áreas de texto
- Fallback para mobile — Rolagem por toque funciona com ScrollTrigger. Considere reduzir contagens de partículas e complexidade de geometria em mobile via verificações
window.innerWidth - Carregamento elegante — Mostre uma tela de carregamento CSS simples, esconda-a quando a cena Three.js estiver pronta
Objetos 3D Comuns para Construir (sem modelos externos necessários)
Estes podem ser criados com geometria integrada do Three.js — sem arquivos GLTF necessários:
- Formas geométricas flutuantes — BoxGeometry, IcosahedronGeometry, TorusKnotGeometry com MeshStandardMaterial
- Terreno — PlaneGeometry com deslocamento de vértices (ondas senoidais, ruído)
- Campos de partículas — BufferGeometry + Points para estrelas, poeira, neve, visualização de dados
- Pisos de grade — GridHelper ou geometria de linha personalizada
- Tubos/túneis — TubeGeometry ao longo de um caminho CatmullRomCurve3
- Texto — Texturas de Canvas renderizadas em PlaneGeometry, ou baseadas em sprites
- Objetos wireframe — Qualquer geometria com material
wireframe: truepara estética tecnológica - Feixes de luz — CylinderGeometry com material emissivo transparente
Etapa 7: Paralaxe do Mouse (Opcional, mas Recomendado)
Adicione um pequeno deslocamento da câmera ao mover o mouse para percepção de profundidade:
const mouse = { x: 0, y: 0 };
document.addEventListener('mousemove', (e) => {
mouse.x = (e.clientX / window.innerWidth - 0.5) * 2; // -1 a 1
mouse.y = (e.clientY / window.innerHeight - 0.5) * 2;
});
// No loop de renderização, adicione um pequeno deslocamento à câmera
const parallaxStrength = 0.3;
camera.position.x = camAnim.x + mouse.x * parallaxStrength;
camera.position.y = camAnim.y - mouse.y * parallaxStrength * 0.5;
Padrão de Passeio por Sala
Para passeios arquitetônicos / imobiliários, construa salas com geometria simples:
// Crie uma sala com BoxGeometry para paredes, piso, teto
function createRoom(width, height, depth, position, color) {
const mat = new THREE.MeshStandardMaterial({ color, side: THREE.BackSide });
const room = new THREE.Mesh(new THREE.BoxGeometry(width, height, depth), mat);
room.position.copy(position);
scene.add(room);
return room;
}
// Crie placeholders de mobília com geometria simples
// Sofá = caixa larga e achatada, Mesa = caixa fina sobre cilindros, Luminária = cilindro + esfera
// Use PointLights emissivas dentro das salas para sensação de interior acolhedor
Princípios chave para passeios por salas:
- Use
THREE.BackSidenos materiais para que as paredes renderizem de dentro - Coloque fontes de
PointLightquentes dentro de cada sala (cor0xffeedd, intensidade 0.8) - O caminho da câmera deve entrar por aberturas de portas, não atravessar paredes
- Anime camera.lookAt para escanear naturalmente cada sala ao entrar
- Adicione retângulos de janela com material emissivo brilhante para simular luz do dia
Antipadrões a Evitar
- ❌ NÃO use
OrbitControls— a rolagem deve ser a única navegação - ❌ NÃO carregue modelos GLTF/GLB externos — mantenha tudo autocontido no arquivo HTML
- ❌ NÃO use
THREE.CapsuleGeometry— não disponível no r128 - ❌ NÃO defina
pointer-events: noneno canvas globalmente — o loop de renderização precisa do canvas - ❌ NÃO esqueça
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))— previne sobrecarga da GPU em retina - ❌ NÃO anime a câmera com
camera.rotationdiretamente — usecamera.lookAt()com coordenadas de alvo animadas para resultados estáveis - ❌ NÃO torne o contêiner de rolagem muito curto — mínimo de 400vh para uma jornada significativa, preferencialmente 600vh+
Direção Estética
Aplique a mesma ousadia criativa da skill frontend-design. Cada página 3D com rolagem deve parecer única:
- Escolha um clima de cor: neon cyberpunk, pôr do sol quente, oceano profundo, gelo cristalino, vazio escuro com acentos emissivos, etc.
- Escolha uma linguagem de geometria: curvas orgânicas vs arestas duras, esparso vs denso, monólitos grandes vs partículas minúsculas
- Tipografia sobreposta: importe fontes Google distintas. Use tipografia grande e cinematográfica. Anime opacidade e transformação na rolagem
- A cena 3D e o conteúdo HTML devem parecer uma experiência coesa, não um fundo 3D com texto colocado
Referência Rápida: URLs CDN
Three.js r128: https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js
GSAP 3.12.5: https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js
ScrollTrigger: https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js