Three.js为3d场景添加2d图片&相机移动

import * as THREE from 'https://threejs.org/build/three.module.js';

import Stats from 'https://threejs.org/examples/jsm/libs/stats.module.js';

import { OrbitControls } from 'https://threejs.org/examples/jsm/controls/OrbitControls.js';
import { FBXLoader } from 'https://threejs.org/examples/jsm/loaders/FBXLoader.js';

import { CSS2DRenderer, CSS2DObject } from "https://threejs.org/examples/jsm/renderers/CSS2DRenderer.js"

var container, stats, controls, viewWidth, viewHeight;
var camera, scene, renderer, light, lookPos;
var labelRenderer;
var mouse, rayCaster;
var paddingLeft, paddingTop;
var clock = new THREE.Clock();

var mixer;

init();
animate();

function init() {

    container = document.getElementById('model');
    viewWidth = parseFloat(window.getComputedStyle(container, null).getPropertyValue('width'));
    viewHeight = parseFloat(window.getComputedStyle(container, null).getPropertyValue('height'));
    // viewWidth = parseFloat(window.getComputedStyle(container, null).getPropertyValue('width')) / window.devicePixelRatio;
    // viewHeight = parseFloat(window.getComputedStyle(container, null).getPropertyValue('height')) / window.devicePixelRatio;
    mouse = new THREE.Vector2();
    rayCaster = new THREE.Raycaster();


    camera = new THREE.PerspectiveCamera( 45, viewWidth / viewHeight, 1, 10000 );
    camera.position.set( 100, 200, 300);

    scene = new THREE.Scene();
   // scene.background = new THREE.Color( 0xa0a0a0 );
    scene.fog = new THREE.Fog( 0xa0a0a0, 200, 1000 );



    // scene.add( new CameraHelper( light.shadow.camera ) );

    // ground
    // var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2000, 2000 ), new THREE.MeshPhongMaterial( { color: 0x999999, depthWrite: false } ) );
    var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2000, 2000 ), new THREE.MeshPhongMaterial( { color: null, depthWrite: false } ) );
    mesh.rotation.x = - Math.PI / 2;
    mesh.receiveShadow = true;
    //scene.add( mesh );

    //网格线
    // var grid = new THREE.GridHelper( 2000, 20, 0x000000, 0x000000 );
    // grid.material.opacity = 0.2;
    // grid.material.transparent = true;
    // scene.add( grid );




    // model
    var loader = new FBXLoader();
    loader.load( 'uv.fbx', function ( object ) {

        //播放动画
        //  mixer = new THREE.AnimationMixer( object );
        //  var action = mixer.clipAction( object.animations[ 0 ] );
        //  action.play();
        //渲染阴影
        // object.traverse( function ( child ) {
        //
        //     if ( child.isMesh ) {
        //
        //         child.castShadow = true;
        //         child.receiveShadow = true;
        //
        //     }
        //
        // } );
        object.scale.set(0.01,0.01,0.01);//修改模型缩放系数(x,y,z)
        object.name = "object";
        scene.add( object );



    } );








    light = new THREE.HemisphereLight( 0xffffff, 0x444444 );
    light.position.set( 0, 200, 0 );
    scene.add( light );

    light = new THREE.DirectionalLight( 0xffffff );
    light.position.set( 0, 200, 100 );
    light.castShadow = true;
    light.shadow.camera.top = 180;
    light.shadow.camera.bottom = - 100;
    light.shadow.camera.left = - 120;
    light.shadow.camera.right = 120;
    scene.add( light );




//场景指定位置添加2d图片
    var sbcs = document.getElementById('sbcs');
    var ckObject = new CSS2DObject(sbcs);
    ckObject.position.x = 0;
    ckObject.position.y = 50;
    ckObject.position.z = 0;
    scene.add(ckObject);
     labelRenderer = new CSS2DRenderer();
     labelRenderer.setSize(viewWidth, viewHeight);
     labelRenderer.domElement.style.position = 'absolute';
     container.appendChild(labelRenderer.domElement);



    renderer = new THREE.WebGLRenderer( { antialias: true, alpha:true } );
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize( viewWidth, viewHeight );
    renderer.shadowMap.enabled = true;
    container.appendChild( renderer.domElement );


    controls = new OrbitControls( camera, container );

    controls.update();
    calculateGap();
    window.addEventListener( 'resize', onWindowResize, false );
     container.addEventListener('dblclick', onDocumentMouseDown, false);
     container.addEventListener('touchstart', onDocumentTouchStart, false);
    // stats 显示帧数(以及画面渲染时间)
    // stats = new Stats();
    // container.appendChild( stats.dom );




}

//窗口大小改变
function onWindowResize() {


    viewWidth = parseFloat(window.getComputedStyle(container, null).getPropertyValue('width'));
    viewHeight = parseFloat(window.getComputedStyle(container, null).getPropertyValue('height'));

    camera.aspect = viewWidth / viewHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(viewWidth, viewHeight);
     labelRenderer.setSize(viewWidth, viewHeight);




    camera.aspect = viewWidth / viewHeight;
     camera.updateProjectionMatrix();

    renderer.setSize( viewWidth, viewHeight );


}



/**
 * 全屏
 * @param event
 */
function fullScreen(event) {

    var docElm = document.documentElement;
    if (docElm.requestFullscreen) {
        docElm.requestFullscreen();
    } else if (docElm.msRequestFullscreen) {
        docElm.msRequestFullscreen();
    } else if (docElm.mozRequestFullScreen) {
        docElm.mozRequestFullScreen();
    } else if (docElm.webkitRequestFullScreen) {
        docElm.webkitRequestFullScreen();
    }
}
//
/**
 * 计算边距
 */
function calculateGap() {
    var parent = renderer.domElement;
    paddingLeft = 0;
    while (parent) {

        paddingLeft += parseFloat(window.getComputedStyle(parent, null).getPropertyValue("padding-left"));
        parent = parent.parentElement;
    }
    paddingTop = $('#model').offset().top;
}

/**
 * 触摸事件
 * @param event
 */
function onDocumentTouchStart(event) {

    event.preventDefault();

    event.clientX = event.touches[0].clientX;
    event.clientY = event.touches[0].clientY;
    onDocumentMouseDown(event);
}

/**
 * 双击鼠标,将鼠标双击模型位置置于canvas中间显示
 * @param event
 */
function onDocumentMouseDown(event) {

    if (event.which == 1) {

        event.preventDefault();
        mouse.x = ((event.clientX - paddingLeft) / viewWidth) * 2 - 1;
        mouse.y = -((event.clientY - paddingTop) / viewHeight) * 2 + 1;

        //发射射线,返回与之相交的像素点数组
        rayCaster.setFromCamera(mouse, camera);
        var intersects = rayCaster.intersectObjects(scene.getObjectByName('object').children, true);

        if (intersects.length > 0) {
            //var object    = intersects[0].object;
            var position = intersects[0].point;//第一个是距离最近的一个像素点位置
            var toPz = (position.z > 0) ? position.z + 300 : position.z - 300;

            //new TWEEN.Tween(controls.target).to({x: position.x, y: position.y, z: position.z}, 3000).delay(500).start();
            //过渡动画调整相机位置
            new TWEEN.Tween({px: camera.position.x, py: camera.position.y, pz: camera.position.z}).to({
                px: position.x*3,
                py: position.y*3,
                pz: position.z*3
            }, 3000).onUpdate(function () {
                camera.position.x = this.px;
                camera.position.y = this.py;
                camera.position.z = this.pz;
                camera.updateProjectionMatrix();
            }).onComplete(function () {

            }).delay(500).start();
        }
    }
}


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


    // if (mixers.length > 0) {
    //     for (var i = 0; i < mixers.length; i++) {
    //         mixers[i].update(clock.getDelta() * 0.2);
    //     }
    // }

    requestAnimationFrame(animate);
    TWEEN.update();
    controls.update();

    render();

    // requestAnimationFrame( animate );
    //
    // var delta = clock.getDelta();
    //
    // if ( mixer ) mixer.update( delta );
    //
    // renderer.render( scene, camera );

    //stats.update();

}
//相机复位
document.getElementById('reset').onclick = function () {
    controls.reset();
}
//全屏
document.getElementById('full').onclick = function () {
    fullScreen();
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值