Well, it's less bad.

This commit is contained in:
Gender Shrapnel 2020-08-23 04:52:07 +02:00
parent 53487944bc
commit b21a0f82d0
3 changed files with 49 additions and 8 deletions

View File

@ -0,0 +1,21 @@
import React, { useEffect } from "react"
import { FrameContext } from "./Canvas"
interface AnimationProxyProps<T> {
things: T[],
factory: (thing: T) => JSX.Element
}
function AnimationProxy<T>({ things, factory }: AnimationProxyProps<T>) {
const frameCount = React.useContext(FrameContext)
const [keptThings, setKeptThings] = React.useState<T[]>([])
useEffect(() => {
setKeptThings(things)
}, [frameCount])
return <>{keptThings.map((thing) => factory(thing))}</>
}
export default AnimationProxy

View File

@ -2,29 +2,48 @@ import React from "react"
import CanvasContext from "./CanvasContext"
export const FrameContext = React.createContext(0)
export interface SystemCanvasProps {
height: number,
width: number,
children?: JSX.Element[]
children?: JSX.Element[] | JSX.Element
}
function SystemCanvas({ height, width, children }: SystemCanvasProps) {
const canvasRef = React.useRef<HTMLCanvasElement>(null)
const [context, setContext] = React.useState<CanvasRenderingContext2D>(null)
const [frameCount, setFrameCount] = React.useState(0)
React.useEffect(() => {
const context = canvasRef.current.getContext("2d")
if (canvasRef.current != null) {
const context = canvasRef.current.getContext("2d")
setContext(context)
}
}, [frameCount])
React.useEffect(() => {
const frameId = requestAnimationFrame(() => {
setFrameCount(frameCount + 1)
})
return () => {
cancelAnimationFrame(frameId)
}
}, [frameCount])
if (context != null) {
context.save()
context.fillStyle = "black"
context.fillRect(0, 0, width, height)
context.restore()
setContext(context)
})
}
return (<div>
<CanvasContext.Provider value={ context }>
<canvas width={width} height={height} ref={canvasRef} style={{ width, height }} />
{children}
<FrameContext.Provider value={ frameCount }>
<canvas width={width} height={height} ref={canvasRef} style={{ width, height }} />
{children}
</FrameContext.Provider>
</CanvasContext.Provider>
</div>
)

View File

@ -1,6 +1,7 @@
import React, { useEffect, useState } from "react"
import { Body, Bounds, Message } from "@app/types"
import AnimationProxy from "./AnimationProxy"
import Canvas from "./Canvas"
import Client from "@app/client"
import RenderedBody from "./RenderedBody"
@ -49,12 +50,12 @@ function Home() {
<h1>Hello, World!</h1>
<p>Iteration: { iteration }, message count: { messageCount }, nObjects: { bodies.length }.</p>
<Canvas height={actualBounds.height} width={actualBounds.width}>
{bodies.map((body) => <RenderedBody
<AnimationProxy things={bodies} factory={(body) => <RenderedBody
key={body.id}
body={body}
bounds={bounds}
actualBounds={actualBounds}
/>)}
/>}/>
</Canvas>
</>
)