three.js+react实现相机控制

相机参数设计

先存储变量-鼠标状态,相机半径和角度

const IsDown = useRef(false); 记录鼠标是否按下,用于控制页面移动
const PI = useRef(15) camera的半径
const R = useRef(90) 初始的角度,物体在正前方,跟我们视角是90度

重要的两个属性设置

1.设置相机位置(眼睛位置或者说相机篇拍照位置)

Camera.position.set(0, 3, PI.current); 相机位置

2. 摄像机镜头指向的具体坐标位置

Camera.lookAt(0, 0, 0); 设置相机方向

 const init = useCallback(() => {
    //渲染器尺寸
    Render.setSize(Body.current.offsetWidth, Body.current.offsetHeight);
    // 设计相机参数
    /**PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number )
       fov — 摄像机视锥体垂直视野角度
       aspect — 摄像机视锥体长宽比
       near — 摄像机视锥体近端面
       far — 摄像机视锥体远端面
    */
    Camera.fov = 45;
    Camera.aspect = Body.current.offsetWidth / Body.current.offsetHeight;
    Camera.near = 1;
    Camera.far = 1000;
    Camera.position.set(0, 3, PI.current); //位置相机位置
    Camera.lookAt(0, 0, 0); //设置相机方向
    // 相机参数动态设置完 必须调用此参数才可以更新
    Camera.updateProjectionMatrix();
    console.log("Render, Camera参数");
  }, [Render, Body]);

鼠标move触发,相机的位置(x,y,z)变化以及角度变化的算法

//...

  /**鼠标事件-按下 */
  const down = useCallback(() => {IsDown.current = true;}, []);
  /**鼠标事件-抬起 */
  const up = useCallback(() => {IsDown.current = false;}, []);
  /**鼠标事件-移动--相机控制 */
  const move = useCallback((e) => {
    if (IsDown.current === false) return;
    //console.log(e,'e---move',Camera.position);
    R.current -= e.movementX * 0.5 //鼠标左右移动对角度自减 
    
    // 重新设置相机位置,相机在XOY平面绕着坐标原点旋转运动
    const x = PI.current * Math.cos(R.current / 180 * Math.PI)
    const y = Camera.position.y + e.movementY * 0.1;
    const z = PI.current * Math.sin(R.current / 180 * Math.PI)

// 相机位置改变后,注意执行.looAt()方法重新计算视图矩阵旋转部分 
// 如果不执行.looAt()方法,相当于相机镜头方向保持在首次执行`.lookAt()`的时候
    Camera.position.set(x, y, z);//重新设置相机的位置
    Camera.lookAt(0, 0, 0);
  }, []);
  //...

此时已经可以左右旋转了,3d对象围绕相机原点x轴可以旋转,y轴上下拉会变大变小

添加缩放功能

滑轮滚动,相机y轴不变,半径改变

  /**鼠标滚轮事件---相机控制功能--缩放功能 */
  const wheel = useCallback((e) => {
    // console.log(e,'滚动滑轮');
    //判断滚轮方向 >0 滑轮向上 半径要自增 否则就是向下 半径自减
    if (e.deltaY > 0) PI.current += 1;
    else PI.current -= 1;
    // 半径变化 角度如果旋转果 要重新获取xy轴
    const x = PI.current * Math.cos((R.current / 180) * Math.PI);
    const y = Camera.position.y; //滑轮滚动默认y轴不变
    const z = PI.current * Math.sin((R.current / 180) * Math.PI);

    Camera.position.set(x, y, z);
    Camera.lookAt(0, 0, 0);
  }, []);

div处

return ( <div //.....// onMouseUp={up} onMouseDown={down} onMouseMove={move} onWheel={wheel} /> );

Gif效果

gif截图工具有问题。。。。但图片显示的相机控制功能的左右转动及缩放正常
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值