You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js案例技术咨询:滚动控制动画及页面融合实现方案

Great question! I’ve built similar scroll-driven WebGL experiences before, so let’s break down how to tackle each of your requirements step by step:

1. 滚轮控制Three.js动画进度

The core idea is to map scroll wheel input to a progress value (0 to 1) that drives your entire animation. Here’s how to implement it:

  • First, set up a global progress variable to track your animation state:

    let animationProgress = 0;
    const scrollSensitivity = 0.01; // Adjust this to control scroll speed
    
  • Listen for the wheel event to update the progress. Make sure to clamp the value between 0 and 1 to prevent over-scrolling:

    window.addEventListener('wheel', (e) => {
      // Reverse direction if needed (deltaY is positive when scrolling down)
      animationProgress -= e.deltaY * scrollSensitivity;
      // Clamp to 0-1 range
      animationProgress = Math.max(0, Math.min(1, animationProgress));
    });
    
  • In your Three.js render loop, use this progress value to animate your scene—whether that’s moving the camera, rotating models, or tweaking material properties:

    function animate() {
      requestAnimationFrame(animate);
    
      // Example: Move camera along a path based on progress
      camera.position.x = THREE.MathUtils.lerp(startX, endX, animationProgress);
      camera.lookAt(targetPosition);
    
      renderer.render(scene, camera);
    }
    

Pro tip: For smoother scroll behavior, add a lerp (linear interpolation) to the progress update instead of setting it directly—this creates a "follow" effect that feels more natural.

2. WebGL元素与常规页面布局融合

To make your Three.js canvas act as a background while letting standard HTML content sit on top, use CSS positioning and z-index:

  • Style your Three.js canvas to cover the entire viewport, with a lower z-index than your page content:

    canvas.threejs-background {
      position: fixed;
      top: 0;
      left: 0;
      width: 100vw;
      height: 100vh;
      z-index: -1;
      pointer-events: none; /* Let clicks pass through to HTML elements */
    }
    
  • Make sure your content container has a higher z-index and normal flow:

    .page-content {
      position: relative;
      z-index: 1;
      max-width: 1200px;
      margin: 0 auto;
      padding: 2rem;
    }
    
  • Don’t forget to handle window resizing to keep the canvas properly scaled:

    window.addEventListener('resize', () => {
      renderer.setSize(window.innerWidth, window.innerHeight);
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
    });
    
3. Suspended HTML Elements: Animation Timing Control

To sync HTML element animations with your WebGL scroll progress, you have two reliable approaches:

Option 1: Scroll Progress Triggered Animations

Use the same animationProgress variable to trigger CSS or JS animations on HTML elements when the progress hits a specific threshold:

function updateHTMLAnimations() {
  const infoPanel = document.querySelector('.info-panel');
  
  // Trigger fade-in when progress reaches 0.3
  if (animationProgress >= 0.3 && !infoPanel.classList.contains('active')) {
    infoPanel.classList.add('active');
  }
}

// Call this in your render loop
function animate() {
  requestAnimationFrame(animate);
  updateHTMLAnimations();
  // ... rest of your Three.js rendering
}

Pair this with CSS transitions for smooth effects:

.info-panel {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}

.info-panel.active {
  opacity: 1;
  transform: translateY(0);
}

Option 2: Intersection Observer for Viewport Detection

If you want animations to trigger when elements enter the viewport (instead of being tied directly to scroll progress), use the Intersection Observer API:

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      entry.target.classList.add('active');
      // Optional: Sync Three.js animation to this point
      animationProgress = 0.3; // Match the scroll progress where this element appears
    }
  });
}, { threshold: 0.1 });

// Observe your HTML elements
document.querySelectorAll('.animated-element').forEach(el => {
  observer.observe(el);
});

This works seamlessly with the WebGL background because the canvas is fixed, so scrolling the page moves the HTML elements relative to the static WebGL scene.


内容的提问来源于stack exchange,提问作者Mogie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:12:31