我的网站之被迫营业——救命的React-three-fiber

前言

这次是真的被迫营业,原本打算五天做好糊弄一下的东西,三天做好还部署好上交了,感谢React-three-fiber和netlify。

来龙去脉

大致就是离校一个月了,疫情原因回不去,导师自然会催催进度,赶巧的是那天是我准备为他干活的前一天。满口应允下来,原本五天的空闲时间一下就缩成了三天,还要部署好,还要能给他看。

这个过程主要运用到了react-three-fiber框架,这是一个基于React Hooks和Three.js的web GL框架,还是很好用的,有用的API其实有很多,时间原因我也没有看太多,只用到了最基础的useFrame和几个基础的geometry、texture。

最后我其实真不觉得这个仿真系统有啥用,但是导师就想有个展示的东西,,

React-three-fiber

关于这个框架因为我还没有摸熟,很多东西都是靠着逻辑硬做的,研究深了可能会有些收获。其次这个框架中很大的一部分是可以用Three.js取代的,因为他其实只是使用React逻辑将很多元素从canvas里面分离出来而已。

先看个小demo给没有接触过three.js的开发者找点感觉:

import ReactDOM from 'react-dom'
import React, { useRef, useState } from 'react'
import { Canvas, useFrame } from 'react-three-fiber'

function Box(props) {
  const mesh = useRef()
  const [hovered, setHover] = useState(false)
  const [active, setActive] = useState(false)
  
  useFrame(() => (mesh.current.rotation.x = mesh.current.rotation.y += 0.01))
  
  return (
    <mesh
      {...props}
      ref={mesh}
      scale={active ? [1.5, 1.5, 1.5] : [1, 1, 1]}
      onClick={e => setActive(!active)}
      onPointerOver={e => setHover(true)}
      onPointerOut={e => setHover(false)}>
      <boxBufferGeometry attach="geometry" args={[1, 1, 1]} />
      <meshStandardMaterial attach="material" color={hovered ? 'hotpink' : 'orange'} />
    </mesh>
  )
}

ReactDOM.render(
  <Canvas>
    <ambientLight />
    <pointLight position={[10, 10, 10]} />
    <Box position={[-1.2, 0, 0]} />
    <Box position={[1.2, 0, 0]} />
  </Canvas>,
  document.getElementById('root')
)

简单讲一下这段浓重的React风格的代码,mesh作为可以负载到canvas上的元素,是渲染模型等的唯一载体,一个简单的mesh如图所示,主要需要注意的就是下面这两段:

<boxBufferGeometry attach="geometry" args={[1, 1, 1]} />
<meshStandardMaterial attach="material" color={hovered ? 'hotpink' : 'orange'} 

一个定义了geometry,我们可以理解为物体,形状之类的,一个是material,即这个物体的材质。

这里通过useRef()取到mesh并通过useFrame让其渲染,如上代码即让box这个mesh不断旋转。

优点

使用过three.js的朋友应该知道,在canvas上面检查元素,添加点击事件等其实都是比较麻烦的,能够和最新的web GL结合的框架更是少之又少,大部分工程化构建都是通过ts start来实现的,而react-three-fiber借助react-spring社区的东风,加上可以直接通过create-react-app这个优秀的脚手架进行创建,因此在国外的three.js开发中一直都是很受欢迎的。

上段代码也显示,我们在mesh元素上添加动作是很容易的,当然这只是我学艺不精的肤浅了解,对这个框架的几个钩子函数或Three.jsAPI更熟悉的人应该更能发现其中的优点。

扫描二维码关注公众号,回复: 9003608 查看本文章

Redux的一个坑

当然这个框架不是完美的,其中一个很尴尬的问题就是Redux的问题。简单的讲,即使我们用Provider完美的包裹了Canvas(注意这个canvas的C是大写的,他是react-three-fiber的一个元素,而不是H5的canvas),我们仍然不能在canvas中内部的任意mesh里面使用UseSelector等react-redux的API。

关于这一点目前主要有两种解决办法,一个是通过rustand这个react-spring推荐的状态管理框架解决,它提供了更契合react-three-fiber框架的解决方案。

同时它的一些API和Redux还是有点像的,反正我是没用,但不代表以后不用。

第二种就是在Canvas外拿到数据,然后用props传值进去,虽然周转麻烦了点,但是用起来倒还好,毕竟我的那个仿真系统除了canvas外也有很多逻辑和数据要处理,行吧其实还是redux生态习惯了之后不喜欢别的。

部署

部署的问题,原本不是问题,create-react-app打包会生成一个build文件夹,一般来说我们直接把这个文件夹拖到netlify或者zeit-to之后,他自然就会使用服务器给我们部署好,域名什么的添加起来也特别简单,比如Github Students有一项权益,有免费一年的name.com的一个免费域名。

问题就是网速呀,netlify加上name.com的域名,足够让我这个附加WebGL技术的网站加载个几分钟了,如果没有FQ的话。

但是因为使用到了react-router-dom,也不能就直接打开index.html,因此目前的方案主要有两个,一个是通过github pages和github actions,使用node.js服务,但是失败了。这个是后话,涉及CICD,我们后面再聊。

另一个就是用自己的服务器呗,其实这是最简单的,无非加个docker,nginx多解析一项,但是因为我自己的网站部署在这里,就很不想把这个个人服务器充公。

继续纠结中。

网站就不放了,涉及毕设,等我明年毕业吧

发布了362 篇原创文章 · 获赞 352 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_43870742/article/details/104199938