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.













