Closed qpwo closed 2 years ago
Hi Luke,
What you want is already there, have a look at Custom Components. As custom components are created in the reconciliation process, it does not have direct access to any PIXI.Application specific logic like loaders or tickers.
In your example you use a simple <Sprite>
component, in that case I'd recommend you compose a simple React component to handle logic via a ref
if you're determined to control it imperatively.
function CustomSprite() {
const ref = useRef();
const { ticker } = useApp();
useEffect(() => {
const sprite = ref.current;
function tick(elapsed) {
sprite.rotation -= 0.01 * elapsed;
}
ticker.add(tick);
return () => ticker.remove(tick);
}, []);
return <Sprite image="image.png" ref={ref} />;
}
I'll close this issue., please let me know if you think we should reopen it
For future readers, I think you want your effect to depend on Sprite as well, since refs don't trigger re-renders. Complete example in typescript:
import React, { useEffect, useState } from 'react'
import { Sprite as PXSprite, } from 'pixi.js'
import { Sprite, useApp } from '@inlet/react-pixi'
type Callback = () => void
export function Spinner(props: {imgSrc: string}): JSX.Element {
const { ticker } = useApp()
const [sprite, setSprite] = useState<PXSprite | null>(null)
useEffect((): void | Callback => {
if (sprite == null) return undefined
const tick = (elapsed: number) => {
sprite.rotation -= 0.01 * elapsed
}
ticker.add(tick)
return () => ticker.remove(tick)
}, [sprite, ticker])
return <Sprite image={props.imgSrc} ref={s => setSprite(s)} />
}
And here's the start of a generic version although it's not quite right
export function PixiAppComponent<
T extends typeof PixiComponent,
S extends DisplayObject>
(props:
{
Component: T,
componentProps: React.Props<T>
}): JSX.Element {
const { ticker } = useApp()
const [sprite, setSprite] = useState<S | null>(null)
useEffect((): void | Callback => {
if (sprite == null) return undefined
const tick = (elapsed: number) => {
sprite.rotation -= 0.01 * elapsed
}
ticker.add(tick)
return () => ticker.remove(tick)
}, [sprite, ticker])
const { Component, componentProps } = props
return <Component {...componentProps} ref={s => setSprite(s)} />
}
I'm aware of
useTick
but want to manage my animations in plain js withoutuseState
s.In my ideal world I could write this code:
I don't know if this would work but if it's possible could be very useful. I imagine it's more performant when a page has a lot of animations.