Week 1: Build a site that responds to scroll with animation and depth


 

Week 1 Schedule:

✅ Days 1–2: Scroll Setup & Animation Flow

✅ Day 3: Generative Motion & AI Integration

✅ Day 4: Scroll-Reactive Design Tweaks

✅ Day 5: Visual Polish & Motion Pacing Site Cohesion

 

Built Using:

  • Framework: Next.js

  • Animation: Framer Motion

  • Smooth Scroll: Lenis

  • Creative Coding: Vanilla Canvas API

  • Visual Assets: AI-generated imagery (RunwayAI) & Original Photos

  • IDE: VS Code

  • Version Control: Git + GitHub

 

Days 1 & 2: Scroll Setup & Animation Flow


My Goals:

I kicked off the sprint by focusing on the basics: scroll behavior, layout structure, and entrance motion.

My goal was to set up the technical foundation for an interactive, scroll-driven site — and start experimenting with how motion shapes experience.

  • Start a project using React’s component-based system to build interactive, scroll-responsive interfaces.

  • Install and configure Framer Motion and Lenis to create smooth, expressive animations tied to user scroll behavior.

  • Build reusable layout sections and connect them to scroll events to explore visual rhythm and flow.

  • Use motion to choreograph the pacing, entrance timing, and transitions between sections.

 

What I Built:

  • Cloned a starter repo from Git configured with Next.js, Framer Motion, and Lenis as the foundation for scroll-based motion.

  • Launched the local dev environment using npm run dev to preview scroll interactions and test motion changes in real time.

  • Created a reusable layout component (MySection.js) to animate individual sections on scroll.

  • Integrated animated sections into the homepage to establish a vertical flow.

  • Applied entrance animations using ‘motion.section’ with easing and offset timing.

  • Built a second section featuring a combined fade + scale effect to vary transition dynamics.

  • Used Lenis to fine-tune scroll behavior, pacing, and smoothness throughout the page.

 

What I Learned:

After the first two days, I learned how to set up Framer Motion in a Next.js project using the App Router to support scroll-based animation.

The following bullets are technical moments I worked through in VS Code to get the site up and running.

  • Enabled client-side animation by declaring "use client" in key component files.

  • Used whileInView and viewport to trigger entrance animations as elements scroll into view.

  • Adjusted animation values like ‘y offset’ and ‘duration’ to make motion feel intentional and visible.

  • Debugged scroll behavior and animation timing using console.log() and onViewportEnter().

  • Observed how spacing, scroll distance, and easing curves shape the overall rhythm of the page.

 

Challenges:

Even with clear goals, things broke down, which is to be expected.

The following bullets cover some of the bugs and snags I encountered while getting scroll-based animation to work in a local React and Next.js project.

  • Defined multiple Home() functions in page.js, which caused a compiler error until cleaned up.

  • Imported a new component but forgot to actually use it in the layout — no animation, no render.

  • Got stuck debugging why animations weren’t firing; turned out to be missing spacing and incorrect viewport settings.

  • Realized scroll-triggered motion won’t run if the page doesn’t scroll. I fixed this by increasing the section height for more scroll room.

 

Reflecting on the first two days:

Seeing scroll-based animation come to life made the entire layout feel more intentional.

Creating my own sections and layering animation effects gave me a sense of design authorship I rarely feel in no-code tools. I now understand how rhythm, padding, and entrance timing shape the user's experience as they move down a page.

This felt like the first real moment of creative dev clicking.

 

Day 3: Generative Motion & AI Integration


 

My Goals:

After setting up the foundational scroll behavior in Days 1 and 2, I wanted to push the visuals further.

Day 3 was about shifting from layout motion to generative motion by exploring how code, input, and animation can blend to create something more reactive and expressive.

These were the goals I set that defined that exploration:

  • Animate visuals inside a <canvas> element using vanilla JavaScript

  • Make visuals react to both mouse movement and scroll position

  • Layer in an AI-generated background image with visual depth

  • Explore generative animation as a storytelling layer

 

What I Built:

To bring those goals to life, I built a generative visual system using the Canvas API; no libraries, just raw JavaScript. I started with a simple draw loop, then added behavior: motion, interaction, and visual depth. It took 4 stages to get from static to fully in motion.

Below is the visual evolution of the generative motion implemented.

  • Created an animated canvas using requestAnimationFrame() for a smooth draw loop

  • Drew 100 generative, pulsing circles with independent color + motion

  • Made circles react to cursor position for a line-to-mouse interaction

  • Connected scroll position to color shifting using a scrollYRef

  • Layered a glowing AI-generated bubble image behind the canvas

  • Managed layout with position: relative and stacked DOM layers using z-index

 

Stage 1: Static Circles

To start, the circles in the section are static, just to make sure all the correct elements are there. Now to animating them.

 
 

Stage 2: Pulsing in Motion

Then I went full generative mode, using requestAnimationFrame() to continuously animate the canvas by giving each circle a pulsing rhythm. I also made it so that the cursor would be the center of gravity for a perspective web of lines that moved with your movements.

 
 

Stage 3: Scroll-Driven Hue Shifting

I tied each circle’s color hue to the scroll position using a scrollYRef. As you move down the page, the entire generative field subtly shifts in color, making the scroll itself feel alive.

 
 

Stage 4: Layered AI Background

A soft, AI-generated bubble texture sits behind the canvas, blending into the animated circles. It adds subtle depth and atmosphere.

 
 

What I Learned:

After building the foundation for scroll animation, I spent Day 3 exploring interactive and generative visuals using the Canvas API. My focus was on creating reactive motion, basically, visuals that respond to user input and scroll position. The following bullets are the technical concepts I worked through in VS Code while integrating animation loops, canvas behaviors, and layered composition.

  • Used useRef to persist scroll position inside an animation loop without re-renders

  • Prevented canvas errors by clamping radius values with Math.max() to avoid negative input in arc()

  • Learned how to position canvas and DOM layers together using z-index and layout styles

  • Realized that subtle background elements (like low-opacity images) can completely shift the tone of an experience

 
 

Challenges:

This was my first time mixing generative visuals with DOM layout and scroll input, so naturally, a few things broke.

These were the issues I hit while setting up animation logic, layering canvas with background visuals, and getting scroll data to behave:

  • Scroll position (scrollY) wasn’t updating inside the animation loop. I fixed it by using useRef to persist scroll state

  • The canvas animation crashed because some circles had negative radius values. This was solved by clamping them with Math.max()

  • Layering a background image beneath the canvas caused layout bugs. I had to adjust z-index, opacity, and pointer-events to get the right blend

  • The scroll-triggered color shifting wasn’t obvious at first so I added more vertical padding to give the visuals room to evolve while scrolling

 

Day 3 Reflections:

This was really cool to create. I enjoyed being able to see it evolve stage by stage, from static, to animated, to gradient hues and finally with an AI generated image for a background.

Watching the canvas respond to my mouse and scroll input made the whole experience feel reactive and alive. The AI background, even at low opacity, brought an unexpected softness that made the code feel more atmospheric than mechanical.

 

Day 4: Scroll-Reactive Design Tweaks using framer


 

Refresher:

After getting scroll-based animations working and layering in canvas visuals (like the generative circles from Day 3), I wanted to bring that same kind of reactivity into the page layout itself.

Today’s focus was about making sections feel dynamic, not just by appearing, but by actually changing as you scroll through them. This required using Framer Motion’s scroll hooks to link real-time motion to scroll behavior.

 

Day 4 Goals:

I wanted to experiment with scroll-based transitions that evolve as you move. Not just one-time entrances, but continuous motion that tracks your scroll.

Day 4 was about refining how sections enter and evolve on scroll — using Framer Motion’s useScroll() and useTransform() to link animation directly to scroll position.

  • Create a new section that reacts to scroll position in real time

  • Use Framer Motion’s scroll tools instead of just whileInView

  • Animate multiple properties together: opacity, scale, and x-position

  • Make the scroll experience feel smoother and more layered

  • Start thinking about how transitions can connect different sections

 

What I built:

To bring this to life, I built a new component called ScrollTransition.js. This section animates based on how far you’ve scrolled through it. I used useScroll() and useTransform() from Framer Motion to make this happen.

  • The section fades in, scales up, and slides in from the side

  • All of that is tied directly to how far you scroll

  • I added it to the main page and tested it locally at localhost:3000

  • The motion is continuous — not just a “one-time” animation

 

What I Learned:

This was my first time using Framer’s scroll hooks instead of whileInView, and it unlocked a lot of control.

  • You can connect scroll to any style — not just opacity

  • Using scale, x, and opacity together creates really smooth transitions

  • Little motion tweaks (like a 0.8→1.1 scale) have a big impact on feel

  • Layout motion doesn’t have to be loud. Subtle changes can be immersive.

  • I now understand the difference between triggering motion once vs. tying it to scroll continuously

 
 

Challenges:

This wasn’t a super technical day, but it was a shift in mindset. The challenge was less about errors and more about understanding why this type of scroll motion is different and when to use it.

  • Took me a minute to understand how this was different from whileInView

  • Had to slow down and think through how useScroll() and useTransform() actually work

  • Visual tweaks (like how far something moves or scales) really changed how it felt — small changes made a big difference

  • At first, the effect was subtle and felt “meh” — I had to layer it with multiple styles to really bring it to life

 

Day 4 Reflections:

This was a turning point.

Today was less about building something new and more about refining flow. The scroll in this section feels smoother, like it breathes with the user. And I realized I’ve been doing this same kind of scroll-reactive behavior in different ways:

In Day 3, it was in Canvas with raw scrollY

In Day 4, it’s in Framer Motion with declarative transforms

Same idea, different tool. That’s the kind of understanding I began this journey to get.

 

Day 5: Visual Polish & Motion Pacing Site Cohesion


 

Quick Intro:

I am keeping the text for today short and sweet since I am a bit frustrated. Today, I shifted my focus away from individual animations and toward the bigger picture: how the entire site flows together.

Day 5 Goals:

The goal for today was to step back and begin transforming the site from a collection of parts into a single, intentional experience. Rather than focusing on new interactions, I wanted to refine the layout, adjust spacing, and start thinking about how the scroll journey feels as a whole.

Until now, each section was designed and animated in isolation. But I started to feel the disjointedness, and I want the experience to feel like one continuous scroll, not a bunch of stacked demos.

 

What I Built:

The biggest step forward today was adding a new section called <SelfPortrait />. I want to shape the site into something that can be a creative reflection of myself.

The new section is the first step towards that. It is a scroll-through list of the cities I've called home: Mexico City, Paris, San Francisco, and more.

I also made some light visual tweaks, like changing the background from black to a softer off-white so that I could use a fun gradient I created (which reflects the visual direction I’m now leaning into), adjusting the gradient opacity, and tightening the layout to better support the new storytelling direction.

It doesn’t look great and it is not perfect but it is a good start.

 

What I Learned:

Shifting from technical demos to personal narrative changes how you design. Every spacing decision, every motion effect, suddenly needs to serve a purpose. I realized how much more intentional I need to be if this site is going to feel like a true interactive self-portrait.

Technically speaking, I learned about adjusting images you add in the VS Code to be exactly how you want them to be and I learned more about creating new sections.

Challenges:

The site still feels a little disjointed, especially in how sections flow from one to the next. I found it hard to step back and design for cohesion while also writing code. A strange amount of space showed up at the bottom of the new section, and some layout decisions (like gradient placement) still need refinement.

The visual direction is shifting, but the content and flow need to catch up.

 

Reflections on Day 5:

Today felt like a pivot. For the first time, the site started to express something about who I am. I’m not just animating scroll sections anymore: I’m building a vibe-driven portrait using motion, layout, and feeling.

It’s still rough and a little scattered, but now there’s a direction I believe in. Next week, I want to map that direction clearly and give each section purpose in the larger scroll journey.

 
Previous
Previous

Week 2: Bringing 3D & Narrative to the Scroll Experience