Scroll system
The scroll system provides smooth scrolling with advanced subscription capabilities and Webflow editor integration.
Overview
Section titled “Overview”The scroll system provides:
- Smooth scrolling using Lenis
- Priority-based subscription system for scroll events
- Automatic Webflow editor detection and handling
- Scroll position management during page transitions
- Configurable scroll behavior
Core Components
Section titled “Core Components”Scroll Instance
Section titled “Scroll Instance”The main scroll instance is available at @lib/scroll:
import { Scroll } from "@lib/scroll";
// Access scroll instanceScroll.scroll; // Current scroll positionScroll.limit; // Total scrollable heightScroll.progress; // Scroll progress (0-1)Scroll.velocity; // Current scroll velocityConfiguration
Section titled “Configuration”The scroll system uses the following configuration:
const SCROLL_CONFIG = { infinite: false, // Enable infinite scrolling lerp: 0.1, // Linear interpolation factor (smoothness) smoothWheel: true, // Smooth mouse wheel scrolling touchMultiplier: 2, // Touch scroll sensitivity multiplier // autoResize: true, // Auto-resize on window resize};Subscription System
Section titled “Subscription System”Basic Subscription
Section titled “Basic Subscription”Subscribe to scroll events with priority-based ordering:
import { Scroll } from "@lib/scroll";
// Subscribe to scroll eventsconst unsubscribe = Scroll.add((data) => { const { scroll, limit, progress, velocity, time } = data;
// Handle scroll data console.log(`Scroll: ${scroll}/${limit} (${(progress * 100).toFixed(1)}%)`); console.log(`Velocity: ${velocity.toFixed(2)}`);});
// Clean up subscriptionunsubscribe();Priority-Based Subscriptions
Section titled “Priority-Based Subscriptions”Use priorities to control execution order (lower numbers = higher priority):
// High priority (runs first)Scroll.add(updateCriticalElements, -1);
// Normal priority (default = 0)Scroll.add(updateBackgroundElements, 0);
// Low priority (runs last)Scroll.add(updateNonCriticalElements, 1);Advanced Usage
Section titled “Advanced Usage”export default function (element: HTMLElement, dataset: DOMStringMap) { // Subscribe to scroll for parallax effect const scrollUnsubscribe = Scroll.add(({ progress, velocity }) => { // Parallax effect element.style.transform = `translateY(${progress * 100}px)`;
// Velocity-based effects if (Math.abs(velocity) > 0.5) { element.classList.add("scrolling-fast"); } else { element.classList.remove("scrolling-fast"); } });
// Clean up on destroy onDestroy(() => { scrollUnsubscribe(); });}Webflow Editor Integration
Section titled “Webflow Editor Integration”The scroll system automatically detects and handles Webflow editor mode:
import { handleEditor } from "@webflow/detect-editor";
// Automatically handles editor detectionhandleEditor((isEditor) => { if (isEditor) { // Disable smooth scrolling in editor Scroll.destroy(); } else { // Enable smooth scrolling in published site Scroll.start(); }});Editor Detection
Section titled “Editor Detection”The system detects Webflow editor by checking for the .w-editor-publish-node class:
const checkEditorState = () => { const firstChild = document.body.firstElementChild; return ( firstChild instanceof HTMLElement && firstChild.classList.contains("w-editor-publish-node") );};Scroll Management
Section titled “Scroll Management”Manual Control
Section titled “Manual Control”// Scroll to top immediatelyScroll.toTop();
// Scroll to specific positionScroll.scrollTo(1000, { immediate: true, // Instant scroll // duration: 1, // Smooth scroll duration});
// Get scroll dataconst scrollData = { position: Scroll.scroll, limit: Scroll.limit, progress: Scroll.progress, velocity: Scroll.velocity,};Page Transition Integration
Section titled “Page Transition Integration”The scroll system integrates with page transitions:
// In page transition outasync transitionOut() { // Reset scroll position for new page Scroll.toTop();}
// In page transition inasync transitionIn() { // Update scroll calculations for new content Scroll.resize();}Performance Considerations
Section titled “Performance Considerations”Subscription Management
Section titled “Subscription Management”- Limit Subscriptions: Only subscribe when needed
- Clean Up: Always unsubscribe in
onDestroy - Use Priorities: Use priorities to optimize performance
- Debounce Heavy Operations: Avoid heavy computations in scroll callbacks
Memory Management
Section titled “Memory Management”export default function (element: HTMLElement, dataset: DOMStringMap) { let isActive = false;
const scrollUnsubscribe = Scroll.add(({ progress }) => { // Only update when element is in view if (!isActive) return;
// Lightweight operations only element.style.setProperty("--scroll-progress", progress.toString()); });
// Activate only when in view const observer = onView(element, { callback: ({ isIn }) => { isActive = isIn; }, });
onDestroy(() => { scrollUnsubscribe(); });}Integration with Track System
Section titled “Integration with Track System”The scroll system works seamlessly with the Track system:
import { onTrack } from "@/modules/_";
const track = onTrack(element, { bounds: [0, 1], top: "bottom", bottom: "top", callback: (value) => { // value is automatically calculated based on scroll position element.style.transform = `translateY(${value * 100}px)`; },});Best Practices
Section titled “Best Practices”Subscription Patterns
Section titled “Subscription Patterns”- Component-Based: Subscribe in component initialization, unsubscribe in cleanup
- Priority Management: Use priorities for critical vs non-critical updates
- Conditional Updates: Only update when necessary (e.g., element in view)
- Lightweight Operations: Keep scroll callbacks fast and efficient
Webflow Integration
Section titled “Webflow Integration”- Editor Detection: Always use
handleEditorfor Webflow projects - Fallback Handling: Ensure graceful degradation when scroll is disabled
- Testing: Test both editor and published modes
Performance Optimization
Section titled “Performance Optimization”- Throttling: Use throttling for heavy scroll operations
- RAF Integration: Use GSAP ticker for smooth animations
- Memory Cleanup: Always clean up subscriptions and observers
- Efficient Updates: Use CSS transforms instead of layout-triggering properties
Troubleshooting
Section titled “Troubleshooting”Common Issues
Section titled “Common Issues”- Scroll Not Working: Check if Webflow editor is active
- Performance Issues: Reduce number of scroll subscriptions
- Memory Leaks: Ensure all subscriptions are cleaned up
- Conflicts: Check for conflicts with other scroll libraries
Debug Mode
Section titled “Debug Mode”// Enable debug loggingScroll.add((data) => { console.log("Scroll Debug:", data);}, -999); // Very high priorityAPI Reference
Section titled “API Reference”Scroll Instance Methods
Section titled “Scroll Instance Methods”Scroll.add(fn, priority?, id?)- Subscribe to scroll eventsScroll.remove(id)- Remove specific subscriptionScroll.toTop()- Scroll to top immediatelyScroll.scrollTo(target, options?)- Scroll to specific positionScroll.resize()- Recalculate scroll boundsScroll.start()- Start smooth scrollingScroll.destroy()- Destroy scroll instance
Scroll Data Properties
Section titled “Scroll Data Properties”scroll- Current scroll positionlimit- Total scrollable heightprogress- Scroll progress (0-1)velocity- Current scroll velocitytime- Timestamp of scroll event