Como fazer um logo que segue o cursor
Por equipe Charmotion · Atualizado em

Para fazer um logo seguir o cursor, escute pointermove, transforme a posição do ponteiro em relação ao logo em um pequeno ângulo ou deslocamento e faça a transição suave do logo até ele. Use transforms CSS para uma inclinação, Math.atan2 para olhos que olham para o ponteiro, ou listeners e Data Binding do Rive para um rig desenhado. Desative com movimento reduzido.
Principais pontos
- Só com CSS dá para reagir ao hover, mas não para ler a posição do ponteiro; algumas linhas de JavaScript definem variáveis CSS para a inclinação.
- Math.atan2(y, x) dá o ângulo do olho até o ponteiro; mova cada pupila uma distância fixa ao longo dele.
- Os listeners do Rive reagem ao ponteiro sobre o canvas; para segui-lo pela página inteira, passe valores por Data Binding.
- Telas de toque não têm hover, então planeje um movimento idle ou uma reação ao toque.
- O movimento acionado pelo ponteiro deve ser desativado com prefers-reduced-motion (WCAG 2.3.3), e loops idle longos precisam de uma forma de parar (WCAG 2.2.2).
Já tem um personagem ou logo? Veja exemplos em telas reais de app: telas de splash, onboarding, carregamento e estado vazio, com a animação que toca em cada uma.
De que formas um logo pode reagir ao mouse?
| Efeito | O que se move | Ferramenta mais simples |
|---|---|---|
| Reação ao hover | O logo faz um movimento curto quando o ponteiro está sobre ele | :hover do CSS |
| Inclinação em direção ao cursor | O logo inteiro gira alguns graus em direção ao ponteiro | JavaScript mais transforms CSS |
| Olhos que acompanham | As pupilas, ou uma parte do logo, apontam para o cursor | JavaScript com Math.atan2 em um SVG inline |
| Rig desenhado | Várias partes respondem com easing, squash e estados | Rive (listeners e Data Binding) |
| Giro em 3D | Um modelo 3D gira no espaço | three.js |
Para um modelo 3D, veja um logo 3D interativo no seu site. O restante deste guia trata das opções 2D.
Dá para fazer um logo reagir ao mouse só com CSS?
Em parte. O CSS consegue reagir a se o ponteiro está sobre o logo, mas não a onde ele está. Uma reação ao hover é puro CSS:
.logo { transition: transform 0.25s ease-out; }
@media (hover: hover) {
.logo:hover { transform: rotate(-6deg) scale(1.05); }
}
A media feature hover testa se "o principal mecanismo de entrada do usuário consegue passar sobre os elementos." Em muitos celulares ela retorna none, porque eles "emulam o hover quando o usuário faz um toque longo inconveniente." Envolver os efeitos de hover em @media (hover: hover) os restringe a dispositivos cuja entrada principal realmente consegue fazer hover.
Para inclinar em direção ao ponteiro, você precisa das coordenadas dele, o que significa um pequeno script.
Como inclinar um logo em direção ao cursor com JavaScript?
Meça onde o ponteiro está em relação ao centro do logo, converta isso em um ângulo e passe para o CSS por custom properties. A transition do CSS suaviza o movimento, então não há loop de animação para gerenciar.
<a class="logo-link" href="/"><img class="logo" src="/logo.svg" alt="Hushwave"></a>
.logo {
transform: perspective(600px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
transition: transform 0.2s ease-out;
}
@media (prefers-reduced-motion: reduce) {
.logo { transform: none; transition: none; }
}
const logo = document.querySelector(".logo");
const moves = matchMedia("(prefers-reduced-motion: no-preference) and (hover: hover)");
if (moves.matches) {
window.addEventListener("pointermove", (e) => {
const r = logo.getBoundingClientRect();
const x = (e.clientX - (r.left + r.width / 2)) / innerWidth; // about -1 to 1
const y = (e.clientY - (r.top + r.height / 2)) / innerHeight;
logo.style.setProperty("--ry", (x * 20) + "deg"); // flip the signs to tilt away instead
logo.style.setProperty("--rx", (-y * 20) + "deg");
});
}
Mantenha os ângulos pequenos. Um logo que gira 45 graus parece quebrado, enquanto alguns graus parecem vivos. Se o logo fica em um cabeçalho fixo, meça-o uma vez no resize em vez de a cada evento.
Escutar em window faz o logo reagir em qualquer ponto da página. Escute no elemento do cabeçalho se ele só deve reagir por perto.
Como fazer os olhos de um logo seguirem o cursor?
O logo precisa ser um SVG inline com as pupilas como elementos separados, para que você possa movê-las. Depois, para cada olho, encontre o ângulo do centro do olho até o ponteiro com Math.atan2, que retorna "o ângulo em radianos (entre -π e π, inclusive)" e recebe "primeiro a coordenada y e depois a coordenada x", segundo o MDN.
const eye = document.querySelector("#eye-left");
const pupil = document.querySelector("#pupil-left");
const reach = 3; // how far the pupil may travel, in SVG units
window.addEventListener("pointermove", (e) => {
const r = eye.getBoundingClientRect();
const a = Math.atan2(e.clientY - (r.top + r.height / 2), e.clientX - (r.left + r.width / 2));
pupil.setAttribute("transform", "translate(" + Math.cos(a) * reach + " " + Math.sin(a) * reach + ")");
});
Um alcance fixo mantém a pupila dentro do olho seja qual for a distância. Para um visual mais suave, reduza o alcance quando o ponteiro estiver muito perto do olho, para que a pupila não salte para a borda.
Ao exportar do Figma, a opção de SVG Include "id" attribute adiciona ids com base nos nomes das camadas, então nomear as camadas como eye-left e pupil-left dá ao script algo para encontrar.
Como fazer um logo Rive seguir o ponteiro?
O Rive oferece dois caminhos, e o certo depende de até onde o ponteiro deve ser seguido.
Listeners, dentro do canvas. Um listener de state machine pode disparar em Pointer Enter, Exit, Move, Down e Up. A ação Align Target dele "posiciona um objeto para que ele siga o ponteiro", por exemplo um alvo invisível ao qual os olhos ou a cabeça estão presos por constraints. A documentação do Rive avisa que o Pointer Exit "só dispara enquanto o Rive consegue ler a posição do ponteiro", então os listeners só veem o ponteiro sobre o canvas. A ação mais antiga Input Change está marcada como obsoleta.
Data Binding, pela página toda. O Data Binding "conecta dados armazenados em View Models a propriedades da sua cena Rive", e os valores podem ser atualizados pelo código em runtime. Escute o ponteiro na página e escreva números no arquivo:
const r = new rive.Rive({
src: "/logo.riv",
canvas: document.querySelector("#logo"),
stateMachine: "Main",
autoplay: true,
autoBind: true,
isTouchScrollEnabled: true,
onLoad: () => {
const lookX = r.viewModelInstance.number("lookX"); // a number property defined in your file
window.addEventListener("pointermove", (e) => {
lookX.value = (e.clientX / innerWidth) * 100;
});
},
});
isTouchScrollEnabled mantém a página rolável quando um dedo arrasta sobre o canvas; sem isso, o Rive diz que "o comportamento de rolagem pode ser bloqueado." O lado da animação (blend states controlados pelo número) é configurado no editor; o guia de state machine do Rive explica como, e SVG para Rive mostra como levar o logo para o Rive.
O que acontece em celulares e tablets sem mouse?
Telas de toque não têm um ponteiro em repouso. A documentação de pointer events do MDN descreve os eventos de entrada e saída em dispositivos que "não suportam hover" chegando junto com o toque e a soltura, então um logo que segue o cursor só se move enquanto um dedo está na tela e depois congela onde estava.
- Limite o efeito: rode o acompanhamento do cursor só sob
(hover: hover), como no exemplo da inclinação. - Dê ao toque o seu próprio movimento: um loop idle lento, ou uma reação curta ao tocar, funciona melhor do que um acompanhamento que funciona pela metade.
- Não bloqueie a rolagem: o MDN descreve
touch-action: nonecomo algo que desativa o comportamento de toque padrão do navegador, como deslocar e dar zoom, naquela região. Em um logo no fluxo da página, um arraste que começa nele deixaria de rolar a página. - Volte ao soltar: faça a transição de volta à pose de repouso em
pointerupepointercancel, para que o logo não fique torto.
Um logo que segue o cursor é acessível?
Pode ser, se as pessoas puderem desativar o movimento. Dois critérios da WCAG se aplicam:
| Critério | Nível | O que ele pede |
|---|---|---|
| 2.3.3 Animation from Interactions | AAA | "A animação de movimento acionada por interação pode ser desativada", a menos que seja essencial |
| 2.2.2 Pause, Stop, Hide | A | Conteúdo em movimento que "começa automaticamente, dura mais de cinco segundos e é apresentado em paralelo com outro conteúdo" precisa de uma forma de pausar, parar ou ocultar |
Um logo que segue o cursor é movimento acionado por interação, e nunca é essencial. O W3C lista a media query prefers-reduced-motion como técnica suficiente (C39) para o 2.3.3, e é por isso que todos os exemplos acima a verificam. Se o logo também tem um loop idle que continua tocando, pare-o depois de alguns ciclos ou dê a ele um controle de pausa para atender ao 2.2.2.
Mantenha também o logo como um link normal com texto alternativo. O movimento é decoração; o nome da marca e o link para a página inicial são o conteúdo. Mais em animação acessível e movimento reduzido.
Dá para ter um logo que segue o ponteiro já pronto?
O Motion Studio do Charmotion cria a partir do seu próprio logo um hero de site que segue o ponteiro, reage ao hover e fica em loop em repouso. Ele trabalha com as partes do seu próprio arquivo, então o logo não é redesenhado. Você recebe um embed hospedado que pausa fora da tela e respeita o movimento reduzido, arquivos para auto-hospedagem e um componente React. Os conceitos são grátis; criar um começa no Starter (US$ 9/mês em novembro de 2026). Para um logo com rosto que deve piscar e falar, um conjunto de personagem é a melhor opção.
Perguntas frequentes
Um logo que segue o cursor deixa a página mais lenta?
Não, se ele continuar pequeno. Um handler de pointermove que define duas variáveis CSS é barato. Evite medir o layout a cada evento quando o logo não se move, pause qualquer loop de animação enquanto o logo estiver fora da tela e pule o efeito por completo em dispositivos de toque e com movimento reduzido.
Um logo Rive pode seguir o cursor fora do seu canvas?
Não só com listeners, que só veem o ponteiro sobre o canvas. Escute pointermove na página em JavaScript e escreva os valores em uma propriedade numérica de view model por Data Binding; a state machine então transforma esses números em movimento.
Quanto um logo deve inclinar em direção ao cursor?
Alguns graus bastam para parecer responsivo sem parecer quebrado. Ângulos grandes distorcem o logo e dificultam a leitura do texto. Suavize o movimento ao longo de uma fração de segundo em vez de saltar, e volte à pose de repouso quando o ponteiro sair.
Fontes
- Pointer events, MDN Web Docs
- hover media feature, MDN Web Docs
- Math.atan2(), MDN Web Docs
- Window: requestAnimationFrame() method, MDN Web Docs
- prefers-reduced-motion, MDN Web Docs
- Listeners, Rive docs
- Data binding overview, Rive docs
- Web data binding, Rive docs
- Rive parameters (web runtime), Rive docs
- Understanding SC 2.3.3: Animation from Interactions, W3C WAI
- Understanding SC 2.2.2: Pause, Stop, Hide, W3C WAI
- C39: Using the CSS prefers-reduced-motion query to prevent motion, W3C WAI
- Export formats and settings for static designs, Figma Learn