什么是导航立方体?
导航立方体是一个交互式的3D控件,它允许用户通过点击和拖动立方体的各个面来改变3D视图的方向。这是一种非常直观的方式,让用户能够轻松地在3D空间中导航。
创建导航立方体
下面是一个基本的步骤,说明如何使用Three.js创建一个导航立方体:
// 创建场景
var scene = new THREE.Scene();
// 创建相机
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// 创建渲染器
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xffffff); // set to white
document.body.appendChild(renderer.domElement);
// 创建立方体的几何体
var geometry = new THREE.BoxGeometry(1, 1, 1);
// 创建立方体的每个面的材质
const CANVAS_SIZE = 256;
var materials = [];
['上', '下', '左', '右', '前', '后'].forEach(function(text) {
// 创建一个canvas元素
var canvas = document.createElement('canvas');
canvas.width = CANVAS_SIZE;
canvas.height = CANVAS_SIZE;
// 获取canvas的2d绘图上下文
var context = canvas.getContext('2d');
// context.fillStyle = '#f0f0f0'; // 设置填充颜色为白色
context.fillStyle = '#f6fcff'; // 设置填充颜色为白色
context.fillRect(0, 0, canvas.width, canvas.height); // 填充整个canvas
// 在canvas上绘制文字
context.fillStyle = 'black'; // 将文字颜色改为红色
// context.font = 'bold 200px serif'; // 将文字大小改为96px
context.font = "bold 100px arial";
context.textAlign = 'center'; // 设置文字对齐方式为居中
context.textBaseline = 'middle'; // 设置文字基线为中线
context.fillText(text, canvas.width / 2, canvas.height / 2); // 将文字绘制在canvas的中心
// 创建一个纹理
// 使用canvas作为纹理
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
// 创建材质并添加到材质数组中
// var material = new THREE.MeshStandardMaterial({ map: texture, color: 0xa5e3ff, emissive: 0xeb780a }); // Set material color to white
// materials.push(material);
// 使用MeshStandardMaterial以支持高光效果
var material = new THREE.MeshStandardMaterial({ map: texture, color: 0xffffff, emissive: 0x000000 });
materials.push(material);
});
// 创建立方体
var cube = new THREE.Mesh(geometry, materials);
cube.position.set(-0.5, -0.5, -0.5); // Set the position to the corner of the cube
// scene.add(cube);
// 添加光源
var light = new THREE.AmbientLight(0xffffff);
scene.add(light);
// 添加平行光源
var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);
// 鼠标悬停高亮效果
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
function onMouseMove(event) {
// 计算鼠标位置的归一化设备坐标
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
// 通过相机和鼠标位置更新射线
raycaster.setFromCamera(mouse, camera);
// 计算物体和射线的交点
var intersects = raycaster.intersectObjects([cube]);
// 遍历交点,将相应面的材质高亮
for (var i = 0; i < materials.length; i++) {
materials[i].emissive.set(0x000000); // 清除之前的高亮
}
if (intersects.length > 0) {
var index = intersects[0].face.materialIndex;
materials[index].emissive.set("#eb780a"); // 设置高亮
}
}
function onClick(event) {
// 处理点击事件,你可以在这里添加你的逻辑
}
// 添加事件监听器
document.addEventListener('mousemove', onMouseMove, false);
document.addEventListener('click', onClick, false);
// 添加坐标系
var axesHelper = new THREE.AxesHelper(2);
axesHelper.position.copy(cube.position); // Set the position to match the cube
// scene.add(axesHelper);
// 创建一个包含立方体和坐标系的组
var group = new THREE.Group();
group.add(cube);
group.add(axesHelper);
scene.add(group);
// 渲染函数
function render() {
requestAnimationFrame(render);
group.rotation.x += 0.01;
group.rotation.y += 0.01;
renderer.render(scene, camera);
}
// 调用渲染函数
render();