大屏看板学习

大屏自适应

核心是使用css的transform中的scale进行缩放以自适应,而缩放比例的计算需要确定一个基准,例如1920*1080:

const getScale = useCallback(() => {
    const ww = document.documentElement.clientWidth / 1920;
    const wh = document.documentElement.clientHeight / 1080;
    return ww < wh ? ww : wh;
 }, []);

然后设置好resize的监听事件,以及对应样式就好:

const demoKanBan = () => {
  const [scale, setScale] = useState();

  // 页面初始化执行
  useEffect(() => {
    changeSize();
    window.addEventListener('resize', changeSize);
  }, []);

  // 大屏缩放比例
  const getScale = useCallback(() => {
    const ww = document.documentElement.clientWidth / 1920;
    const wh = document.documentElement.clientHeight / 1080;
    return ww < wh ? ww : wh;
  }, []);

  // 防抖动
  const changeSize = debounce(() => {
    const s = getScale();
    setScale(s);
  }, 500);

  return (
    
{/* 看板内容 */}
); };

截图如下:


3D旋转

让物体旋转起来,本质就是让它在进行x轴运动的同时,y轴也在运动,我们假定一个运动周期是20s,由于我们可以设置成交替的模式,所以动画的时长就是一半,10s。
我们先来介绍下css的animation这一属性,它是由六个子属性组成的,即:

  • animation-name(动画名称、一般我们设置关键帧即可)
  • animation-duration(定义动画完成一个周期所需要的时间)
  • animation-timing-function(规定动画的速度曲线)
  • animation-delay(定义动画何时开始,定义为负值的话可以使动画跳过指定时间)
  • animation-iteration-count(定义动画的播放次数)
  • animation-direction(定义是否应该轮流反向播放动画)
    所以我们先定义相关的关键帧:
// x轴
@keyframes animX {
    0% {left: 0%;}
    100% {left: 90%;}
}
// y轴
@keyframes animY {
    0% {top: 0%;}
    100% {top: 80%;}
}

然后定义动画即可(多个动画可以','分隔)

.element1 {
    animation: animX 10s cubic-bezier(0.36, 0, 0.64, 1) -5s infinite alternate,
    animY 10s cubic-bezier(0.36, 0, 0.64, 1) 0s infinite alternate,
}

当然,要实现多个动画元素一起运动的效果,在这个例子里我们主要是控制animation-delay这一属性,比如上面的x轴动画是直接从第5s开始,y轴动画则是从0开始,我们可以依次类推接下来所要出现的动画元素初始的位置,如果我们想要n个球一起旋转,那么后一个球只需要在前一个球的基础上分别跳过 动画总时长/n 秒即可;
比如说上面我们定义的动画总时长是20s,10个元素一起旋转,那么从第一个元素往后开始,每个元素的延迟时间都要增加2s,element2的延时时间为-7s、-2s,element3的延迟时间为-9s,-4s,以此类推。
最后的效果如下图:


Three.js

three.js是JavaScript编写的WebGL第三方库。提供了非常多的3D显示功能。
在react中进行three.js的开发,通过查找相关资料,@react-three/fiber这一个包使用可重用、自包含的组件以声明方式构建场景,这些组件可以对状态做出反应,易于交互,并可以进入react的生态系统。而@react-three/drei则是three.js的一些预先制作好的功能的集合。
我们可以先添加这两个包和three.js:

yarn add three @react-three/fiber @react-three/drei

下面是一些概念:
Canvas标签
这个Canvas是定义 React Three Fiber 场景的地方,有点像Three.js中的:

const scene = new THREE.Scene();

注意,Canvas标签首字母大写,且需要从@react-three/fiber中引入,而其它的大部分标签都已经被注入,可以直接使用。

import { Canvas } from '@react-three/fiber';


{/* content */}

mesh标签
相当于Three.js中的网格:

new THREE.Mesh( geometry, material );

只是其相关属性的定义可以写在标签体内,比如缩放和旋转就可以这样子定义:



ambientLight标签
相当于Three.js中的环境光:

const light = new THREE.AmbientLight( color : Integer, intensity : Float);

同样的,现在传入的参数可以作为相关属性定义在标签体内:


directionalLight标签
相当于Three.js中的平行光:

const directionalLight = new THREE.DirectionalLight( color : Integer, intensity : Float );

同样的,现在传入的参数可以作为相关属性定义在标签体内:


OrbitControls标签
相当于Three.js中的轨道控制器:

const controls = new OrbitControls( camera, renderer.domElement );

需要从@react-three/drei中引入,使用时直接:

import { OrbitControls } from "@react-three/drei";


导入3d模型
可以去网站https://sketchfab.com/下载相关3d模型,使用原始的Three.js加载3d模型,方法是:

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

const loader = new GLTFLoader();
loader.load( 'path/to/model.glb', function ( gltf ) {
  scene.add( gltf.scene ); 
}, undefined, function ( error ) {
  console.error( error ); 
});

现在我们使用另一种方式来引入GLTF文件,使用一种工具:gltf-pipeline

gltf-pipeline由Richard Lee和Cesium团队用来优化glTF的工具。

    将glTF转换为glb(并反向)
    将缓冲区/纹理保存为嵌入文件或单独文件
    将glTF 1.0模型转换为glTF 2.0
    应用Draco网格压缩

1.安装:

yarn add global gltf-pipeline

2.将 glTF 转换为 Draco glTF。通过终端进入到3d模型的目录下,在终端输入以下命令:

gltf-pipeline -i scene.gltf -o yourName.gltf -d

然后就会在当前目录下生成 yourName.gltf 这一文件

3.生成js文件

npx gltfjsx yourName.gltf

就会在当前目录下生成yourName.js这一文件,这便是通过这个工具进行操作后生成的可嵌入的一个3D模型;

然后我们把这两个文件放入项目中,注意,由于生成的yourName.js中引入gltf默认是

const { nodes, materials } = useGLTF('/xxx.gltf')

所以我们需要把gltf文件放到项目根目录下的publi文件夹下面,然后在需要使用到模型的地方引入这个js文件即可:

import Car from "./Car.js";
import { Suspense } from "react";


  

完整的一个通过@react-three/fiber辅助创建的Three.js示例代码如下:

import { Canvas } from '@react-three/fiber';
import { OrbitControls } from "@react-three/drei";
import React, { Suspense } from "react";
import Car from "./Car.js";

const ThreeTest = () => {
  return (
    
); }; export default ThreeTest;

你可能感兴趣的:(大屏看板学习)