Site institucional · WordPress + Three.js
Wisionary Lab
Site institucional criado para uma agência de presença digital. Tema WordPress próprio em PHP, cenas 3D interativas com Three.js sincronizadas ao scroll e JavaScript ES6+ modular, sem sacrificar performance nem a autonomia de conteúdo do cliente.
Contexto
A Wisionary Lab vende presença digital com estratégia, então o próprio site precisava provar isso: causar impacto logo no primeiro segundo e continuar rápido e fácil de atualizar pela equipe.
Objetivos
- Hero memorável, com uma cena 3D interativa da marca
- Performance preservada mesmo com WebGL na página
- Autonomia total do cliente para editar o conteúdo no WordPress
O que eu fiz
- Desenvolvi um tema WordPress próprio em PHP, com o conteúdo editável pelo painel.
- Criei a cena 3D do hero em Three.js: o logo da marca é extrudido a partir do SVG, com material metalizado e wireframe, sobre um pódio de três degraus com anéis neon e um campo de estrelas.
- Sincronizei a cena com a navegação: a câmera aproxima e inclina conforme o scroll, e o logo reage ao movimento do mouse.
- Organizei o JavaScript em módulos ES6+, com import map para carregar o Three.js e o SVGLoader.
Resultados
- 100 SEO
- 96 Boas práticas
- 95 Acessibilidade
Medição do site em produção · Lighthouse mobile · out/2026. O site segue em produção sob gestão do cliente, então os números refletem o estado atual dele.
Destaques técnicos
O 3D só gasta GPU quando faz sentido: a cena renderiza apenas enquanto o hero está visível e pausa com a aba em segundo plano. O pixelRatio é limitado a 1,5 e, abaixo de 992px, o canvas é desligado para poupar bateria e não cobrir o texto.
// Renderiza só enquanto o hero estiver visível
const visibilityObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting && !document.hidden) startLoop();
else stopLoop();
});
}, { threshold: 0 });
visibilityObserver.observe(canvas.parentElement || canvas);
// Pausa quando a aba vai para segundo plano
document.addEventListener('visibilitychange', () => {
if (document.hidden) stopLoop();
});