PRACTICAL FIELD GUIDE

How to make a character follow the cursor.

Understand pointer coordinates, normalization, gaze inputs, smoothing and movement limits. Design a useful mobile and reduced-motion fallback before shipping.

Measure relative to the right rectangle

Pointer events report coordinates in the viewport. A character rig usually expects a small numeric range describing gaze direction. Use the canvas or chosen interaction region’s bounding rectangle to translate from the pointer’s position to the character’s local space.

For a canvas-relative mapping, subtract the rectangle’s left edge from clientX and divide by its width. Do the same with clientY and height. Clamp both results between zero and one so a pointer outside the box cannot push the rig beyond its intended extremes.

const rect = canvas.getBoundingClientRect();
const clamp = n => Math.max(0, Math.min(1, n));
const nx = clamp((event.clientX - rect.left) / rect.width);
const ny = clamp((event.clientY - rect.top) / rect.height);
const lookX = nx * 100;
const lookY = ny * 100;

This example assumes the rig expects zero to one hundred with its neutral point at fifty. A different export may require a signed range or an inverted vertical axis. Verify the contract before connecting values.

Separate target position from displayed gaze

Applying every pointer update directly can produce sharp movement. Store the latest target and let the current gaze approach it in requestAnimationFrame. This also avoids doing more visual work than the browser can display.

A simple interpolation adds a fraction of the remaining difference each frame. For more consistent timing across refresh rates, calculate the fraction from elapsed time using an exponential response. Keep the result responsive enough to feel connected to the visitor.

Constrain eyes and head independently

The website should clamp the overall input, while the rig defines how far the eyes and head can move. Eyes may lead the response while the head uses a smaller range. This keeps the face readable and avoids unnatural stretching.

Test the corners of the interaction region, not only the center. Check that blinking, idle motion and click reactions do not reset the gaze unexpectedly. The state machine needs a deliberate route back to neutral or the current tracking position.

Handle pointer exit and touch

When the pointer leaves, set the target back toward center rather than leaving the character looking offscreen indefinitely. Decide whether tracking covers only the mascot or a larger hero region. Keep listeners scoped to what the experience needs.

Touch has no continuous hover. A tap can set a temporary gaze target and play a greeting, then return to idle. Let the browser keep normal scrolling behavior. Avoid preventing touch defaults simply to make the character track a finger.

Stop work when it is not useful

Pause the animation loop when the mascot is offscreen, the document is hidden or the visitor has requested reduced motion. Cancel scheduled frames and remove listeners during cleanup. A static image should communicate the same character without movement.

Eye tracking is decorative, so keyboard users do not need to imitate a pointer. A normal labelled button can expose the greeting reaction. For a commissioned implementation, the cursor-following service includes planning for the rig and website behavior together.

Keep exploring

LET'S MAKE A CONNECTION

Ready to bring your
mascot to life?

Your character. Your personality. A whole new way to interact.

Let’s talk on WhatsApp