three.js 9 控制 - DragControls

import * as THREE from 'three';
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { DragControls } from "three/examples/jsm/controls/DragControls";

/**
 * 3d Controls 控制器,拖放
 * https://threejs.org/docs/index.html#examples/zh/controls/DragControls
 */
export class ThreeDoc9ControlDrag {
    constructor(canvasId) {
        this.work(canvasId);
    }

    work(canvasId) {
        // 创建 3d 场景
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0x9e9e9e);

        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        // 最后一步很重要,我们将renderer(渲染器)的dom元素(renderer.domElement)添加到我们的HTML文档中。这就是渲染器用来显示场景给我们看的<canvas>元素。
        document.body.appendChild(renderer.domElement);
        // 开启阴影
        renderer.shadowMap.enabled = true

        // AxesHelper  3个坐标轴的对象.
        this.addAxesHelper(scene);
        // 半球光(HemisphereLight)
        this.addHemisphereLight(scene);
        // 网格辅助对象
        let size = 20;
        const gridHelper = new THREE.GridHelper( size, 10 , 0x444444, 0xffffff);
        scene.add( gridHelper );


        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        // 设置相机位置
        camera.position.x = 5;
        camera.position.y = 6;
        camera.position.z = 15;
        camera.lookAt(0, 0, 0);

        // 添加控制器
        let orb = new OrbitControls(camera, document.body);
        orb.addEventListener('change', function () {
            renderer.render(scene, camera);
        });

        // 添加物体
        let geometry = new THREE.BoxGeometry(2, 2, 2);
        let material = new THREE.MeshStandardMaterial({ color: 0x049EF4 });
        let obj =  new THREE.Mesh(geometry, material);
        obj.position.set(0, 1, 0);
        scene.add(obj);
        let arr = [obj];
        // 拖拽控制器,将可拖拽的物体,以数组形式传入
        const controls = new DragControls(arr, camera, renderer.domElement);
        /**
         * 事件
         * dragstart : 当用户开始拖拽3D Objects时触发。
         * drag : 当用户拖拽3D Objects时触发。
         * dragend : 当用户开始完成3D Objects时触发。
         * hoveron: 当指针移动到一个3D Object或者其某个子级上时触发。
         * hoveroff : 当指针移出一个3D Object时触发。
         */
        controls.addEventListener('dragstart', function (event) {
            orb.enabled = false;
        });
        controls.addEventListener('drag', function (event) {
            event.object.material.emissive.set(0xaaaaaa);
            console.log(event);
            renderer.render(scene, camera);
        });
        controls.addEventListener('dragend', function (event) {
            orb.enabled = true;
            event.object.material.emissive.set(0x000000);
            renderer.render(scene, camera);
        });

        // 添加第二个物体
        let geometry2 = new THREE.SphereGeometry(1, 32, 16);
        let material2 = new THREE.MeshStandardMaterial({ color: 0x049EF4 });
        let obj2 =  new THREE.Mesh(geometry2, material2);
        obj2.position.set(5, 1, 5);
        scene.add(obj2);
        // 直接操作可拖拽对象的数组,即可添加。这也太方便了吧
        arr.push(obj2);

        /**
         * Methods
         * .activate () : undefined
         * 添加控制器的事件监听。
         * .deactivate () : undefined
         * 移除控制器的事件监听。
         * .dispose () : undefined
         * 若不再需要该控制器,则应当调用此函数。
         * .getObjects () : Array
         * Returns the array of draggable objects.
         * .getRaycaster () : Raycaster
         * Returns the internal Raycaster instance that is used for intersection tests.
         */

        renderer.render(scene, camera);
    }

    /**
     * AxesHelper
     * 用于简单模拟3个坐标轴的对象.
     * 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴.
     * AxesHelper( size : Number )
     * size -- (可选的) 表示代表轴的线段长度. 默认为 1.
     */
    addAxesHelper(scene) {
        const axesHelper = new THREE.AxesHelper(12);
        scene.add(axesHelper);
    }

    /**
     * 半球光(HemisphereLight) - 喜欢这个光
     * 光源直接放置于场景之上,光照颜色从天空光线颜色渐变到地面光线颜色。
     * 半球光不能投射阴影。
     *
     * HemisphereLight( skyColor : Integer, groundColor : Integer, intensity : Float )
     * skyColor - (可选参数) 天空中发出光线的颜色。 缺省值 0xffffff。
     * groundColor - (可选参数) 地面发出光线的颜色。 缺省值 0xffffff。
     * intensity - (可选参数) 光照强度。 缺省值 1。
     */
    addHemisphereLight(scene) {
        const light = new THREE.HemisphereLight(0xffffbb, 0x080820, 50);
        scene.add(light);
        light.position.set(0, -20, 0);
        // const helper = new THREE.HemisphereLightHelper(light, 3);
        // scene.add(helper);
    }
}

 

posted @ 2022-06-06 16:56  名字不好起啊  阅读(674)  评论(0编辑  收藏  举报