我正在帮助一个朋友在运行Lay主题的Wordpress中的页面上设置Three.js场景。主题使用的是一种页面过渡脚本,该脚本在导航到其他页面时不会重新加载网站,每次在网站上注入新页面时都会对Three.js场景进行新的初始化。
我正在寻找在加载新页面时完全删除Three.js整个实例的方法。因此,当The Lay主题具有此功能window.laytheme.on("newpageshown", function(layoutObj, type, obj){}
时,它便可以从头开始创建,可以代替window.onload
。
我尝试了各种方法来删除所有内容,但是不幸的是,由于我的Three.js代码是来自不同演示和示例的复制和粘贴的混合结果,因此我不确定到底需要销毁什么以及如何做。老实说,我不确定代码的设置方式,而且我对Three.js及其生命周期的经验很少。
以下是创建场景的代码:
(function($) {
var base_url = window.location.origin;
var container, stats;
var camera, scene, renderer, controls, manager, loader, texture;
var mouseX = 0,
mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var $currentModel;
var modelName;
var initialGridPosition;
var initialScale;
window.laytheme.on("newpageshown", function(layoutObj, type, obj){
modelName = $(".modelLink.is-active").data("model-name");
initialScale = $(".modelLink.is-active").data("model-scale");
initialGridPosition = $(".modelLink.is-active").data("model-grid-position");
init();
animate();
});
function init() {
container = document.createElement('div');
container.id = "threejs-container";
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.z = 300;
camera.position.y = 100;
// scene
scene = new THREE.Scene();
var ambientLight = new THREE.AmbientLight(0xffffff, 0.7);
scene.add(ambientLight);
var pointLight = new THREE.PointLight( 0xffffff, 0.3 );
camera.add( pointLight );
scene.add(camera);
// model
var onProgress = function(xhr) {
if (xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
$("#domLoader").show();
$("#domLoader").text(Math.round(percentComplete, 2) + '%');
}
};
// texture
manager = new THREE.LoadingManager();
manager.onProgress = function(item, loaded, total) {
if (total == loaded) {
$("#domLoader").hide();
$(".col--row").removeClass("is-hidden");
$currentModel = $(".modelLink.is-active");
$("#meta-title").text('stevns_klint_' + $currentModel.data("model-name"));
$("#meta-vertices").text($currentModel.data("model-vertices"));
$("#meta-faces").text($currentModel.data("model-faces"));
$("#meta-coordinates").text($currentModel.data("model-coordinates"));
$("#meta-coordinates-url").attr("href", $currentModel.data("model-coordinates-url"));
$("#meta-date").text($currentModel.data("model-date"));
$("#meta-images").text($currentModel.data("model-images"));
}
console.log(item, loaded, total);
};
texture = new THREE.Texture();
var onProgress = function(xhr) {
if (xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log(Math.round(percentComplete, 2) + '% downloaded');
$("#domLoader").show();
$("#domLoader").text(Math.round(percentComplete, 2) + '%');
}
};
var onError = function() {};
// Create initial model
loader = new THREE.ImageLoader(manager)
loader.setPath(base_url + '/assets/' + modelName +'/').load('texture.jpg', function(image) {
texture.image = image;
texture.needsUpdate = true;
});
loader = new THREE.OBJLoader(manager);
loader.setPath(base_url + '/assets/' + modelName +'/').load('model.obj', function(object) {
object.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.map = texture;
}
if( child.material ) {
child.material.side = THREE.DoubleSide;
}
});
object.scale.x = initialScale;
object.scale.y = initialScale;
object.scale.z = initialScale;
object.name = "mainModel";
scene.add(object);
}, onProgress, onError);
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xffffff, 1);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
var size = 300;
var divisions = 30;
var gridHelper = new THREE.GridHelper( size, divisions, 0x000000, 0x000000 );
scene.add( gridHelper );
gridHelper.position.y = initialGridPosition;
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.screenSpacePanning = true;
controls.minDistance = 150;
controls.maxDistance = 300;
controls.target.set(0, 0, 0);
controls.enableDamping = true;
controls.enablePan = false;
controls.autoRotate = true;
controls.enableKeys = false;
controls.autoRotateSpeed = 0.04;
controls.dampingFactor = 0.07;
controls.rotateSpeed = 0.04;
controls.update();
window.addEventListener('resize', onWindowResize, false);
// Change model on model link click
$(".modelLink").on("click", function(){
$(".modelLink").removeClass("is-active");
$(this).addClass("is-active");
$(".col--row").addClass("is-hidden");
var modelName = $(this).data("model-name");
var modelScale = Number($(this).data("model-scale"));
var modelGridPosition = $(this).data("model-grid-position");
loader = new THREE.ImageLoader(manager)
loader.setPath(base_url + '/assets/' + modelName +'/').load('texture.jpg', function(image) {
texture.image = image;
texture.needsUpdate = true;
});
loader = new THREE.OBJLoader(manager);
loader.setPath(base_url + '/assets/' + modelName + '/').load('model.obj', function(object) {
object.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.map = texture;
}
if( child.material ) {
child.material.side = THREE.DoubleSide;
}
});
object.scale.x = modelScale;
object.scale.y = modelScale;
object.scale.z = modelScale;
var selectedObject = scene.getObjectByName("mainModel");
scene.remove( selectedObject );
object.name = "mainModel";
gridHelper.position.y = modelGridPosition;
scene.add(object);
}, onProgress, onError);
})
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
controls.update();
render();
}
function render() {
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
})( jQuery );
其中的代码可能与其中无关,并且与Three.js无关。但是如果有人对Three.js的结构和生命周期有更丰富的经验,可以帮助我通读脚本并告诉我与Three.js相关的代码的哪些部分需要删除以及如何完成,我将不胜感激。