看到了react-three-fiber做者展現的做品https://codesandbox.io/embed/r3f-moksha-f1ixt,心聲敬佩,大呼臥草,就想能不能用這個套子作一個數據展現的東
西,因而搞起。
javascript
先看一下效果,雖然寫的跟大佬的比就是shi,可是仍是記錄一下知識點:html
- 圖表部分使用的是plotly
1. 滾動實現
- 經過滾動欄控制position的y
- 經過offset和factor來控制各個block的位置,以及位置變動方向
function Block({ children, offset, factor, ...props }) { const { offset: parentOffset, sectionHeight } = useBlock(); const ref = useRef(); offset = offset !== undefined ? offset : parentOffset; useFrame(() => { const curY = ref.current.position.y; const curTop = state.top.current; ref.current.position.y = lerp(curY, (curTop / state.zoom) * factor, 0.1) }); return ( <offsetContext.Provider value={offset}> <group {...props} position={[0, -sectionHeight * offset * factor, 0]}> <group ref={ref}>{children}</group> </group> </offsetContext.Provider> ) }
2. 添加html元素
- 經過使用Dom組建添加html元素,文字等
<Dom style={{width: pixelWidth / (mobile ? 1 : 2), textAlign: "left"}} position={[contentMaxWidth*alignDirection / 4- alignRight*2, contentMaxWidth / 3, 1]}> {getGraph(graphNum)} </Dom>
3. lerp函數
- 爲了讓過渡更加平滑使用lerp函數,在兩個過程當中插入一些過渡值
ref.current.position.y = lerp(curY, (curTop / state.zoom) * factor, 0.1)
4. Suspense異步加載
- Suspense爲react自帶功能,激活lazy加載,若是爲加載完成 會觸發
fallback
<Suspense fallback={<Dom center className="loading" children="Loading..." />}> <Pages /> {/*<Diamonds />*/} <Startup /> </Suspense>
5.左右切換
- 根據傳入left作到每一頁左右能夠互換
- 經過
contentMaxWidth
指定positon
的x軸位置
<group position={[0, 0, 0]}> <Dom style={{width: pixelWidth / (mobile ? 1 : 2), textAlign: "left"}} position={[contentMaxWidth*alignDirection / 4- alignRight*2, contentMaxWidth / 3, 1]}> {getGraph(graphNum)} </Dom> <Dom style={{width: pixelWidth / (mobile ? 1 : 2), textAlign: "left"}} position={[-contentMaxWidth*alignDirection / 2 - alignRight*0.8 , contentMaxWidth / 10 * 3, 1]} > {getList(getInfo(graphNum))} </Dom> {children} </group>
6. 選擇可視化圖形
- 經過傳入圖形id進行圖形選取
const getGraph = (graphNum) => { if (graphNum === 3) return (<Graph3/>); else if (graphNum === 2) return (<Graph2/>); else return (<Graph1/>); };
7. 完成list
- 經過輸入列表數據完成list
const getList = ({title, lines}) => { const lis = lines.map(line=>(<li>{line}</li>)); return ( <> <h1> {title} </h1> <ul> {lis} </ul> </> ) };
8.演示代碼
githubjava