Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/apursley2012/dev-haunt/llms.txt

Use this file to discover all available pages before exploring further.

HauntedHouse is the centerpiece of the DevHaunt landing page — a fully self-contained SVG illustration that combines Framer Motion animations with a scroll-driven door mechanism. It accepts no props and manages all of its own state internally, making it a true drop-in component.

How It Works

The component registers a scroll event listener via useEffect that writes window.scrollY into a useState variable. Every scroll event recalculates the door rotation angle and re-renders the panel accordingly. Because no external data is needed, the component is completely portable.
import { HauntedHouse } from '../components/HauntedHouse';

// Place it anywhere — no props required
<HauntedHouse />

Scroll-Reactive Door

As the user scrolls down, the front door swings open using a CSS 3D perspective transform applied inline to a <g> element whose transformOrigin is anchored at the left edge of the door frame (175px 320px).
const r = Math.min(Math.max(scrollY * 0.5, 0), 45);
// r ranges from 0° (closed) to 45° (fully open)
The resulting style applied to the door panel group is:
transform: `perspective(400px) rotateY(${r}deg)`
The multiplier 0.5 means the door reaches its maximum 45° opening after the user has scrolled 90 pixels. Adjust that multiplier in HauntedHouse.js to change how quickly the door responds.
The door animation is purely CSS-transform-based and does not use Framer Motion, so it updates on every scroll event without any spring physics or interpolation. This keeps it snappy and frame-accurate.

Framer Motion Animated Elements

Four elements inside the SVG are animated with Framer Motion on infinite loops:
ElementAnimationDuration
MoonFloats vertically y: [0, -10, 0] with easeInOut10 s
CloudDrifts horizontally x: [-100, 300] with linear25 s
Ghost in windowBobs vertically y: [10, 0, 10] with easeInOut4 s
Sign above doorSways with CSS animate-sway classCSS keyframe
Windows use the CSS utility class animate-flicker (defined in main.css) with staggered animationDelay values of 0s, 1s, and 2s so each window appears to flicker independently.
// Moon — Framer Motion loop
<motion.div
  animate={{ y: [0, -10, 0] }}
  transition={{ duration: 10, repeat: Infinity, ease: 'easeInOut' }}
/>

// Cloud — Framer Motion loop
<motion.div
  animate={{ x: [-100, 300] }}
  transition={{ duration: 25, repeat: Infinity, ease: 'linear' }}
/>

// Ghost — Framer Motion loop (inside SVG <g>)
<motion.g
  animate={{ y: [10, 0, 10] }}
  transition={{ duration: 4, repeat: Infinity, ease: 'easeInOut' }}
/>

// Sign — CSS class
<motion.g className="animate-sway" style={{ transformOrigin: '200px 150px' }} />

SVG Structure

The SVG uses a viewBox="0 0 400 400" coordinate space. Below is a breakdown of the main shapes:
ShapeElementFillDescription
Main house body<path> polygon#1a252cCentral five-point house silhouette
Roof<path> triangle#0d151aDark peaked roof above the body
Right tower<path> rectangle#1a252cNarrow vertical tower on the right side of the main body
Annex (left)<path> rectangle#151e24Low left-side annex body
Annex roof<path> triangle#0d151aPeaked triangular roof over the left annex
Windows (×2)<rect> groups#0b3a44 / #ff7a1aDark frame with orange-lit panes, animate-flicker
Round window<circle> + arcs#0b3a44 / #ff7a1aCircular window on the left annex wall, animate-flicker
Door frame<rect>#0b3a44Background door rectangle
Door step<path>#0d151aTrapezoidal stoop
Door panel<rect> + <circle> + <rect>#3e2723 / #ff7a1a / #1a1a1aRotating wooden panel with brass knob and a dark inset window pane
Moon<motion.div>#f4f1eaOff-white circle with three crater <div> children
Cloud<motion.div>bg-night/40Blurred rounded oval
Ghost<motion.g>#f4f1eaGhost body with two dot eyes, bobbing in front of the round window
Sign strings<line> × 2#f4f1eaTwo thin rope lines suspending the sign from the roof peak
DevHaunt sign<motion.g>#3e2723 / #ff7a1aBrown rect with “DevHaunt” text in Caveat Brush font, swaying via animate-sway

Color Palette

The illustration uses seven hardcoded fill values sourced from the DevHaunt design system:
const colors = {
  houseDark:    '#1a252c', // main house body, right tower
  nightDeep:    '#0d151a', // roof, door step, door frame bg
  annexDark:    '#151e24', // left annex wall body
  tealDeep:     '#0b3a44', // window frames, door background
  pumpkin:      '#ff7a1a', // window glow, knob, sign text
  ghost:        '#f4f1ea', // moon, ghost body
  woodBrown:    '#3e2723', // door panel, sign background
};

Customization

All customizations are made directly in components/HauntedHouse.js — the component has no props interface by design.
Change the sign text — Find the <text> element inside the animate-sway group and replace "DevHaunt" with your own name or tagline:
// components/HauntedHouse.js
<text
  x="200" y="190"
  fill="#ff7a1a"
  fontSize="14"
  fontFamily="Caveat Brush"
  textAnchor="middle"
>
  Your Name Here
</text>
Adjust window glow color — Replace the #ff7a1a fill on the inner <rect> panes with any color:
<rect x="135" y="225" width="12" height="20" fill="#a855f7" /> // purple glow
Change animation speeds — Update the duration value in the Framer Motion transition prop for any looping element:
// Slow the moon float to 20 seconds
transition={{ duration: 20, repeat: Infinity, ease: 'easeInOut' }}
Slow or speed up door opening — Change the 0.5 multiplier in the scroll calculation:
// Opens faster (reaches 45° at ~45px of scroll)
const r = Math.min(Math.max(scrollY * 1.0, 0), 45);

// Opens slower (reaches 45° at ~180px of scroll)
const r = Math.min(Math.max(scrollY * 0.25, 0), 45);

Build docs developers (and LLMs) love