如何在Shopify中成功集成Three.js?3D模型显示异常求助
Shopify集成Three.js 3D模型问题解决方案
核心问题排查与修复
1. 版本不兼容问题
你导入的Three.js核心库是0.117.1,但GLTFLoader用的是0.129.0,版本差异会导致加载器无法正常工作。统一版本:
// 统一使用0.129.0版本 import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.129.0/build/three.module.js'; import { GLTFLoader } from 'https://cdn.jsdelivr.net/npm/three@0.129.0/examples/jsm/loaders/GLTFLoader.js';
2. Canvas样式缺失
页面显示的空白小盒子是因为canvas没有设置样式,添加CSS给canvas:
#bg { display: block; width: 100%; height: 100vh; position: relative; }
可以在自定义Liquid区块里添加<style>标签,或者放到Shopify的主题CSS文件中。
3. 模型加载异步导致的错误
animate函数中直接访问loadedModel.scene,但模型加载是异步操作,页面初始化时loadedModel还未赋值,会导致潜在错误。修改animate逻辑:
function animate() { requestAnimationFrame(animate); // 先判断模型是否加载完成再执行旋转 if (loadedModel && loadedModel.scene) { loadedModel.scene.rotation.y += 0.0075; } renderer.render(scene, camera); }
4. 模型缩放与位置设置错误
你错误地给整个scene设置了缩放,应该给加载后的gltf模型设置:
loader.load('https://cdn.shopify.com/s/files/1/0551/2708/1111/files/taiyo_shiny.gltf?v=1662981628', function (gltf) { loadedModel = gltf; const model = gltf.scene; // 给模型设置缩放和位置,而非整个scene model.scale.set(4.2, 4.2, 4.2); model.position.y = 0; // 这里之前的Math.PI/8被覆盖了,按需调整 scene.add(model); }, undefined, function (error) { console.error(error); });
5. 初始渲染时机问题
模型加载完成后,虽然animate循环会持续渲染,但可以在加载回调里触发一次渲染确保模型显示:
loader.load('...', function(gltf) { // ... 其他代码 renderer.render(scene, camera); });
完整修正后的JS代码示例
import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.129.0/build/three.module.js'; import { GLTFLoader } from 'https://cdn.jsdelivr.net/npm/three@0.129.0/examples/jsm/loaders/GLTFLoader.js'; // Setup const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer({ canvas: document.querySelector('#bg'), }); renderer.setPixelRatio(window.devicePixelRatio * 2); renderer.setSize(window.innerWidth, window.innerHeight); camera.position.setZ(45); camera.position.setX(0); camera.position.setY(7); // Lights const pointLight = new THREE.PointLight(0xffffff); pointLight.position.set(5, 5, 5); const ambientLight = new THREE.AmbientLight(0xffffff); scene.add(pointLight, ambientLight); // Background scene.background = new THREE.Color(0xffffff); // Load Model let loadedModel; const loader = new GLTFLoader(); loader.load('https://cdn.shopify.com/s/files/1/0551/2708/1111/files/taiyo_shiny.gltf?v=1662981628', function (gltf) { loadedModel = gltf; const model = gltf.scene; model.scale.set(4.2, 4.2, 4.2); model.position.y = 0; scene.add(model); // 加载完成后立即渲染一次 renderer.render(scene, camera); }, undefined, function (error) { console.error(error); }); // Resize Listener window.addEventListener('resize', onWindowResize, false); function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } // Animation Loop function animate() { requestAnimationFrame(animate); if (loadedModel && loadedModel.scene) { loadedModel.scene.rotation.y += 0.0075; } renderer.render(scene, camera); } animate();
内容的提问来源于stack exchange,提问作者sofus
相关产品推荐
相关产品推荐

