From 4529d2e8d31dfb123e61f079626b5dca57bcffeb Mon Sep 17 00:00:00 2001 From: cha0s Date: Sun, 14 Jul 2024 21:07:46 -0500 Subject: [PATCH] refactor: radians --- app/context/radians.js | 9 ++++ app/react-components/dom/chat/message.jsx | 41 +++++++++---------- app/react-components/dom/dialogue.jsx | 22 +--------- app/react-components/pixi/entities.jsx | 21 ++++------ app/react-components/pixi/pixi.jsx | 10 ++++- app/react-components/pixi/targeting-ghost.jsx | 15 ++----- app/react-components/pixi/targeting-grid.jsx | 15 ++----- app/react-components/ui.jsx | 5 ++- app/routes/_main-menu.play.$.$/route.jsx | 24 ++++++++++- 9 files changed, 82 insertions(+), 80 deletions(-) create mode 100644 app/context/radians.js diff --git a/app/context/radians.js b/app/context/radians.js new file mode 100644 index 0000000..3840b56 --- /dev/null +++ b/app/context/radians.js @@ -0,0 +1,9 @@ +import {createContext, useContext} from 'react'; + +const context = createContext(); + +export default context; + +export function useRadians() { + return useContext(context); +} diff --git a/app/react-components/dom/chat/message.jsx b/app/react-components/dom/chat/message.jsx index a9eaef3..de34012 100644 --- a/app/react-components/dom/chat/message.jsx +++ b/app/react-components/dom/chat/message.jsx @@ -1,33 +1,32 @@ -import {useEffect, useState} from 'react'; +import {memo, useEffect, useState} from 'react'; +import {useRadians} from '@/context/radians.js'; import {render} from '@/dialogue.js'; -import {TAU} from '@/util/math.js'; import styles from './message.module.css'; -export default function Message({letters}) { - const [radians, setRadians] = useState(0); +function Message({letters}) { + const radians = useRadians(); + const [localRadians, setLocalRadians] = useState(radians); + const [isAnimating, setIsAnimating] = useState(true); useEffect(() => { - setRadians(0); - let handle; - let last; - const spin = (ts) => { - if ('undefined' === typeof last) { - last = ts; - } - const elapsed = (ts - last) / 1000; - last = ts; - setRadians((radians) => radians + (elapsed * TAU)); - handle = requestAnimationFrame(spin); - }; - handle = requestAnimationFrame(spin); + const handle = setTimeout(() => { + setIsAnimating(false); + }, 2_000); return () => { - cancelAnimationFrame(handle); - }; + clearTimeout(handle); + } }, []); + useEffect(() => { + if (isAnimating) { + setLocalRadians(radians) + } + }, [isAnimating, radians]); return (
- {render(letters, '')(letters.length - 1, radians)} + {render(letters, '')(letters.length - 1, localRadians)}
) -} \ No newline at end of file +} + +export default memo(Message); diff --git a/app/react-components/dom/dialogue.jsx b/app/react-components/dom/dialogue.jsx index d26878c..933da1f 100644 --- a/app/react-components/dom/dialogue.jsx +++ b/app/react-components/dom/dialogue.jsx @@ -2,8 +2,8 @@ import {useEffect, useMemo, useRef, useState} from 'react'; import {RESOLUTION} from '@/constants.js'; import {useDomScale} from '@/context/dom-scale.js'; +import {useRadians} from '@/context/radians.js'; import {render} from '@/dialogue.js'; -import {TAU} from '@/util/math.js'; import styles from './dialogue.module.css'; @@ -18,7 +18,7 @@ export default function Dialogue({ const ref = useRef(); const [dimensions, setDimensions] = useState({h: 0, w: 0}); const [caret, setCaret] = useState(0); - const [radians, setRadians] = useState(0); + const radians = useRadians(); useEffect(() => { return dialogue.addSkipListener(() => { if (caret >= dialogue.letters.length - 1) { @@ -29,24 +29,6 @@ export default function Dialogue({ } }); }, [caret, dialogue]); - useEffect(() => { - setRadians(0); - let handle; - let last; - const spin = (ts) => { - if ('undefined' === typeof last) { - last = ts; - } - const elapsed = (ts - last) / 1000; - last = ts; - setRadians((radians) => radians + (elapsed * TAU)); - handle = requestAnimationFrame(spin); - }; - handle = requestAnimationFrame(spin); - return () => { - cancelAnimationFrame(handle); - }; - }, []); useEffect(() => { const {params} = dialogue.letters[caret]; let handle; diff --git a/app/react-components/pixi/entities.jsx b/app/react-components/pixi/entities.jsx index 111839e..4703dd2 100644 --- a/app/react-components/pixi/entities.jsx +++ b/app/react-components/pixi/entities.jsx @@ -1,11 +1,12 @@ import {AdjustmentFilter} from '@pixi/filter-adjustment'; import {GlowFilter} from '@pixi/filter-glow'; import {Container} from '@pixi/react'; -import {useEffect, useState} from 'react'; +import {useState} from 'react'; import {usePacket} from '@/context/client.js'; import {useEcs, useEcsTick} from '@/context/ecs.js'; import {useMainEntity} from '@/context/main-entity.js'; +import {useRadians} from '@/context/radians.js'; import Entity from './entity.jsx'; @@ -13,10 +14,13 @@ export default function Entities({filters, monopolizers}) { const [ecs] = useEcs(); const [entities, setEntities] = useState({}); const [mainEntity] = useMainEntity(); - const [radians, setRadians] = useState(0); + const radians = useRadians(); const [willInteractWith, setWillInteractWith] = useState(0); - const [interactionFilters] = useState([new AdjustmentFilter(), new GlowFilter({color: 0x0})]); - const pulse = (Math.cos(radians) + 1) * 0.5; + const [interactionFilters] = useState([ + new AdjustmentFilter(), + new GlowFilter({color: 0x0}), + ]); + const pulse = (Math.cos(radians / 4) + 1) * 0.5; interactionFilters[0].brightness = (pulse * 0.75) + 1; interactionFilters[1].outerStrength = pulse * 0.5; usePacket('EcsChange', async () => { @@ -64,15 +68,6 @@ export default function Entities({filters, monopolizers}) { setWillInteractWith(main.Interacts.willInteractWith); } }, [ecs, mainEntity]); - useEffect(() => { - setRadians(0); - const handle = setInterval(() => { - setRadians((radians) => (radians + 0.1) % (Math.PI * 2)) - }, 50); - return () => { - clearInterval(handle); - }; - }, []); const renderables = []; for (const id in entities) { const isHighlightedInteraction = 0 === monopolizers.length && id == willInteractWith; diff --git a/app/react-components/pixi/pixi.jsx b/app/react-components/pixi/pixi.jsx index 6c90eca..4c10e8a 100644 --- a/app/react-components/pixi/pixi.jsx +++ b/app/react-components/pixi/pixi.jsx @@ -11,13 +11,21 @@ import ClientContext from '@/context/client.js'; import DebugContext from '@/context/debug.js'; import EcsContext from '@/context/ecs.js'; import MainEntityContext from '@/context/main-entity.js'; +import RadiansContext from '@/context/radians.js'; import Ecs from './ecs.jsx'; import styles from './pixi.module.css'; BaseTexture.defaultOptions.scaleMode = SCALE_MODES.NEAREST; -const Contexts = [AssetsContext, ClientContext, DebugContext, EcsContext, MainEntityContext]; +const Contexts = [ + AssetsContext, + ClientContext, + DebugContext, + EcsContext, + MainEntityContext, + RadiansContext, +]; const ContextBridge = ({children, render}) => { const contexts = Contexts.map(useContext); diff --git a/app/react-components/pixi/targeting-ghost.jsx b/app/react-components/pixi/targeting-ghost.jsx index ce95a8a..5b2f335 100644 --- a/app/react-components/pixi/targeting-ghost.jsx +++ b/app/react-components/pixi/targeting-ghost.jsx @@ -1,7 +1,8 @@ import {Container} from '@pixi/display'; import {Graphics} from '@pixi/graphics'; import {PixiComponent} from '@pixi/react'; -import {useEffect, useState} from 'react'; + +import {useRadians} from '@/context/radians.js'; const tileSize = {x: 16, y: 16}; @@ -34,15 +35,7 @@ const TargetingGhostInternal = PixiComponent('TargetingGhost', { }) export default function TargetingGhost({projected, tileLayer}) { - const [radians, setRadians] = useState(0); - useEffect(() => { - const handle = setInterval(() => { - setRadians((radians) => (radians + 0.2) % (Math.PI * 2)) - }, 50); - return () => { - clearInterval(handle); - }; - }, []); + const radians = useRadians(); const ghosts = []; const {area} = tileLayer; for (const {x, y} of projected) { @@ -54,7 +47,7 @@ export default function TargetingGhost({projected, tileLayer}) { key={JSON.stringify({x, y})} x={x * tileSize.x + tileSize.x * 0.5} y={y * tileSize.y + tileSize.y * 0.5} - radians={radians} + radians={radians / 2} /> ); } diff --git a/app/react-components/pixi/targeting-grid.jsx b/app/react-components/pixi/targeting-grid.jsx index 01e26d5..28e8f83 100644 --- a/app/react-components/pixi/targeting-grid.jsx +++ b/app/react-components/pixi/targeting-grid.jsx @@ -4,7 +4,8 @@ import {BlurFilter} from '@pixi/filter-blur'; import {Graphics} from '@pixi/graphics'; import {PixiComponent, useApp} from '@pixi/react'; import {Sprite} from '@pixi/sprite'; -import {useEffect, useState} from 'react'; + +import {useRadians} from '@/context/radians.js'; const tileSize = {x: 16, y: 16}; const radius = 9; @@ -86,19 +87,11 @@ const TargetingGridInternal = PixiComponent('TargetingGrid', { export default function TargetingGrid({tileLayer, x, y}) { const app = useApp(); - const [radians, setRadians] = useState(0); - useEffect(() => { - const handle = setInterval(() => { - setRadians((radians) => (radians + 0.1) % (Math.PI * 2)) - }, 50); - return () => { - clearInterval(handle); - }; - }, []); + const radians = useRadians(); return ( { + let handle; + let last; + const spin = (ts) => { + if ('undefined' === typeof last) { + last = ts; + } + const elapsed = (ts - last) / 1000; + last = ts; + setRadians((radians) => radians + (elapsed * TAU)); + handle = requestAnimationFrame(spin); + }; + handle = requestAnimationFrame(spin); + return () => { + cancelAnimationFrame(handle); + }; + }, []); useEffect(() => { if (!Client) { return; @@ -121,7 +141,9 @@ export default function PlaySpecific() { - + + +