Pular para o conteúdo
Todos os projetos

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.

Cliente
Wisionary Lab, agência de presença digital
Meu papel
Desenvolvimento do tema WordPress e das cenas 3D
Stack
WordPress (tema próprio), PHP, Three.js, JavaScript ES6+
Hero do site da Wisionary Lab com o logo 3D no desktop
Página inicial da Wisionary Lab no celular
Telas do projeto no desktop e no celular

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

  1. Desenvolvi um tema WordPress próprio em PHP, com o conteúdo editável pelo painel.
  2. 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.
  3. Sincronizei a cena com a navegação: a câmera aproxima e inclina conforme o scroll, e o logo reage ao movimento do mouse.
  4. 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();
});