如何用GSAP移动Three.js动画对象且不遮挡HTML文本?
问题描述
我是网页设计新手,若问题较为基础还请见谅。我想要使用GSAP将Three.js中的动画对象移至屏幕左侧,但屏幕左侧已有文本“Hello”。当前GSAP动画移动的是整个场景,移动过程中会短暂遮挡HTML文本。请问是否可以仅移动对象而非整个场景,或是始终保持HTML文本可见?
Three.js代码
import * as THREE from 'three'; import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js'; import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader.js'; import {RGBELoader} from 'three/examples/jsm/loaders/RGBELoader.js'; // Scene 1 - Landing Page container = document.getElementById( 'canvas' ); document.body.appendChild( container ); const renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setSize(window.innerWidth, window.innerHeight); container.appendChild( renderer.domElement ); const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 700 ); const orbit = new OrbitControls(camera, renderer.domElement); camera.position.x = 90 camera.position.y = 200 camera.position.z = 250 orbit.update(); //const grid = new THREE.GridHelper(30, 30); const gltfLoader = new GLTFLoader(); const rgbeLoader = new RGBELoader(); renderer.linearEncoding = THREE.SRGBColorSpace; renderer.toneMapping = THREE.ACESFilmicToneMapping; renderer.toneMappingExposure = 4; let car; rgbeLoader.load('./assets/MR_INT-005_WhiteNeons_NAD.hdr', function(texture) { texture.mapping = THREE.EquirectangularReflectionMapping; scene.environment = texture; gltfLoader.load('./assets/scene.gltf', function(gltf) { const model = gltf.scene; scene.add(model); car = model; }); }); function animate(time) { if(car) car.rotation.y = - time / 3000; renderer.render(scene, camera); } renderer.setAnimationLoop(animate); window.addEventListener('resize', function() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); });
HTML及CSS代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="./style.css"> </head> <body> <div id="canvas"></div> <div class="text-container"> <div class="title"> <h1>Hello</h1> </div> </div> <body> <script src="./js/scripts.js" type="module"></script> <script src="./js/app.js" type="module"></script> <!-- npm install @parcel/config-default -d "staticFiles": { "staticOutPath": "static" } --> </body> </html>
@import url('https://fonts.googleapi.com/css2?family=Montserrat&display=swap'); html { background: black; scroll-behavior: smooth; } body { margin: 0; padding: 0; box-sizing: border-box; overflow-x: hidden; overflow-y: hidden; } .canvas{ position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; } .text-container{ position: absolute; top: 50%; left: 50; width: 50%; height: auto; } .title{ color: whitesmoke } .title h1{ color:whitesmoke }
GSAP脚本
// GSAP Animations import { gsap } from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; gsap.registerPlugin(ScrollTrigger); gsap.to("#canvas",{ x: 350, duration: 2, delay: 1 });
解决方案
方案一:仅移动Three.js中的3D对象(推荐)
你当前的GSAP是直接移动承载Three.js的#canvas容器,导致整个画布移动。正确做法是直接控制Three.js加载的模型对象(即car变量),而非整个容器。
步骤1:让car变量全局可访问
在Three.js脚本末尾添加导出语句,让GSAP脚本能访问到模型对象:
// 在Three.js脚本最后添加 export let car;
步骤2:修改GSAP脚本,直接动画模型位置
// GSAP Animations import { gsap } from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; // 导入Three.js脚本中的car变量 import { car } from './path-to-your-threejs-script.js'; gsap.registerPlugin(ScrollTrigger); // 等待模型加载完成后执行动画(避免car未初始化) gsap.to(car.position,{ x: -100, // 根据需求调整X轴偏移值,负数为向左移动 duration: 2, delay: 1 });
说明
- Three.js的3D坐标与DOM像素坐标不同,需测试调整
x值以达到理想位置 - 模型的
renderLoop已在运行,无需额外触发渲染更新
方案二:让HTML文本始终显示在最上层
若不想修改Three.js动画逻辑,可通过CSS提升文本容器层级,确保不会被画布遮挡:
修改后的CSS代码
@import url('https://fonts.googleapi.com/css2?family=Montserrat&display=swap'); html { background: black; scroll-behavior: smooth; } body { margin: 0; padding: 0; box-sizing: border-box; overflow-x: hidden; overflow-y: hidden; } /* 修复选择器:HTML中是id="canvas",对应#canvas而非.canvas */ #canvas{ position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; z-index: 1; /* 明确画布层级低于文本 */ } .text-container{ position: absolute; top: 50%; left: 50px; /* 修复笔误:原left:50改为具体数值 */ width: 50%; height: auto; z-index: 9999; /* 提升文本层级,确保不会被遮挡 */ transform: translateY(-50%); /* 让文本垂直居中,可选优化 */ } .title{ color: whitesmoke } .title h1{ color:whitesmoke }
说明
- 修复了CSS中的选择器错误:
.canvas改为#canvas z-index:9999确保文本容器层级远高于画布transform: translateY(-50%)优化文本垂直居中效果
内容的提问来源于stack exchange,提问作者EngineerIt
相关产品推荐
相关产品推荐

