feat: add scroll-driven animation to About page Timeline section#691
feat: add scroll-driven animation to About page Timeline section#691ankitkr104 wants to merge 1 commit intoAOSSIE-Org:mainfrom
Conversation
- Add useScroll + useTransform to track scroll progress through timeline - Animated yellow vertical line grows/shrinks as user scrolls up/down - Travelling yellow dot moves along the line in sync with scroll - Dual pulsing rings on the travelling dot for visual depth - Background track line added as static reference - Pass index prop to TimelineElement for alternating card animations - Heading entrance animation updated with scale effect Closes AOSSIE-Org#690
📝 WalkthroughWalkthroughThe Timeline component was refactored to replace static rendering with a scroll-driven animated timeline using Framer Motion. Added scroll tracking hooks (useRef, useScroll, useTransform) to dynamically animate a growing vertical line, traveling dot with pulsating rings, and entry animations synchronized with scroll position. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment Tip CodeRabbit can suggest fixes for GitHub Check annotations.Configure the |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/components/about/Timeline.jsx (1)
43-59: Travelling dot may overflow at scroll end; consider reduced-motion preference.Two potential issues:
Overflow at 100%: When
glowYreaches"100%", the 15px dot's top edge aligns with the container's bottom, causing the dot to render outside the visible timeline area.Accessibility: The infinite pulsing animations can be problematic for users with vestibular disorders. Consider respecting
prefers-reduced-motion.Proposed fix for overflow and accessibility
+import { useReducedMotion } from 'framer-motion'Then in the component:
export function Timeline() { const containerRef = useRef(null) + const prefersReducedMotion = useReducedMotion() const { scrollYProgress } = useScroll({Fix the overflow by accounting for dot height:
- const glowY = useTransform(scrollYProgress, [0, 1], ["0%", "100%"]) + const glowY = useTransform(scrollYProgress, [0, 1], ["0%", "calc(100% - 15px)"])Conditionally disable pulsing animations:
{/* pulsing ring 1 */} - <motion.span - animate={{ scale: [1, 2.5, 1], opacity: [0.7, 0, 0.7] }} - transition={{ duration: 1.6, repeat: Infinity, ease: "easeOut" }} - className="absolute inset-0 rounded-full bg-yellow-400" - /> + {!prefersReducedMotion && ( + <motion.span + animate={{ scale: [1, 2.5, 1], opacity: [0.7, 0, 0.7] }} + transition={{ duration: 1.6, repeat: Infinity, ease: "easeOut" }} + className="absolute inset-0 rounded-full bg-yellow-400" + /> + )} {/* pulsing ring 2 — offset */} - <motion.span - animate={{ scale: [1, 2, 1], opacity: [0.4, 0, 0.4] }} - transition={{ duration: 1.6, repeat: Infinity, ease: "easeOut", delay: 0.5 }} - className="absolute inset-0 rounded-full bg-yellow-300" - /> + {!prefersReducedMotion && ( + <motion.span + animate={{ scale: [1, 2, 1], opacity: [0.4, 0, 0.4] }} + transition={{ duration: 1.6, repeat: Infinity, ease: "easeOut", delay: 0.5 }} + className="absolute inset-0 rounded-full bg-yellow-300" + /> + )}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/about/Timeline.jsx` around lines 43 - 59, The moving dot can overflow when glowY is "100%" and its pulsing is inaccessible; clamp or adjust glowY so the dot stays fully inside the timeline (e.g., cap the value at calc(100% - 15px) or compute a numeric max before passing to style top) and respect reduced-motion by disabling the pulsing animations when the user prefers reduced motion (use framer-motion's useReducedMotion or matchMedia to skip/replace the animate/transition props on the motion.div/motion.span elements and avoid infinite repeats).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/components/about/Timeline.jsx`:
- Around line 61-88: The TimelineElement instances are being passed an unused
index prop; either remove index from all TimelineElement usages or update the
TimelineElement component (where it destructures {title, description, time}) to
also accept index and apply it to its animation/staggering logic (e.g., use
index to compute animation delay, alternate side placement, or conditional
classes). Locate the TimelineElement component and either delete index from the
props list and from all TimelineElement JSX here, or add index to the
destructured props and incorporate it into the animation/timing/position
calculations so the staggered/alternating behavior mentioned in the PR works.
---
Nitpick comments:
In `@src/components/about/Timeline.jsx`:
- Around line 43-59: The moving dot can overflow when glowY is "100%" and its
pulsing is inaccessible; clamp or adjust glowY so the dot stays fully inside the
timeline (e.g., cap the value at calc(100% - 15px) or compute a numeric max
before passing to style top) and respect reduced-motion by disabling the pulsing
animations when the user prefers reduced motion (use framer-motion's
useReducedMotion or matchMedia to skip/replace the animate/transition props on
the motion.div/motion.span elements and avoid infinite repeats).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: cbff1e9f-79a6-4552-b1f5-44400a78c3fa
📒 Files selected for processing (1)
src/components/about/Timeline.jsx
| <TimelineElement index={0} | ||
| title="AOSSIE's First Projects" time="2011" | ||
| description="3 of AOSSIE's first projects (Skeptik/Scavenger, Carbon Footprint for Google Maps and Mind the Word) were started by Dr. Bruno Woltzenlogel Paleo and started participating in GSoC under the CSE@TU-Wien org." | ||
| /> | ||
| <TimelineElement index={1} | ||
| title="AOSSIE's Creation" time="2016" | ||
| description="Dr. Bruno Woltzenlogel Paleo created the Australian Open Source Software Innovation and Education (AOSSIE) while he was a researcher at the Australian National University." | ||
| /> | ||
| <TimelineElement index={2} | ||
| title="First GSoC Participation" time="2016" | ||
| description="We participated in Google Summer of Code for the first time, mentoring students from around the world. Our Agora voting project became our fourth project." | ||
| /> | ||
| <TimelineElement index={3} | ||
| title="AOSSIE's Independence" time="2017" | ||
| description="AOSSIE was established as an independent not-for-profit charity organization." | ||
| /> | ||
| <TimelineElement index={4} | ||
| title="Pace Acceleration" time="2020" | ||
| description="In 2020, AOSSIE accelerated its innovation pace and started several new projects, especially using emerging technologies such as blockchains and AI." | ||
| /> | ||
| <TimelineElement index={5} | ||
| title="Stability Nexus Spin-Off" time="2022" | ||
| description="In 2022, AOSSIE's blockchain projects were grouped under the Stability Nexus sub-organization." | ||
| /> | ||
| <TimelineElement index={6} | ||
| title="Becoming an AI-Powered AI-Ready Organization" time="2025--2026" | ||
| description="AOSSIE is radically transforming its processes to fully benefit from AI productivity boosts while protecting itself from AI slop." | ||
| /> |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify TimelineElement's function signature and whether index is used
echo "=== TimelineElement function signature ==="
rg -n "function TimelineElement|const TimelineElement|export.*TimelineElement" src/components/about/TimelineElement.jsx
echo ""
echo "=== Check if 'index' is referenced anywhere in TimelineElement ==="
rg -n "index" src/components/about/TimelineElement.jsx || echo "No references to 'index' found"Repository: AOSSIE-Org/Website
Length of output: 269
Remove unused index props or implement them for staggered animations in TimelineElement.
The index prop is passed to TimelineElement in lines 61–88 but the component only destructures {title, description, time} and never uses index. If these props were intended to enable alternating or staggered animations (as mentioned in the PR description), update TimelineElement to actually reference the index in its animation logic. Otherwise, remove the index props from all TimelineElement instances.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/components/about/Timeline.jsx` around lines 61 - 88, The TimelineElement
instances are being passed an unused index prop; either remove index from all
TimelineElement usages or update the TimelineElement component (where it
destructures {title, description, time}) to also accept index and apply it to
its animation/staggering logic (e.g., use index to compute animation delay,
alternate side placement, or conditional classes). Locate the TimelineElement
component and either delete index from the props list and from all
TimelineElement JSX here, or add index to the destructured props and incorporate
it into the animation/timing/position calculations so the staggered/alternating
behavior mentioned in the PR works.
Closes #690
Recordings:
Aossie.web.mp4
AI Usage Disclosure:
We encourage contributors to use AI tools responsibly when creating Pull Requests. While AI can be a valuable aid, it is essential to ensure that your contributions meet the task requirements, build successfully, include relevant tests, and pass all linters. Submissions that do not meet these standards may be closed without warning to maintain the quality and integrity of the project. Please take the time to understand the changes you are proposing and their impact. AI slop is strongly discouraged and may lead to banning and blocking. Do not spam our repos with AI slop.
Check one of the checkboxes below:
I have used the following AI models and tools: TODO
Checklist
Summary by CodeRabbit