看到了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