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
🔜 Day 6: AI + Motion Concept Development
🔜 Day 7: Clean-up & Document
Built Using:
Framework: Next.js
Animation: Framer Motion
Smooth Scroll: Lenis
Creative Coding: Vanilla Canvas API
Visual Assets: AI-generated imagery (RunwayAI)
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; all developed and tested locally in VS Code.
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. These are some of the bugs and snags I encountered while getting scroll-based animation to work as expected 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 — fixed by increasing section height for more scroll room.
Reflections for 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 to guide 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.
Here's what came together by the end of the session:
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
Visual Evolution: Generative Motion in 4 Stages
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-dev mode, using requestAnimationFrame() to continuously animate the canvas by giving each circle a pulsing rhythm.
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-rendersPrevented canvas errors by clamping radius values with
Math.max()
to avoid negative input inarc()
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 making sections feel dynamic, not just by appearing, but by actually changing as you scroll through them. This meant 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.
Today’s goals:
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 make scroll more 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