You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Three.js的VideoTexture加载视频时显示加载器?

Absolutely! This is a common UX improvement, and there are a couple of clean ways to pull it off in Three.js. The core idea is to use a placeholder texture (like a loading spinner or static message) initially, then swap it out for your VideoTexture once the video is ready to play. Let's break down the two most straightforward approaches:

1. Placeholder Texture + Video Load Event (Simple & Direct)

This method starts with a static loading texture, then switches to the video texture as soon as the video is ready.

  • Step 1: Create your loading placeholder texture
    You can use an image file, or generate a simple loading screen directly with canvas (no external assets needed):

    // Create a canvas for the loading screen
    const loadingCanvas = document.createElement('canvas');
    loadingCanvas.width = 512;
    loadingCanvas.height = 512;
    const ctx = loadingCanvas.getContext('2d');
    
    // Draw a minimal loading state (customize this to match your design!)
    ctx.fillStyle = '#222';
    ctx.fillRect(0, 0, loadingCanvas.width, loadingCanvas.height);
    ctx.fillStyle = '#fff';
    ctx.font = '48px sans-serif';
    ctx.textAlign = 'center';
    ctx.fillText('Loading Video...', loadingCanvas.width / 2, loadingCanvas.height / 2);
    
    // Turn the canvas into a Three.js texture
    const loadingTexture = new THREE.CanvasTexture(loadingCanvas);
    
  • Step 2: Initialize your material with the placeholder, then listen for video readiness

    // Start with the loading texture on your material
    const material = new THREE.MeshBasicMaterial({ map: loadingTexture });
    
    // Grab your video element
    const video = document.getElementById('your-video-element-id');
    
    // Wait for the video to have enough data to play
    video.addEventListener('canplay', () => {
      // Create the VideoTexture now that the video is ready
      const videoTexture = new THREE.VideoTexture(video);
      // Set proper filters to avoid blurriness (adjust based on your video)
      videoTexture.minFilter = THREE.LinearFilter;
      videoTexture.magFilter = THREE.LinearFilter;
      videoTexture.format = THREE.RGBAFormat;
    
      // Swap the texture and tell Three.js to update the material
      material.map = videoTexture;
      material.needsUpdate = true;
    
      // Start playing the video
      video.play();
    });
    
2. Dynamic Canvas Texture (For Animated Loading States)

If you want a more interactive loading experience (like an animated spinner), use a dynamic canvas texture that switches from drawing loading content to video frames once loaded.

// Create a canvas for dynamic content
const canvas = document.createElement('canvas');
canvas.width = 512;
canvas.height = 512;
const ctx = canvas.getContext('2d');
const dynamicTexture = new THREE.CanvasTexture(canvas);

// Initialize material with the dynamic texture
const material = new THREE.MeshBasicMaterial({ map: dynamicTexture });

const video = document.getElementById('your-video-element-id');
let videoIsReady = false;

// Function to draw the loading state (animate this if you want!)
function drawLoading() {
  ctx.fillStyle = '#222';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = '#fff';
  ctx.font = '48px sans-serif';
  ctx.textAlign = 'center';
  // Add a simple animation by rotating the text (optional)
  ctx.save();
  ctx.translate(canvas.width / 2, canvas.height / 2);
  ctx.rotate(Date.now() * 0.001);
  ctx.fillText('⟳ Loading', 0, 0);
  ctx.restore();
  dynamicTexture.needsUpdate = true;
}

// Function to draw the video frame
function drawVideo() {
  ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
  dynamicTexture.needsUpdate = true;
}

// Listen for video readiness
video.addEventListener('canplay', () => {
  videoIsReady = true;
  video.play();
});

// Add to your existing animation loop
function animate() {
  requestAnimationFrame(animate);

  // Draw the appropriate content based on video state
  if (videoIsReady) {
    drawVideo();
  } else {
    drawLoading();
  }

  // Your standard Three.js render call
  renderer.render(scene, camera);
}
animate();

Key Notes:

  • Use the canplay event instead of loadeddata — it’s more reliable because it confirms the video has enough buffered data to start playing without stuttering.
  • Always set material.needsUpdate = true after swapping textures, otherwise Three.js won’t detect the change.
  • If you’re using an external image for the loading texture, use THREE.TextureLoader() with a callback to ensure the image loads before creating the texture.

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

火山引擎 最新活动