Patrzę na dwa przykłady, jeden to interaktywne obiekty na płótnie, a drugi to podpowiedź myszy. Próbowałem połączyć te dwa, aby wygenerować etykiety tekstowe na każdym pojedynczym sześcianie i oto, co mam do tej pory.Jak ustawić etykiety tekstowe w aparacie przez cały czas? Być może za pomocą duszków?
Tekst porusza się jednak z obracającymi się sześcianami, a tekst pojawia się czasem w tył lub w bok.
Jak mogę poprawić tekst w sprite'u, tak jak w przykładowej podpowiedzi myszy (http://stemkoski.github.io/Three.js/Mouse-Tooltip.html)? Próbowałem włączyć duszka, ale ciągle dostrzegałem błędy. Nie jestem pewien, jak to zrobić. Czy możesz wyjaśnić, jak mogę to zrobić?
Dzięki.
Oto mój kod do tej pory:
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js canvas - interactive - cubes</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="js/three.min.js"></script>
<script src="js/stats.min.js"></script>
<script>
var container, stats;
var camera, scene, projector, renderer;
var projector, mouse = { x: 0, y: 0 }, INTERSECTED;
var particleMaterial;
var currentLabel = null;
var objects = [];
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
var info = document.createElement('div');
info.style.position = 'absolute';
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.innerHTML = '<a href="http://threejs.org" target="_blank">three.js</a> - clickable objects';
container.appendChild(info);
camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 1, 10000);
camera.position.set(0, 300, 500);
scene = new THREE.Scene();
var geometry = new THREE.CubeGeometry(100, 100, 100);
for (var i = 0; i < 10; i ++) {
var object = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff, opacity: 0.5 }));
object.position.x = Math.random() * 800 - 400;
object.position.y = Math.random() * 800 - 400;
object.position.z = Math.random() * 800 - 400;
object.scale.x = Math.random() * 2 + 1;
object.scale.y = Math.random() * 2 + 1;
object.scale.z = Math.random() * 2 + 1;
object.rotation.x = Math.random() * 2 * Math.PI;
object.rotation.y = Math.random() * 2 * Math.PI;
object.rotation.z = Math.random() * 2 * Math.PI;
object.label = "Object " + i;
scene.add(object);
objects.push(object);
}
var PI2 = Math.PI * 2;
particleMaterial = new THREE.ParticleCanvasMaterial({
color: 0x000000,
program: function (context) {
context.beginPath();
context.arc(0, 0, 1, 0, PI2, true);
context.closePath();
context.fill();
}
});
projector = new THREE.Projector();
renderer = new THREE.CanvasRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild(stats.domElement);
document.addEventListener('mousedown', onDocumentMouseDown, false);
//
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
camera.aspect = window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onDocumentMouseDown(event) {
event.preventDefault();
var vector = new THREE.Vector3((event.clientX/window.innerWidth) * 2 - 1, - (event.clientY/window.innerHeight) * 2 + 1, 0.5);
projector.unprojectVector(vector, camera);
var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
var intersects = raycaster.intersectObjects(objects);
if (intersects.length > 0) {
if (intersects[ 0 ].object != INTERSECTED)
{
// restore previous intersection object (if it exists) to its original color
if (INTERSECTED) {
INTERSECTED.material.color.setHex(INTERSECTED.currentHex); }
// store reference to closest object as current intersection object
INTERSECTED = intersects[ 0 ].object;
// store color of closest object (for later restoration)
INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
// set a new color for closest object
INTERSECTED.material.color.setHex(0xffff00);
var canvas1 = document.createElement('canvas');
var context1 = canvas1.getContext('2d');
context1.font = "Bold 40px Arial";
context1.fillStyle = "rgba(255,0,0,0.95)";
context1.fillText(INTERSECTED.label, 0, 50);
// canvas contents will be used for a texture
var texture1 = new THREE.Texture(canvas1)
texture1.needsUpdate = true;
var material1 = new THREE.MeshBasicMaterial({map: texture1, side:THREE.DoubleSide });
material1.transparent = true;
var mesh1 = new THREE.Mesh(
new THREE.PlaneGeometry(canvas1.width, canvas1.height),
material1
);
mesh1.position = intersects[0].point;
if (currentLabel)
scene.remove(currentLabel);
scene.add(mesh1);
currentLabel = mesh1;
}
else // there are no intersections
{
// restore previous intersection object (if it exists) to its original color
if (INTERSECTED) {
console.log("hello");
INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
}
// remove previous intersection object reference
// by setting current intersection object to "nothing"
INTERSECTED = null;
mesh1 = null;
mesh1.position = intersects[0].point;
scene.add(mesh1);
}
//var particle = new THREE.Particle(particleMaterial);
//particle.position = intersects[ 0 ].point;
//particle.scale.x = particle.scale.y = 8;
//scene.add(particle);
}
/*
// Parse all the faces
for (var i in intersects) {
intersects[ i ].face.material[ 0 ].color.setHex(Math.random() * 0xffffff | 0x80000000);
}
*/
}
//
function animate() {
requestAnimationFrame(animate);
render();
stats.update();
}
var radius = 600;
var theta = 0;
function render() {
theta += 0.1;
camera.position.x = radius * Math.sin(THREE.Math.degToRad(theta));
camera.position.y = radius * Math.sin(THREE.Math.degToRad(theta));
camera.position.z = radius * Math.cos(THREE.Math.degToRad(theta));
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
</script>
</body>
To, co chcesz, nazywa się billboardem. Wierzę, że three.js ma je wbudowane – Dave
@Dave, czy istnieje przykład, który mogę śledzić? –