Sprite Animator
export type SpriteAnimatorProps = {
/** The start frame of the animation */
startFrame?: number
/** The end frame of the animation */
endFrame?: number
/** The desired frames per second of the animation. If set to 0 or negative, animation will be static */
fps?: number
/** The animation names of the spritesheet (if the spritesheet -with JSON- contains more animation sequences) */
animationNames?: Array<string>
/** The frame identifier to use, must be one of animationNames */
frameName?: string
/** The URL of the texture JSON (if using JSON-Array or JSON-Hash) */
textureDataURL?: string
/** The URL of the texture image */
textureImageURL?: string
/** Whether or not the animation should loop */
loop?: boolean
/** The number of frames of the animation (required if using plain spritesheet without JSON) */
numberOfFrames?: number
/** Animation auto-start when all assets are loaded */
autoPlay?: boolean
/** Event callback when the animation starts or restarts */
onStart?: (data: AnimationEventData) => void
/** Event callback when the animation ends */
onEnd?: (data: AnimationEventData) => void
/** Event callback when the animation completes a loop cycle */
onLoopEnd?: (data: AnimationEventData) => void
/** Event callback fired on each frame change */
onFrame?: (data: AnimationEventData) => void
/** @deprecated Use pause={false} instead. Control when the animation runs */
play?: boolean
/** Control when the animation pauses */
pause?: boolean
/** Whether or not the Sprite should flip sides on the x-axis */
flipX?: boolean
/** Sets the alpha value to be used when running an alpha test
* @default 0.0
*/
alphaTest?: number
/** Displays the texture on a Billboard component always facing the camera.
* @default false
*/
asSprite?: boolean
/** Allows for manual update of the sprite animation e.g: via ScrollControls.
* Value should be between 0 and 1
*/
offset?: number
/** Allows the sprite animation to start from the end towards the start */
playBackwards?: boolean
/** Allows the animation to be paused after it ended so it can be restarted on demand via autoPlay */
resetOnEnd?: boolean
/** Array of Vector3-like positions for creating multiple instances of the sprite */
instanceItems?: (THREE.Vector3 | [number, number, number])[]
/** The maximum number of instances to render (for buffer size calculation)
* @default 1
*/
maxItems?: number
/** Pre-parsed sprite data, usually from useSpriteLoader */
spriteDataset?: {
spriteTexture: THREE.Texture
spriteData: SpriteData
}
/** Configuration options for the canvas context when loading textures */
canvasRenderingContext2DSettings?: CanvasRenderingContext2DSettings
/** Controls whether frame positions are rounded for precise pixel alignment.
* Enable this if you notice slight texture bleeding between frames.
* @default false
*/
roundFramePosition?: boolean
/** Additional properties to be passed to both mesh and instance components.
* Only includes safe properties that work across both types.
* @example { frustumCulled: false, renderOrder: 1 }
* @see https://threejs.org/docs/#api/en/core/Object3D
*/
meshProps?: CommonMeshProps
} & GroupProps
The SpriteAnimator component provided by drei is a powerful tool for animating sprites in a simple and efficient manner. It allows you to create sprite animations by cycling through a sequence of frames from a spritesheet image and JSON data.
Notes:
- The SpriteAnimator component internally uses the useFrame hook from react-three-fiber (r3f) for efficient frame updates and rendering.
- The sprites (without a JSON file) should contain equal size frames
- Trimming of spritesheet frames is not yet supported
- Internally uses the
useSpriteLoader
or can use data from it directly (which is the recommended way of loading assets)
<SpriteAnimator
position={[-3.5, -2.0, 2.5]}
startFrame={0}
meshProps={{ frustumCulled: false, scale: 2.5 }}
autoPlay={true}
loop={true}
numberOfFrames={16}
textureImageURL={'./alien.png'}
/>
Load sprite textures via useSpriteLoader
const { spriteObj: statics } = useSpriteLoader('/statics.png', '/statics.json', ['heart', 'skull', 'sword'], null)
<SpriteAnimator
position={[2, 2.8, 0.01]}
fps={0}
meshProps={{ frustumCulled: false, scale: 2.5 }}
autoPlay={true}
loop={true}
flipX={false}
startFrame={0}
frameName={'sword'}
spriteDataset={statics}
asSprite={false}
alphaTest={0.01}
/>
ScrollControls
example
;<ScrollControls damping={0.2} maxSpeed={0.5} pages={2}>
<SpriteAnimator
position={[0.0, -1.5, -1.5]}
startFrame={0}
onEnd={doSomethingOnEnd}
onStart={doSomethingOnStart}
autoPlay={true}
textureImageURL={'sprite.png'}
textureDataURL={'sprite.json'}
>
<FireScroll />
</SpriteAnimator>
</ScrollControls>
function FireScroll() {
const sprite = useSpriteAnimator()
const scroll = useScroll()
const ref = React.useRef()
useFrame(() => {
if (sprite && scroll) {
sprite.current = scroll.offset
}
})
return null
}