我的網站之被迫營業——救命的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更熟悉的人應該更能發現其中的優點。

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多解析一項,但是因爲我自己的網站部署在這裏,就很不想把這個個人服務器充公。

繼續糾結中。

網站就不放了,涉及畢設,等我明年畢業吧

發佈了386 篇原創文章 · 獲贊 411 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章