Just a little playground to:
- make some tests with Rive
- have some examples from Documentation
- list some usefull doc/helpers.
Playground | Controls | Fire State |
---|---|---|
Set Input State | Mesh State Machine | Avatars | InputStateAtPath |
---|---|---|---|
- Install dependencies
yarn install
- Build and run the app
yarn ios
yarn android
- Expo: ~52.0.7
- React Native: 0.76.2
- Yarn: 4.5.1
- Rive: 8.1.0
rive-react-native
version 8.1.0
seems to fix the folowing issue:
Assets Loader needed for RN
To automatically load .riv
files inside native folders without pass by Xcode
and Android Studio
then use <Rive />
resourceName
property to load assets from them.
- Install expo-custom-assets module:
yarn add expo-custom-assets
-
Add animations
.riv
in a specific folder (ex:./assets/animations
) -
Modify the
app.json
config:
{
"expo": {
// ...
"plugins": [
// ...
[
"expo-custom-assets",
{
// Path to the folder with the animations
"assetsPaths": ["./assets/animations"]
}
]
]
}
}
- Add automatically the
.riv
files in the native foldersios
andandroid
:
# For both platforms
npx expo prebuild
# For a specific platform
npx expo prebuild --platform ios
npx expo prebuild --platform android
- Use the
<Rive />
component with theresourceName
property:
import Rive from "rive-react-native";
<Rive resourceName="animation_name.riv" />;
To automatically use .riv
local files in custom wrapper component without the need to import them in the native folders.
bouncing
and idle
), there is a white flash at each switch.
const [animation, setAnimation] = useState<"bouncing" | "idle">("idle");
return (
<>
<RiveAnimation source={truckV7} animationName={animation} />
<Button onPress={() => setAnimation("bouncing")}>Play bouncing</Button>
<Button onPress={() => setAnimation("idle")}>Play idle</Button>
</>
);
Maybe consider using Handle .RIV assets with expo-custom-assets for production 🤷♂️
- Modify the
metro.config.js
file:
If the file doesn't exist, generate it with the command:
npx expo customize metro.config.js
Then update it:
// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require("expo/metro-config");
/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);
// ADD THIS LINE
config.resolver.assetExts.push("riv");
module.exports = config;
-
Add animations
.riv
in a specific folder (ex:./assets/animations
) -
Add type declaration for
.riv
files:
If you don't have any types.d.ts
file, create it and add to it the following:
declare module "*.riv" {
const content: string;
export default content;
}
Then update the tsconfig.json
file to include the types.d.ts
file:
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
// ...
},
"include": [
// ...
"path/to/your/types.d.ts"
]
}
- Create a custom component to wrap the
<Rive />
component:
Create a component RiveAnimation
with the following content:
Source for the base: rive-app/rive-react-native#185 (comment)
import React, { forwardRef, useMemo } from "react";
import Rive, { RiveRef } from "rive-react-native";
// @ts-ignore
import resolveAssetSource from "react-native/Libraries/Image/resolveAssetSource";
type RiveComponentProps = Omit<
React.ComponentProps<typeof Rive>,
"url" | "resourceName"
> & {
source: string | number;
};
const isValidUrl = (uri: string | undefined): boolean => {
if (!uri) return false;
return uri.startsWith("http") || uri.startsWith("file");
};
export const RiveAnimation = forwardRef<RiveRef, RiveComponentProps>(
(props, ref) => {
const { source, ...riveProps } = props;
const riveConfig = useMemo(() => {
if (typeof source === "string" && isValidUrl(source)) {
return { url: source };
}
const resolved = resolveAssetSource(source);
const uri = resolved?.uri;
const isUrl = isValidUrl(uri);
return {
resourceName: !isUrl && uri ? uri : undefined,
url: isUrl ? uri : undefined,
};
}, [source]);
return <Rive ref={ref} {...riveProps} {...riveConfig} />;
}
);
- Use the
<RiveAnimation />
component instead of the<Rive />
component:
- with import:
import React from "react";
import { RiveAnimation } from "../components/RiveAnimation";
import truckV7 from "../assets/animations/truck_v7.riv";
export default function Playground() {
return <RiveAnimation source={truckV7} />;
}
- with require:
import React from "react";
import { RiveAnimation } from "../components/RiveAnimation";
export default function Playground() {
return (
<RiveAnimation source={require("../assets/animations/truck_v7.riv")} />
);
}
- with remote url:
import React from "react";
import { RiveAnimation } from "../components/RiveAnimation";
export default function Playground() {
return (
<RiveAnimation
source={
"https://public.uat.rive.app/community/runtime-files/148-325-tape.riv"
}
/>
);
}