Three.js WordPress背景:线框顶点球体绑定及场景集成问题
问题解决与实现指南
一、顶点球体同步旋转问题
你当前的核心问题是球体未跟随线框同步变换,解决思路是将线框与球体挂载到同一个容器组中,通过旋转容器实现所有元素同步运动,利用Three.js父子对象的变换继承特性完成绑定。
修正代码示例:
// 创建总容器组,所有元素挂载于此 const scene = new THREE.Scene(); const group = new THREE.Group(); scene.add(group); // 1. 创建绿松石色二十面体线框 const icoGeometry = new THREE.IcosahedronGeometry(1, 0); const wireframeGeo = new THREE.EdgesGeometry(icoGeometry); const wireframeMat = new THREE.LineBasicMaterial({ color: 0x40e0d0 }); const wireframe = new THREE.LineSegments(wireframeGeo, wireframeMat); wireframe.scale.set(1.5, 1.5, 1.5); // 放大1.5倍 group.add(wireframe); // 2. 创建顶点球体并绑定到容器 const sphereGeo = new THREE.SphereGeometry(0.05, 16, 16); const sphereMat = new THREE.MeshPhongMaterial({ color: 0xffffff }); // 适配光照的材质 // 遍历线框顶点创建球体,同步线框缩放比例 icoGeometry.vertices.forEach(vertex => { const sphere = new THREE.Mesh(sphereGeo, sphereMat); sphere.position.copy(vertex.clone().multiplyScalar(1.5)); group.add(sphere); }); // 动画循环中旋转总容器,所有元素同步转动 function animate() { requestAnimationFrame(animate); group.rotation.y += 0.005; // 调整旋转速度 renderer.render(scene, camera); } animate();
二、WordPress区块背景集成方法
提供两种实用方案,按需选择:
方案1:自定义区块(规范推荐)
- 生成区块骨架:用官方工具创建区块
npx @wordpress/create-block threejs-background-block - 修改渲染结构:在
edit.js和save.js中输出层级结构// save.js 示例 export default function save({ attributes }) { return ( <div className="threejs-bg-block"> <canvas className="threejs-bg-canvas"></canvas> <div className="block-content">{attributes.content}</div> </div> ); } - 添加定位样式:在区块
style.css中设置层级.threejs-bg-block { position: relative; overflow: hidden; min-height: 400px; } .threejs-bg-canvas { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; /* 置于内容下方 */ } .block-content { position: relative; z-index: 1; /* 确保内容可见 */ padding: 2rem; color: #fff; } - 前端初始化Three.js:在
view.js中编写初始化逻辑import * as THREE from 'three'; window.addEventListener('DOMContentLoaded', () => { const blocks = document.querySelectorAll('.threejs-bg-block'); blocks.forEach(block => { const canvas = block.querySelector('.threejs-bg-canvas'); if (!canvas) return; const camera = new THREE.PerspectiveCamera(75, block.clientWidth / block.clientHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer({ canvas, alpha: true }); // 开启透明背景 renderer.setSize(block.clientWidth, block.clientHeight); renderer.setPixelRatio(window.devicePixelRatio); const scene = new THREE.Scene(); const group = new THREE.Group(); // 插入线框、球体、光照代码 scene.add(group); camera.position.z = 5; const animate = () => { requestAnimationFrame(animate); group.rotation.y += 0.005; renderer.render(scene, camera); }; animate(); // 监听窗口尺寸变化 window.addEventListener('resize', () => { camera.aspect = block.clientWidth / block.clientHeight; camera.updateProjectionMatrix(); renderer.setSize(block.clientWidth, block.clientHeight); }); }); });
方案2:自定义HTML区块(快速实现)
- 在编辑器插入自定义HTML区块:
<div class="threejs-bg-container" style="position:relative; overflow:hidden; min-height:400px;"> <canvas class="threejs-bg-canvas"></canvas> <div style="position:relative; z-index:1; padding:2rem; color:#fff;">你的区块内容</div> </div> - 在主题
functions.php中注册脚本:function enqueue_threejs_assets() { wp_enqueue_script('threejs', 'https://cdn.jsdelivr.net/npm/three@0.158.0/build/three.min.js', array(), '0.158.0', true); wp_enqueue_script('threejs-bg-script', get_template_directory_uri() . '/js/threejs-bg.js', array('threejs'), '1.0', true); } add_action('wp_enqueue_scripts', 'enqueue_threejs_assets'); - 在主题
js/threejs-bg.js中编写与方案1类似的初始化代码,获取.threejs-bg-container元素处理即可。
三、添加平行光实现光影效果
平行光需配合受光材质使用,基础代码如下:
// 添加平行光 const directionalLight = new THREE.DirectionalLight(0xffffff, 1.2); directionalLight.position.set(3, 3, 5); scene.add(directionalLight); // 添加环境光避免阴影过暗 const ambientLight = new THREE.AmbientLight(0x404040, 0.5); scene.add(ambientLight);
如需阴影效果,补充以下配置:
// 开启渲染器阴影 renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 设置光源投射阴影 directionalLight.castShadow = true; directionalLight.shadow.mapSize.width = 1024; directionalLight.shadow.mapSize.height = 1024; // 设置球体投射/接收阴影 sphere.castShadow = true; sphere.receiveShadow = true;
内容的提问来源于stack exchange,提问作者ambaamba
相关产品推荐
相关产品推荐

