three.js 场景切换

查看场景切换效果

用6个面组成的立方体作为场景图,发现会出现变形的现象,css3DRenderer 不会变形,但是不方便增加文字,最后采用scene的背景作为场景,背景是用cubeTextureLoader()加载的。

完整代码

        <button id="btn1" class="btn btn-primary" style="margin-bottom:20px;">切换场景1</button>
        <button id="btn2" class="btn btn-warning" style="margin-bottom:20px;">切换场景2</button>
        <canvas id="canvas" width="64" height="64" style="display:none;"></canvas>
        <div class="canvasWrap" id="canvasWrap" style="margin-bottom:15px;"></div>
    <script src="../plugins/jQuery/jQuery-2.1.4.min.js"></script>
    <script src="../bootstrap/js/bootstrap.js"></script>
    <script src="../dist/js/three.js"></script>
    <script src="../dist/js/OrbitControls.js"></script>
    <script>
    var width, height;

    var renderer;

    function initRender() {
        width = document.getElementById('canvasWrap').clientWidth;
        height = document.getElementById('canvasWrap').clientHeight;
        renderer = new THREE.WebGLRenderer({ antialias: true });

        renderer.setSize(width, height);

        document.getElementById('canvasWrap').appendChild(renderer.domElement);

    }

    var camera;
    function initCamera() {

        camera = new THREE.PerspectiveCamera(75, width / height, 1, 1000);
        console.log(camera)
        camera.position.set(0, 0, 300);

    }

    var scene;
    function initScene() {
        scene = new THREE.Scene();
        //scene.background = new THREE.TextureLoader().load( '../textures/2294472375_24a3b8ef46_o.jpg' ) //scene不会跟着旋转
        scene.background = new THREE.CubeTextureLoader()
            .setPath('../dist/textures/cube/Bridge2/').load(
                [
                    'posx.jpg',
                    'negx.jpg',
                    'posy.jpg',
                    'negy.jpg',
                    'posz.jpg',
                    'negz.jpg'
                ]
            );
        console.log(scene)
    }

    var light;
    function initLight() {

        //scene.add(new THREE.AmbientLight(0x404040)); 

        scene.add(new THREE.AmbientLight(0xffffff));

        light = new THREE.DirectionalLight(0xffffff);

        //light.position.set(1,1,1); 
        light.position.set(0, 0, 50);
        scene.add(light);

    }

    var text = "first text";

    function showText() {
        const canvas = document.getElementById("canvas");
        const ctx = canvas.getContext("2d");
        ctx.canvas.width = 256;
        const x = 0;
        const y = 32;
        ctx.fillStyle = "red";
        ctx.font = "30px arial";
        ctx.textAlign = "left";
        ctx.textBaseline = "middle";
        ctx.fillText(text, x, y)
    }

    var sprite

    function showSprite() {
        showText()
        const canvasTexture = new THREE.CanvasTexture(
            document.querySelector("#canvas")
        )
        //canvasTexture.needsUpdate = true; //注意这句不能少
        const spritMaterial = new THREE.SpriteMaterial({
            map: canvasTexture
        })
        sprite = new THREE.Sprite(spritMaterial)
        sprite.position.set(-380, 100, 0);
        //精灵的默认大小很小估计是[1,1,1]
        sprite.scale.set(0.64 * 256, 0.64 * 64, 1);
        scene.add(sprite)
    }

    function initModel() {
        var texture1 = new THREE.TextureLoader().load('../dist/textures/cube/Bridge2/posx.jpg')
        var texture2 = new THREE.TextureLoader().load('../dist/textures/cube/Bridge2/negx.jpg')
        var texture3 = new THREE.TextureLoader().load('../dist/textures/cube/Bridge2/posy.jpg')
        var texture4 = new THREE.TextureLoader().load('../dist/textures/cube/Bridge2/negy.jpg')
        var texture5 = new THREE.TextureLoader().load('../dist/textures/cube/Bridge2/posz.jpg')
        var texture6 = new THREE.TextureLoader().load('../dist/textures/cube/Bridge2/negz.jpg')

        var materialArr = [
            //纹理对象赋值给6个材质对象
            new THREE.MeshBasicMaterial({ map: texture1, side: THREE.DoubleSide }),
            new THREE.MeshBasicMaterial({ map: texture2, side: THREE.DoubleSide }),
            new THREE.MeshBasicMaterial({ map: texture3, side: THREE.DoubleSide }),
            new THREE.MeshBasicMaterial({ map: texture4, side: THREE.DoubleSide }),
            new THREE.MeshBasicMaterial({ map: texture5, side: THREE.DoubleSide }),
            new THREE.MeshBasicMaterial({ map: texture6, side: THREE.DoubleSide })
        ];
        var boxGeometry = new THREE.BoxGeometry(200, 200, 200, 100, 100, 100);
        //boxGeometry.scale( -1, 1, 1 );
        var cube = new THREE.Mesh(boxGeometry, materialArr);
        // var cube = new THREE.Mesh(new THREE.SphereGeometry(50, 180, 120), material)  
        //new THREE.SphereGeometry(3, 18, 12)
        scene.add(cube);
    }

    //用户交互插件 鼠标左键按住旋转,右键按住平移,滚轮缩放 

    var controls;
    function initControls() {
        controls = new THREE.OrbitControls(camera, renderer.domElement);

        // 如果使用animate方法时,将此函数删除 

        //controls.addEventListener( 'change', render ); 

        // 使动画循环使用时阻尼或自转 意思是否有惯性 

        controls.enableDamping = true;

        //动态阻尼系数 就是鼠标拖拽旋转灵敏度 

        //controls.dampingFactor = 0.25; 

        //是否可以缩放 

        controls.enableZoom = true;

        //是否自动旋转 

        controls.autoRotate = false;

        //设置相机距离原点的最远距离 

        //controls.minDistance = 50; 

        //设置相机距离原点的最远距离 

        //controls.maxDistance =200; 

        //是否开启右键拖拽 

        controls.enablePan = true;
    }

    function render() {
        renderer.render(scene, camera);
    }

    //窗口变动触发的函数 
    function onWindowResize() {
        width = document.getElementById('canvasWrap').clientWidth;
        height = document.getElementById('canvasWrap').clientHeight;

        camera.aspect = width / height;

        camera.updateProjectionMatrix();

        render();

        renderer.setSize(width, height);
    }

    function animate() {

        //更新控制器 

        controls.update();

        render();

        requestAnimationFrame(animate);

    }


    function draw() {

        initRender();

        initScene();

        initCamera();

        //initLight()
        showSprite();

        initModel();

        initControls();

        animate();

        window.onresize = onWindowResize;
    }

    var btn = document.getElementById("btn1");
    btn.onclick = function() {
        console.log(scene)
        //scene.background = new THREE.Color( 0xff0000 )
        scene.background = new THREE.CubeTextureLoader()
            .setPath('../dist/textures/cube/Park2/').load(
                [
                    'posx.jpg',
                    'negx.jpg',
                    'posy.jpg',
                    'negy.jpg',
                    'posz.jpg',
                    'negz.jpg'
                ]
            );
    }

    var btn = document.getElementById("btn2");
    btn.onclick = function() {
        console.log(scene)
        //scene.background = new THREE.Color( 0xff0000 )
        scene.background = new THREE.CubeTextureLoader()
            .setPath('../dist/textures/cube/Bridge2/').load(
                [
                    'posx.jpg',
                    'negx.jpg',
                    'posy.jpg',
                    'negy.jpg',
                    'posz.jpg',
                    'negz.jpg'
                ]
            );
    }
    //MeshFaceMaterial 不加灯光会不显示,MeshBasicMaterial可以不用光线,MeshPhongMaterial一定要有光线,否则不显示
    </script>

如果点击文字的时候弹出对话框,需要用到Raycaster ,特别注意有多个精灵sprite的话,最好建一个组,把所有的精灵放进去

	var group = new THREE.Group();

	function showSprite1(){
	  scene.add(group);
	  showText()
	  const canvasTexture = new THREE.CanvasTexture(
	    document.querySelector("#canvas")
	  )
	  	const spritMaterial = new THREE.SpriteMaterial({
	    map:canvasTexture
	  })
	  sprite = new THREE.Sprite(spritMaterial)
	  sprite.position.set(-380,100,0);
	  //精灵的默认大小很小估计是[1,1,1]
	  sprite.scale.set(0.64*256,0.64*64,1);
	  sprite.name = "the first sprite";
	  group.add(sprite)
	
	}

关于事件交互的具体用法请见我另一篇博客

转载于:https://my.oschina.net/u/2612473/blog/3048051

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用Tween.js库来实现three.js中的动画效果。首先,你需要在HTML文件中引入Tween.js和three.js库。然后,你可以使用Tween.js的Tween类来创建一个动画对象,该对象可以控制three.js中的摄像机位置和旋转。在点击按钮时,你可以使用Tween.js的to()方法来设置摄像机的目标位置和旋转,然后使用start()方法来启动动画。以下是一个示例代码: ```javascript // 引入Tween.js和three.js库 import * as THREE from 'three'; import { Tween } from '@tweenjs/tween.js'; // 创建场景、摄像机和渲染器 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 创建一个立方体 const geometry = new THREE.BoxGeometry(); const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // 创建一个Tween对象 const tween = new Tween(camera.position) .to({ x: 0, y: 0, z: 5 }, 1000) .easing(TWEEN.Easing.Quadratic.InOut) .onUpdate(() => { camera.lookAt(scene.position); }); // 点击按钮时启动Tween动画 document.getElementById('button').addEventListener('click', () => { tween.start(); }); // 渲染场景 function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate(); ``` 在上面的代码中,我们创建了一个立方体和一个Tween对象。当点击按钮时,我们启动Tween动画,将摄像机的位置移动到(0, 0, 5)的位置,并使用Quadratic.InOut缓动函数使动画更加平滑。在动画更新时,我们使用camera.lookAt()方法来使摄像机始终朝向场景中心。最后,我们使用requestAnimationFrame()方法来循环渲染场景

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值