



Dream Canvas
A living gallery of frontend techniques built with hand-sketched assets and animated in real time.
Explore custom cards, buttons, frames and effects designed with organic textures and brought to life with subtle motion. Every custom effect is a technical showcase, optimized to run together in real time and offer a unique experience.
Frontend Techniques Showcase
This project is a curated gallery of frontend experiments, blending hand-sketched assets refined with AI into polished interactive components. Each effect demonstrates a different technical approach—React hooks, Tailwind animations, global utilities, and layered compositions—all optimized to run together in real time.
The culmination of these experiments is the Living Canvas, a feature that combines rain, snow, gradients, stars, planets, and wind into a single dynamic environment. It represents the core idea of this showcase: pushing frontend techniques beyond isolated demos into a cohesive, responsive visual system.
City Selector
Choose a city and watch the Living Canvas transform in real time. Weather data from the OpenWeather API is translated into hand‑drawn skies, rain, snow, and wind — each effect layered together to create a living illustration of the world outside. This isn’t just a forecast; it’s a visual story that changes minute by minute with the atmosphere.
Select your location below to see the canvas breathe with your city’s weather.
Technical Showcase Overview
Each visual effect in this gallery is not just aesthetic—it demonstrates distinct engineering patterns in React and Tailwind CSS.
- Rain: Raindrops styled in
globals.css, generated viagenerateRaindrop, each usinguseState+useEffectwith staggered timers and keyframe classes (animate-rain-animation-*) to avoid uniform lines. - Snow: Similar to Rain but slower, with opacity tweaks and layered speed variants to create depth and softness in the fall.
- Sky Gradient: A simple array of 24 Tailwind gradient strings indexed by the current hour, updated via props and smoothed with
transition-colorsfor an elegant day/night illusion. - Stars & Planets: Stars generated globally and passed as props into
StarField(state-driven twinkle), while planets are memoized withuseMemoand animated with orbital keyframes. - Wind: Clouds animated with multiple roll speeds tied to API wind data or randomized, while trees sway via wrapper divs to separate layout transforms from animation classes (
animate-tree-sway).
Together these effects illustrate how hooks, props, global utilities, and custom Tailwind animations combine to produce naturalistic motion and responsive visual systems.

Rain
Raindrops are styled globally in globals.css and instantiated via generateRaindrop.tsx. Each drop component (RainDropSuperSlow through RainDropSuperFast) initializes its position with useState(generateRaindrop()) and refreshes via useEffect + setTimeout at different intervals (1300ms down to 700ms). The left property is randomized per drop, while vertical motion is handled by CSS keyframes (animate-rain-animation-*). By importing groups of these components into RainCurtain, the staggered speeds prevent uniform lines and create the illusion of natural rainfall.
Sky Gradient
SkyGradient maps the current hour (0-23) directly to an index in a predefined gradient array. Each gradient is a Tailwind utility string (bg-gradient-to-b from-gray-900 via-gray-800 to-gray-700, etc.), fine-tuned to simulate the sky's transition from midnight black to midday white and back. The component receives hour as a prop, which is updated every minute via useState + useEffect in the parent. The gradient is applied with absolute inset-0 to cover the preview container, and transitions are smoothed with transition-colors duration-2000 for a subtle fade. Midnight corresponds to index 0, noon to index 12, and so on, creating a continuous illusion of the sun's position without complex math or external assets.
Snow
Snowflakes are styled globally in globals.css with lighter opacity and larger radii than raindrops to simulate softness. Each curtain imports multiple flake components (SnowRegular, SnowSlow, SnowVerySlow, SnowSuperSlow, and SnowFast), each initialized with randomized horizontal positions. Like Rain, they use useState(generateSnowflake()) and refresh via useEffect + setTimeout, but with longer intervals to slow the descent. Vertical motion is handled by CSS keyframes (animate-snow-animation-*), tuned for gentler fall speeds. Transparency (opacity-70 to opacity-50) ensures flakes overlap naturally without harsh edges. By mixing speeds and opacities across the curtain, the composition avoids synchronized lines and creates depth, mimicking natural snowfall.
Stars
Stars are generated via a global utility (generateStars) and passed as props into StarField, which uses randomized Image attributes for size, location and color, it also employs a short randomized delay set upon generation to make each star twinkle at a different rate. Planets are created with generatePlanets and memoized using useMemo to avoid regeneration on re renders on the actual showcase. In this case, 100 stars are being generted for the preview, but more or less can be generated as needed.
Wind
Cloud assets are animated with Tailwind keyframes (animate-cloud-roll-short, animate-cloud-roll-medium, animate-cloud-roll-long), each tied either to live wind speed values from the API or set arbitrarily to prevent synchronized motion. This layering ensures clouds drift at different rates, mimicking natural variability. Tree sway was more complex: applying transforms directly to the <Image> conflicted with positioning classes. The solution was to wrap each tree asset in a container <div> and apply the sway animation (animate-tree-sway) to the wrapper instead. This separation preserved layout positioning while allowing independent transform animations. The curtain composition blends multiple cloud speeds with tree sway, producing a cohesive illusion of wind-driven movement.