如何使三个 JS 中的 TextGeometry 跟随鼠标?
How to make TextGeometry in THREE JS follow mouse?
这是我的源代码。我正在尝试使文本根据鼠标位置旋转。
// Initialization
const scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
let renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
let body = document.getElementsByTagName("body");
let pageX = 0.5;
let pageY = 0.5;
renderer.setSize( window.innerWidth, window.innerHeight );
document.getElementById("board").appendChild(renderer.domElement);
// Handle resize event
window.addEventListener('resize', () => {
renderer.setSize( window.innerWidth, window.innerHeight );
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});
camera.position.z = 20;
// Create light
let directLight = new THREE.DirectionalLight('#fff', 4);
directLight.position.set(0, 7, 5);
scene.add(directLight);
var light = new THREE.AmbientLight( 0x404040 ); // soft white light
scene.add( light );
function animate (){
requestAnimationFrame( animate );
var loader = new THREE.FontLoader();
loader.load( 'https://threejs.org/examples/fonts/helvetiker_regular.typeface.json', function ( font ) {
var geometry = new THREE.TextGeometry( 'Hello three.js!', {
font: font,
size: 3,
height: 0.5,
curveSegments: 4,
bevelEnabled: true,
bevelThickness: 0.02,
bevelSize: 0.05,
bevelSegments: 3
} );
geometry.center();
var material = new THREE.MeshPhongMaterial(
{ color: '#dbe4eb', specular: '#dbe4eb' }
);
var mesh = new THREE.Mesh( geometry, material );
mesh.rotation.x = (pageY - 0.5) * 2;
mesh.rotation.y = (pageX - 0.5) * 2;
scene.add( mesh );
} );
renderer.render(scene, camera);
}
animate();
// Get mouse coordinates inside the browser
document.body.addEventListener('mousemove', (event) => {
pageX = event.pageX / window.innerWidth;
pageY = event.pageY / window.innerHeight;
});
renderer.render(scene, camera);
</script>
这是我能得到的最好的。问题是每次我移动鼠标时,它都会实例化一个新的网格并相应地旋转它,而我只需要一个网格来跟随鼠标。谁能帮忙?
提前致谢!
正如您已经知道的那样,您每次都在重新加载字体并最终重新创建网格。
要解决这个问题,您需要将字体加载和对象创建移动到一些初始化函数中,这样它只会发生一次。
您希望保留在渲染循环中的唯一部分代码是根据鼠标移动更新文本的旋转:
mesh.rotation.x = (pageY - 0.5) * 2;
mesh.rotation.y = (pageX - 0.5) * 2;
但这会带来另一个问题。由于 mesh
是在字体加载器的回调函数中定义的本地对象,因此外部无法访问它。幸运的是 three.js 提供了一个名为 .name 的 属性,您可以使用它来为您的对象命名。
例如
var mesh = new THREE.Mesh(geometry, material);
mesh.name = "myText";
scene.add(mesh);
稍后您可以使用以下方法获取对此对象的引用:
scene.getObjectByName("myText")
这是一个例子:
var container, scene, camera, renderer, pageX, pageY;
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
pageX = 0.5;
pageY = 0.5;
renderer.setSize(window.innerWidth, window.innerHeight);
document.getElementById("container").appendChild(renderer.domElement);
window.addEventListener('resize', () => {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});
camera.position.z = 20;
let directLight = new THREE.DirectionalLight('#fff', 4);
directLight.position.set(0, 7, 5);
scene.add(directLight);
var light = new THREE.AmbientLight(0x404040); // soft white light
scene.add(light);
var loader = new THREE.FontLoader();
loader.load('https://threejs.org/examples/fonts/helvetiker_regular.typeface.json', function(font) {
var geometry = new THREE.TextGeometry('Hello three.js!', {
font: font,
size: 3,
height: 0.5,
curveSegments: 4,
bevelEnabled: true,
bevelThickness: 0.02,
bevelSize: 0.05,
bevelSegments: 3
});
geometry.center();
var material = new THREE.MeshPhongMaterial({
color: '#dbe4eb',
specular: '#dbe4eb'
});
var mesh = new THREE.Mesh(geometry, material);
mesh.name = "myText";
scene.add(mesh);
animate();
});
document.body.addEventListener('mousemove', (event) => {
pageX = event.pageX / window.innerWidth;
pageY = event.pageY / window.innerHeight;
});
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
scene.getObjectByName("myText").rotation.x = (pageY - 0.5) * 2;
scene.getObjectByName("myText").rotation.y = (pageX - 0.5) * 2;
renderer.render(scene, camera);
}
init();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r120/three.min.js"></script>
<div id="container"></div>
这是我的源代码。我正在尝试使文本根据鼠标位置旋转。
// Initialization
const scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
let renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
let body = document.getElementsByTagName("body");
let pageX = 0.5;
let pageY = 0.5;
renderer.setSize( window.innerWidth, window.innerHeight );
document.getElementById("board").appendChild(renderer.domElement);
// Handle resize event
window.addEventListener('resize', () => {
renderer.setSize( window.innerWidth, window.innerHeight );
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});
camera.position.z = 20;
// Create light
let directLight = new THREE.DirectionalLight('#fff', 4);
directLight.position.set(0, 7, 5);
scene.add(directLight);
var light = new THREE.AmbientLight( 0x404040 ); // soft white light
scene.add( light );
function animate (){
requestAnimationFrame( animate );
var loader = new THREE.FontLoader();
loader.load( 'https://threejs.org/examples/fonts/helvetiker_regular.typeface.json', function ( font ) {
var geometry = new THREE.TextGeometry( 'Hello three.js!', {
font: font,
size: 3,
height: 0.5,
curveSegments: 4,
bevelEnabled: true,
bevelThickness: 0.02,
bevelSize: 0.05,
bevelSegments: 3
} );
geometry.center();
var material = new THREE.MeshPhongMaterial(
{ color: '#dbe4eb', specular: '#dbe4eb' }
);
var mesh = new THREE.Mesh( geometry, material );
mesh.rotation.x = (pageY - 0.5) * 2;
mesh.rotation.y = (pageX - 0.5) * 2;
scene.add( mesh );
} );
renderer.render(scene, camera);
}
animate();
// Get mouse coordinates inside the browser
document.body.addEventListener('mousemove', (event) => {
pageX = event.pageX / window.innerWidth;
pageY = event.pageY / window.innerHeight;
});
renderer.render(scene, camera);
</script>
这是我能得到的最好的。问题是每次我移动鼠标时,它都会实例化一个新的网格并相应地旋转它,而我只需要一个网格来跟随鼠标。谁能帮忙? 提前致谢!
正如您已经知道的那样,您每次都在重新加载字体并最终重新创建网格。
要解决这个问题,您需要将字体加载和对象创建移动到一些初始化函数中,这样它只会发生一次。
您希望保留在渲染循环中的唯一部分代码是根据鼠标移动更新文本的旋转:
mesh.rotation.x = (pageY - 0.5) * 2;
mesh.rotation.y = (pageX - 0.5) * 2;
但这会带来另一个问题。由于 mesh
是在字体加载器的回调函数中定义的本地对象,因此外部无法访问它。幸运的是 three.js 提供了一个名为 .name 的 属性,您可以使用它来为您的对象命名。
例如
var mesh = new THREE.Mesh(geometry, material);
mesh.name = "myText";
scene.add(mesh);
稍后您可以使用以下方法获取对此对象的引用:
scene.getObjectByName("myText")
这是一个例子:
var container, scene, camera, renderer, pageX, pageY;
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
pageX = 0.5;
pageY = 0.5;
renderer.setSize(window.innerWidth, window.innerHeight);
document.getElementById("container").appendChild(renderer.domElement);
window.addEventListener('resize', () => {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});
camera.position.z = 20;
let directLight = new THREE.DirectionalLight('#fff', 4);
directLight.position.set(0, 7, 5);
scene.add(directLight);
var light = new THREE.AmbientLight(0x404040); // soft white light
scene.add(light);
var loader = new THREE.FontLoader();
loader.load('https://threejs.org/examples/fonts/helvetiker_regular.typeface.json', function(font) {
var geometry = new THREE.TextGeometry('Hello three.js!', {
font: font,
size: 3,
height: 0.5,
curveSegments: 4,
bevelEnabled: true,
bevelThickness: 0.02,
bevelSize: 0.05,
bevelSegments: 3
});
geometry.center();
var material = new THREE.MeshPhongMaterial({
color: '#dbe4eb',
specular: '#dbe4eb'
});
var mesh = new THREE.Mesh(geometry, material);
mesh.name = "myText";
scene.add(mesh);
animate();
});
document.body.addEventListener('mousemove', (event) => {
pageX = event.pageX / window.innerWidth;
pageY = event.pageY / window.innerHeight;
});
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
scene.getObjectByName("myText").rotation.x = (pageY - 0.5) * 2;
scene.getObjectByName("myText").rotation.y = (pageX - 0.5) * 2;
renderer.render(scene, camera);
}
init();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r120/three.min.js"></script>
<div id="container"></div>