2.hook+ts+three 3d场景控制器与动画添加

290 阅读2分钟

3d场景控制器

1.引入依赖

import Orbitcontrols from 'three-orbitcontrols';

2.初始化控制器

//避坑:在初始化相机并加入场景后再初始化控制器

const initControls = () => {    controls=new Orbitcontrols(camera, renderer.domElement)    //controls.addEventListener('change', renderer);//不使用anime下使用    controls.enabled = true;// 鼠标控制是否可用    controls.enableRotate = true;//是否可旋转,旋转速度(鼠标左键)    controls.minDistance = 10;//最大最小相机移动距离(景深相机)    controls.maxDistance = 40;    controls.minPolarAngle = Math.PI / 180; //最大仰视角和俯视角   // 1度视角   //从z轴正上方开始计算角度    controls.maxPolarAngle = Math.PI / 2; // 90度视角    controls.enableDamping = true;//惯性滑动,滑动大小默认0.25    controls.dampingFactor = 0.5;    controls.enableZoom = true;//滚轮缩放控制    controls.zoomSpeed = 1.5;    controls.enablePan = true;//是否可平移,默认移动速度为7px    controls.panSpeed = 0.5;    //controls.minAzimuthAngle = -Math.PI/4;//水平方向视角限制    //controls.maxAzimuthAngle = Math.PI/4;    controls.autoRotate = true;// 是否自动旋转    controls.autoRotateSpeed = 0.05;  }

3.在anime中监听controls

const animate = () => {controls.update();}

3D场景动画

定义动画帧方法,将渲染器渲染方法放入其中,并调用requestAnimationFrame:

const animate = () => {    controls.update();    renderer.render(scene, camera);    requestAnimationFrame(animate);  }

完整代码:

import React, { useEffect, useRef } from 'react';import * as THREE from 'three'import Orbitcontrols from 'three-orbitcontrols';//react hookfunction Three() {  let width = 800, height = 600,    renderer: any = new THREE.WebGLRenderer({      antialias: true    }), // 创建一个渲染器(抗锯齿)    scene: any = new THREE.Scene(), // 初始化场景    camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000),  // 创建摄像机    axesHelper = new THREE.AxesHelper(30),//辅助线    controls:any,//控制器    mesh:any  const threeRef: any = useRef(null)  const initRenderer = () => {    renderer = new THREE.WebGLRenderer({      antialias: true    });    renderer.setSize(width, height);    threeRef && threeRef.current.appendChild(renderer.domElement);    renderer.setClearColor(0x000000, 1.0);  }  const initCamera = () => {    camera.position.set(10, 25, 25);    //camera.lookAt(new THREE.Vector3(0, 0, 0));    camera.lookAt(0, 0, 0)    scene.add(camera);      }  const initLight = () => {    //light.position.set(0, 25, 25);    //scene.add(light);    let spotLight = new THREE.DirectionalLight(0xffffff, 1, 50);  //点光源    spotLight.position.set(20, 40, 30);    spotLight.intensity = 1;    scene.add(spotLight);  }  const initControls = () => {    controls=new Orbitcontrols(camera, renderer.domElement)    //controls.addEventListener('change', renderer);//不使用anime下使用    controls.enabled = true;// 鼠标控制是否可用    controls.enableRotate = true;//是否可旋转,旋转速度(鼠标左键)    controls.minDistance = 10;//最大最小相机移动距离(景深相机)    controls.maxDistance = 40;    controls.minPolarAngle = Math.PI / 180; //最大仰视角和俯视角   // 1度视角   //从z轴正上方开始计算角度    controls.maxPolarAngle = Math.PI / 2; // 90度视角    controls.enableDamping = true;//惯性滑动,滑动大小默认0.25    controls.dampingFactor = 0.1;    controls.enableZoom = true;//滚轮缩放控制    controls.zoomSpeed = 1.5;    controls.enablePan = true;//是否可平移,默认移动速度为7px    controls.panSpeed = 0.5;    //controls.minAzimuthAngle = -Math.PI/4;//水平方向视角限制    //controls.maxAzimuthAngle = Math.PI/4;    controls.autoRotate = true;// 是否自动旋转    controls.autoRotateSpeed = 0.05;  }  const initObject = () => {    const geometry = new THREE.BoxGeometry(10, 5, 7);    const material = new THREE.MeshPhongMaterial({ color: 0xFF0000 });    mesh = new THREE.Mesh(geometry, material);    mesh.position.set(0, 0, 0);    scene.add(mesh);    scene.add(axesHelper);    console.log(scene)  }  const animate = () => {    controls.update();    mesh.rotation.y += 0.01    camera.position.y += 0.05    renderer.render(scene, camera);    requestAnimationFrame(animate);  }  useEffect(() => {    initRenderer()    initCamera()    initLight()    initObject()    //初始化控制器    initControls()    //动画帧    animate();  })  return (    <div>      <div id="d3"        ref={threeRef}></div>    </div>  );}export default Three