Have you ever wanted to build something so fun that you
forgot you were even coding? That's exactly what happened
when I built this â a fully cinematic, interactive login
portal featuring Toothless the Night Fury from
How to Train Your Dragon đ
đ Live Demo
đ Try it here
⨠What Does It Do?
This isn't just a login form. Toothless reacts to everything you do:
- đ Eye Tracking â the dragon's pupils follow your cursor in real time as you move around the screen
- đĒŊ Shy Behavior â when you click the password field, Toothless lowers his wings and hides shyly
- ⥠Plasma Charge â hitting the login button triggers a full plasma charging animation sequence
- đŠī¸ Cinematic Thunder â custom lightning and thunder effects fire during dramatic moments
đ ī¸ Tech Stack
- Angular 21 â component architecture and reactive form state handling
- Tailwind CSS v3 â all layout and utility styles
- Pure SVG â Toothless is hand-crafted SVG, no images or libraries
- CSS Keyframe Animations â all motion is pure CSS
- Gemini AI â used to engineer the cinematic animation sequences and thunder/lightning effects
đĄ How the Eye Tracking Works
The core idea is simple â track the mouse position
relative to the eye center and move the pupils:
@HostListener('mousemove', ['$event'])
onMouseMove(event: MouseEvent) {
const eyeRect = this.eyeElement.getBoundingClientRect();
const eyeCenterX = eyeRect.left + eyeRect.width / 2;
const eyeCenterY = eyeRect.top + eyeRect.height / 2;
const angle = Math.atan2(
event.clientY - eyeCenterY,
event.clientX - eyeCenterX
);
const distance = 4; // max pupil travel distance
this.pupilX = Math.cos(angle) * distance;
this.pupilY = Math.sin(angle) * distance;
}
The pupils are constrained to a small radius so they
never go outside the eye boundary â giving a natural
realistic feel.
đĒŊ How the Shy Behavior Works
When the password field receives focus, Angular's
reactive form detects the state change and triggers
a CSS class that animates the wings downward:
onPasswordFocus() {
this.isPasswordFocused = true; // wings lower
}
onPasswordBlur() {
this.isPasswordFocused = false; // wings rise back
}
In the template:
<div [class.wings-down]="isPasswordFocused"
class="toothless-wings">
</div>
⥠The Plasma Charge Sequence
On form submission, a multi-stage animation fires:
- Toothless opens his mouth
- A glowing plasma orb builds up
- The orb pulses and expands
- A flash covers the screen
- Login success state appears
This entire sequence is timed using Angular's
setTimeout chain synced with CSS animation durations.
Top comments (0)