可点击的三个JS凸对象(点击一次即可显示图像)

Clickable Three JS Convex Objects (once clicked reveals image)

本文关键字:一次 显示图 图像 显示 JS 三个 对象      更新时间:2024-06-02

我从三个js网站中调整了一个例子。

我正在寻找使小的浮动对象有一个点击事件。

点击事件将触发显示在中心中较大凸起形状上的图像或视频

概念+图像

http://kevinwitkowski.tumblr.com/post/109592122645/workshop-update

工作样品

这是我当前的代码。

            var container;
        var camera, scene, renderer;
        var mesh;
        var mouseX = 0, mouseY = 0;
        var windowHalfX = window.innerWidth / 2;
        var windowHalfY = window.innerHeight / 2;
        // array of functions for the rendering loop
        var onRenderFcts= [];
        init();
        animate();
        function init() {
            container = document.createElement( 'div' );
            document.body.appendChild( container );
            scene = new THREE.Scene();
            scene.fog = new THREE.FogExp2( 0xd6e3e8, 0.0030 );
            camera  = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 1000);
            camera.position.z = 0;
            controls    = new THREE.OrbitControls(camera)


            var light, object, materials;
            light = new THREE.DirectionalLight( 0xe8dbd6 );
            light.position.set( -50, -80, -10 );
            scene.add( light );
            light = new THREE.DirectionalLight( 0xd6dae8 );
            light.position.set( 20, 120, 1 );
            scene.add( light );
            light = new THREE.DirectionalLight( 0xd6e8e4 );
            light.position.set( 0, 1, 30 );
            scene.add( light );
            var map = THREE.ImageUtils.loadTexture( 'textures/1.jpeg' );
            map.wrapS = map.wrapT = 
            THREE.RepeatWrapping;
            map.anisotropy = 16;
            var materials = [
                new THREE.MeshLambertMaterial( { color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors } )
                //new THREE.MeshBasicMaterial( { color: 0x00000, shading: THREE.FlatShading, wireframe: true, transparent: false, opacity: 0.5} )
            ];

            // random convex 1
            points = [];
            for ( var i = 0; i < 30; i ++ ) {
                points.push( randomPointInSphere( 50 ) );
            }
            object = THREE.SceneUtils.createMultiMaterialObject( new THREE.ConvexGeometry( points ), materials );
            object.position.set( 0, 0, 0);
            scene.add( object );
            // random convex 2
            points = [];
            for ( var i = 0; i < 30; i ++ ) {
                points.push( randomPointInSphere( 15 ) );
            }
            object = THREE.SceneUtils.createMultiMaterialObject( new THREE.ConvexGeometry( points ), materials );
            object.position.set( 15, 50, -60 );
            scene.add( object );

            // random convex 3
            points = [];
            for ( var i = 0; i < 30; i ++ ) {
                points.push( randomPointInSphere( 15 ) );
            }
            object = THREE.SceneUtils.createMultiMaterialObject( new THREE.ConvexGeometry( points ), materials );
            object.position.set( 30, 10, 80 );
            scene.add( object );
            // random convex 4
            points = [];
            for ( var i = 0; i < 30; i ++ ) {
                points.push( randomPointInSphere( 8 ) );
            }
            object = THREE.SceneUtils.createMultiMaterialObject( new THREE.ConvexGeometry( points ), materials );
            object.position.set( -80, -50, 20 );
            scene.add( object );

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

            //


            window.addEventListener( 'resize', onWindowResize, true );
        }
        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize( window.innerWidth, window.innerHeight );
        }
        function onDocumentMouseMove( event ) {
            mouseX = ( event.clientX - windowHalfX );
            mouseY = ( event.clientY - windowHalfY );
        }
        //
        function randomPointInSphere( radius ) {
            return new THREE.Vector3(
                ( Math.random() - 0.5 ) * 1 * radius,
                ( Math.random() - 0.5 ) * 2 * radius,
                ( Math.random() - 0.5 ) * 2 * radius
            );
        }
        function animate() {
            requestAnimationFrame( animate );
            render();

        }
        function render() {
            var timer = Date.now() * 0.00005;
            camera.position.x = Math.cos( timer ) * 300;
            camera.position.z = Math.sin( timer ) * 300;
            camera.lookAt( scene.position );
            for ( var i = 0, l = scene.children.length; i < l; i ++ ) {
                var object = scene.children[ i ];
                object.rotation.x = timer * 1;
                object.rotation.y = timer * 3;
            }
            // handle window resize
    window.addEventListener('resize', function(){
    renderer.setSize( window.innerWidth, window.innerHeight )
    camera.aspect   = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()     
    }, true)

            renderer.render( scene, camera );
        }
var lastTimeMsec= null
requestAnimationFrame(function animate(nowMsec){
    // keep looping
    requestAnimationFrame( animate );
    // measure time
    lastTimeMsec    = lastTimeMsec || nowMsec-1000/60
    var deltaMsec   = Math.min(200, nowMsec - lastTimeMsec)
    lastTimeMsec    = nowMsec
    // call each update function
    onRenderFcts.forEach(function(onRenderFct){
        onRenderFct(deltaMsec/1000, nowMsec/1000)
    })
})

通常的方法是使用THREE.Raycaster和THREE.Projector从相机向太空投射光线,然后查找对象是否与该光线相交。

请参见此示例:http://soledadpenades.com/articles/three-js-tutorials/object-picking/

值得庆幸的是,其他人已经实现了ObjectControls等库:https://github.com/cabbibo/ObjectControls

这允许您直接将悬停或选择事件附加到网格,这样就可以正常工作了。

CreateMultiMaterialObject方法创建一个object3D,因此当您单击时,需要指定第二个参数(recursion)=true:

var intersects = raycaster.intersectObjects( objects, true );
if ( intersects.length > 0 ) {
    intersects[ 0 ].object.material.color.setHex( Math.random() * 0xffffff );
}