Three.js,光线投射-将球体创建为超链接

时间:2018-11-08 12:16:38

标签: three.js raycasting

我想在球体上创建超链接,“行星”。链接将引用在index.html中创建的div,以创建上推式内容(就像您在本网站中单击汉堡包图标时一样) :http://serwer1814906.home.pl/LEM-01/lem_desktop.html)。因此,每个球体都会打开另一个div。

我已经使用raycaster创建了基本代码,以将球体地球作为到Three.js主页的超链接-但这是行不通的。您可以帮我编写适当的代码吗?

代码在这里(相当长,我制作了6个球体):

// --- cleaning console --- //
console.clear();

// --- threeJS --- //
var renderer, scene, camera, distance, raycaster, projector, labelRenderer;

var container = document.getElementById('container');

var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var distance = 400;


var clock = new THREE.Clock();
var textureLoader = new THREE.TextureLoader();

var earth, saturn, mars, jowish, mercury, jupiter, line;


init();
animate();



// -- basic initialization -- //
function init() {


    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.2, 25000);
    camera.position.set(100, 100, 2000);
    scene.add(camera);

    light = new THREE.PointLight(0xffffff, 1, 1000);
    light.position.set(150, 50, 100);
    light_two = new THREE.PointLight(0xffffff, 1, 1000);
    light_two.position.set(-100, 50, 500);
    light_three = new THREE.PointLight(0xffffff, 1, 1000);
    light_three.position.set(250, 800, 450);

    scene.add(light, light_two, light_three);

    createPlanet();



    var size = 10000, step = 70;

    var geometry = new THREE.Geometry();
    var material = new THREE.LineBasicMaterial({
        color: 0x404040,
        linewidth: 1
    });

    for ( var i = - size; i <= size; i += step){
        geometry.vertices.push(new THREE.Vector3( - size, - 0.04, i));
        geometry.vertices.push(new THREE.Vector3( size, - 0.04, i));

        geometry.vertices.push(new THREE.Vector3( i, - 0.04, - size));
        geometry.vertices.push(new THREE.Vector3( i, - 0.04, size));
    }

    var line = new THREE.Line( geometry, material, THREE.LinePieces);
    line.rotation.x = Math.PI / 2;
    scene.add(line);



    var curve = new THREE.SplineCurve( [
        new THREE.Vector2( -1000, -100 ),
        new THREE.Vector2( -500, -250 ),
        new THREE.Vector2( 10, -200 ),
        new THREE.Vector2( 50, -500 ),
        new THREE.Vector2( 1200, 0 )
    ] );

    var points = curve.getPoints( 500 );
    var geometry = new THREE.BufferGeometry().setFromPoints( points );

    var material = new THREE.LineBasicMaterial( { 
        color : 0xffffff,
        linewidth: 2
    } );

                // Create the final object to add to the scene
    var splineObject = new THREE.Line( geometry, material );
    scene.add(splineObject);

    var curve = new THREE.SplineCurve( [
        new THREE.Vector2( -1500, 800 ),
        new THREE.Vector2( -500, 300 ),
        new THREE.Vector2( 220, 450 ),
        new THREE.Vector2( 300, 300 ),
        new THREE.Vector2( 1100, 600 )
    ] );

    var points = curve.getPoints( 500 );
    var geometry = new THREE.BufferGeometry().setFromPoints( points );

    var material = new THREE.LineBasicMaterial( { 
        color : 0xffffff,
        linewidth : 2 
    } );

                // Create the final object to add to the scene
    var splineObject = new THREE.Line( geometry, material );
    scene.add(splineObject);


    renderer = new THREE.WebGLRenderer({
        antialias: true
    });
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColor(0x000, 1);
    container.appendChild(renderer.domElement);
    document.body.appendChild( renderer.domElement );


    labelRenderer = new THREE.CSS2DRenderer();
    labelRenderer.setSize( window.innerWidth, window.innerHeight );
    labelRenderer.domElement.style.position = 'absolute';
    labelRenderer.domElement.style.top = 0;
    document.body.appendChild( labelRenderer.domElement );


    renderer.render(scene, camera);

    document.addEventListener('mousemove', onMouseMove, false);
    window.addEventListener('resize', onWindowResize, false);
}


function createPlanet() {


            var EARTH_RADIUS = 2;
            var SATURN_RADIUS = 2.5;
            var MARS_RADIUS = 2;
            var JOWISH_RADIUS = 2;
            var MERCURY_RADIUS = 2.5;
            var JUPITER_RADIUS = 3;


            var earthGeometry = new THREE.SphereBufferGeometry( EARTH_RADIUS, 120, 120 );
            var earthMaterial = new THREE.MeshPhongMaterial( {
                    specular: 0x333333,
                    shininess: 50,
                    map: textureLoader.load( 'js/texture/planet2.jpg' ),
                    specularMap: textureLoader.load( 'js/texture/planet2.jpg' ),
                    normalMap: textureLoader.load( 'js/texture/planet2_NRM.png' ),
                    normalScale: new THREE.Vector2( 0.85, 0.85 )
                } );
            earth = new THREE.Mesh( earthGeometry, earthMaterial );
            earth.position.x = 320;
            earth.position.y = 500;
            earth.position.z = 200;
            earth.rotation.y = Math.random() * 2 * Math.PI;
            earth.scale.x = earth.scale.y = earth.scale.z = Math.random() * 50 + 10;
            earth.userData = { URL: "http://threejs.org"};

                scene.add( earth );


            var earthDiv = document.createElement( 'div' );
            earthDiv.className = 'label';
            earthDiv.textContent = '.Projekt-1';
            earthDiv.style.marginTop = '-1em';
            var earthLabel = new THREE.CSS2DObject( earthDiv );
            earthLabel.position.set( (EARTH_RADIUS + 2), 0, 0 );
            earth.add( earthLabel );


            var saturnGeometry = new THREE.SphereBufferGeometry( SATURN_RADIUS, 120, 120 );
            var saturnMaterial = new THREE.MeshPhongMaterial( {
                    specular: 0xffffff,
                    shininess: 5,
                    map: textureLoader.load( 'js/texture/planet4.jpg' ),
                    specularMap: textureLoader.load( 'js/texture/planet4.jpg' ),
                    normalMap: textureLoader.load( 'js/texture/planet2_NRM.png' ),
                    //normalScale: new THREE.Vector2( 0.85, 0.85 )
                } );
            saturn = new THREE.Mesh( saturnGeometry, saturnMaterial );
            saturn.position.x = 750;
            saturn.position.y = 450;
            saturn.position.z = 100;
            saturn.rotation.y = Math.random() * 2 * Math.PI;
            saturn.scale.x = saturn.scale.y = saturn.scale.z = Math.random() * 50 + 10;

                scene.add( saturn );


            var saturnDiv = document.createElement( 'div' );
            saturnDiv.className = 'label';
            saturnDiv.textContent = '.Projekt-2';
            saturnDiv.style.marginTop = '-1em';
            var saturnLabel = new THREE.CSS2DObject( saturnDiv );
            saturnLabel.position.set( 0, (SATURN_RADIUS + 0.5), 0 );
            saturn.add( saturnLabel );

            var marsGeometry = new THREE.SphereBufferGeometry( MARS_RADIUS, 120, 120 );
            var marsMaterial = new THREE.MeshPhongMaterial( {
                    specular: 0x333333,
                    shininess: 50,
                    map: textureLoader.load( 'js/texture/planet5.jpg' ),
                    specularMap: textureLoader.load( 'js/texture/planet2.jpg' ),
                    normalMap: textureLoader.load( 'js/texture/planet2_NRM.png' ),
                    //normalScale: new THREE.Vector2( 0.95, 0.85 )
                } );
            mars = new THREE.Mesh( marsGeometry, marsMaterial );
            mars.position.x = -350;
            mars.position.y = 250;
            mars.position.z = 100;
            mars.rotation.y = Math.random() * 2 * Math.PI;
            mars.scale.x = mars.scale.y = mars.scale.z = Math.random() * 50 + 10;

            scene.add( mars );


            var marsDiv = document.createElement( 'div' );
            marsDiv.className = 'label';
            marsDiv.textContent = '.Projekt-3';
            marsDiv.style.marginTop = '-1em';
            var marsLabel = new THREE.CSS2DObject( marsDiv );
            marsLabel.position.set( 0, (MARS_RADIUS + 0.5), 0 );
            mars.add( marsLabel );

            var jowishGeometry = new THREE.SphereBufferGeometry( JOWISH_RADIUS, 120, 120 );
            var jowishMaterial = new THREE.MeshPhongMaterial( {
                    specular: 0x333333,
                    shininess: 50,
                    map: textureLoader.load( 'js/texture/planet7.jpg' ),
                    specularMap: textureLoader.load( 'js/texture/planet2.jpg' ),
                    normalMap: textureLoader.load( 'js/texture/planet2_NRM.png' ),
                    //normalScale: new THREE.Vector2( 0.85, 0.85 )
                } );
            jowish = new THREE.Mesh( jowishGeometry, jowishMaterial );
            jowish.position.x = -600;
            jowish.position.y = -200;
            jowish.position.z = 100;
            jowish.rotation.y = Math.random() * 4 * Math.PI;
            jowish.scale.x = jowish.scale.y = jowish.scale.z = Math.random() * 50 + 10;

                scene.add( jowish );


            var jowishDiv = document.createElement( 'div' );
            jowishDiv.className = 'label';
            jowishDiv.textContent = '.Projekt-4';
            jowishDiv.style.marginTop = '-1em';
            var jowishLabel = new THREE.CSS2DObject( jowishDiv );
            jowishLabel.position.set( JOWISH_RADIUS, 2, 0 );
            jowish.add( jowishLabel );


            var mercuryGeometry = new THREE.SphereBufferGeometry( MERCURY_RADIUS, 120, 120 );
            var mercuryMaterial = new THREE.MeshPhongMaterial( {
                    specular: 0x333333,
                    shininess: 50,
                    map: textureLoader.load( 'js/texture/planet6.jpg' ),
                    specularMap: textureLoader.load( 'js/texture/planet2.jpg' ),
                    normalMap: textureLoader.load( 'js/texture/planet2_NRM.png' ),
                    normalScale: new THREE.Vector2( 0.85, 0.85 )
                } );
            mercury = new THREE.Mesh( mercuryGeometry, mercuryMaterial );
            mercury.position.x = 400;
            mercury.position.y = -500;
            mercury.position.z = 100;
            mercury.rotation.y = Math.random() * 2 * Math.PI;
            mercury.scale.x = mercury.scale.y = mercury.scale.z = Math.random() * 50 + 10;

                scene.add( mercury );


            var mercuryDiv = document.createElement( 'div' );
            mercuryDiv.className = 'label';
            mercuryDiv.textContent = '.Projekt-5';
            mercuryDiv.style.marginTop = '-1em';
            var mercuryLabel = new THREE.CSS2DObject( mercuryDiv );
            mercuryLabel.position.set( MERCURY_RADIUS, 2, 0 );
            mercury.add( mercuryLabel );

            var jupiterGeometry = new THREE.SphereBufferGeometry( JUPITER_RADIUS, 120, 120 );
            var jupiterMaterial = new THREE.MeshPhongMaterial( {
                    specular: 0x333333,
                    shininess: 50,
                    map: textureLoader.load( 'js/texture/planet8.jpg' ),
                    specularMap: textureLoader.load( 'js/texture/planet2.jpg' ),
                    normalMap: textureLoader.load( 'js/texture/planet2_NRM.png' ),
                    normalScale: new THREE.Vector2( 0.85, 0.85 )
                } );
            jupiter = new THREE.Mesh( jupiterGeometry, jupiterMaterial );
            jupiter.position.x = 900;
            jupiter.position.y = -180;
            jupiter.position.z = 50;
            jupiter.rotation.y = Math.random() * 2 * Math.PI;
            jupiter.scale.x = jupiter.scale.y = jupiter.scale.z = Math.random() * 50 + 10;
            jupiter.userData = { URL: "http://stackoverflow.com"};
            scene.add( jupiter );


            var jupiterDiv = document.createElement( 'div' );
            jupiterDiv.className = 'label';
            jupiterDiv.textContent = '.Projekt-6';
            jupiterDiv.style.marginTop = '-1em';
            var jupiterLabel = new THREE.CSS2DObject( jupiterDiv );
            jupiterLabel.position.set( JUPITER_RADIUS, 2, 0 );
            jupiter.add( jupiterLabel );



}



// -- events -- //
function onMouseMove(event) {

    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
    mouseX = event.clientX - window.innerWidth / 2;
    mouseY = event.clientY - window.innerHeight / 2;
    camera.position.x += (mouseX - camera.position.x) * 0.01;
    camera.position.y += (mouseY - camera.position.y) * 0.01;
    camera.lookAt(scene.position);

};

function onDocumentMouseDown(event) {
    event.preventDefault();
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

    raycaster.setFromCamera(mouse, camera);

    var intersects = raycaster.intersectObjects(earth);
    if (intersects.length > 0) {
    //get a link from the userData object
        window.open(intersects[0].object.userData.URL);
    }
};


function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    renderer.setSize(window.innerWidth, window.innerHeight);
    labelRenderer.setSize( window.innerWidth, window.innerHeight );
    camera.updateProjectionMatrix();
};


// ---- //
function animate() {
    requestAnimationFrame(animate);
    var elapsed = clock.getElapsedTime();
    render();
};



// -- render all -- //
function render() {

    var timer = 0.00001 * Date.now();

    earth.rotation.z += Math.PI / 500;
    saturn.rotation.y += Math.PI / 500;
    mars.rotation.y += Math.PI / 500;
    jowish.rotation.z += Math.PI / 500;
    mercury.rotation.z += Math.PI / 500;
    jupiter.rotation.z += Math.PI / 700;



    renderer.render(scene, camera);
    labelRenderer.render( scene, camera );


};

0 个答案:

没有答案