@playcanvas/react
Version:
A React renderer for PlayCanvas – build interactive 3D applications using React's declarative paradigm.
53 lines • 2.35 kB
JavaScript
"use client";
import { useLayoutEffect } from "react";
import { useComponent, useParent } from "../hooks/index.js";
import { Entity, Asset } from "playcanvas";
import { validatePropsWithDefaults, createComponentDefinition, getStaticNullApplication } from "../utils/validation.js";
/**
* The Anim component allows an entity to play animations.
* GLB's and GLTF's often contain animations. When you attach this component to an entity,
* it will automatically animate them. You'll also need a Render component to display the entity.
*
* @param {AnimProps} props - The props to pass to the animation component.
* @see https://api.playcanvas.com/engine/classes/AnimComponent.html
*
* @example
* <Entity>
* <Render type="asset" asset={asset} />
* <Anim asset={asset} clip="Walk" loop />
* </Entity>
*/
export const Anim = (props) => {
const { asset, ...safeProps } = validatePropsWithDefaults(props, componentDefinition);
// Create the anim component
useComponent("anim", safeProps, componentDefinition.schema);
// Get the associated Entity
const entity = useParent();
// Assign Asset animations to Anim component
useLayoutEffect(() => {
const anim = entity.anim;
if (!asset?.resource)
return;
const resource = asset.resource;
// Early out if component instantiation fails, or the asset contains no animations
if (!anim || !resource?.animations || resource.animations.length === 0)
return;
// Filter out non animations, and assign animations to component
resource.animations
.filter(animation => animation.type === 'animation')
.forEach(animation => {
anim.assignAnimation('animation', animation.resource);
});
}, [asset, asset?.id, asset?.resource, entity.getGuid()]);
return null;
};
const componentDefinition = createComponentDefinition("Anim", () => new Entity("mock-anim", getStaticNullApplication()).addComponent('anim'), (component) => component.system.destroy());
componentDefinition.schema = {
...componentDefinition.schema,
asset: {
validate: (value) => !value || value instanceof Asset,
errorMsg: (value) => `Invalid value for prop "asset": ${value}. Expected an Asset.`,
default: undefined
}
};
//# sourceMappingURL=Anim.js.map