跳到主要内容

动画图像

React Native Skia 支持动画图像。支持的格式为 GIF 和动画 WebP。

使用 Reanimated

如果你使用 Reanimated,我们提供一个 useAnimatedImageValue Hook,它可以自动完成所有操作。useAnimatedImageValue 返回一个共享值,该值会在每一帧自动更新。

在下面的示例中,我们使用 Reanimated 显示并动画一个 GIF。共享值首先为 null,一旦图像加载,它将在每一帧使用 SkImage 对象进行更新。

tsx
import React from "react";
import {
Canvas,
Image,
useAnimatedImageValue,
} from "@shopify/react-native-skia";
 
export const AnimatedImages = () => {
// This can be an animated GIF or WebP file
const bird = useAnimatedImageValue(
require("../../assets/birdFlying.gif")
);
return (
<Canvas
style={{
width: 320,
height: 180,
}}
>
<Image
image={bird}
x={0}
y={0}
width={320}
height={180}
fit="contain"
/>
</Canvas>
);
};
 
tsx
import React from "react";
import {
Canvas,
Image,
useAnimatedImageValue,
} from "@shopify/react-native-skia";
 
export const AnimatedImages = () => {
// This can be an animated GIF or WebP file
const bird = useAnimatedImageValue(
require("../../assets/birdFlying.gif")
);
return (
<Canvas
style={{
width: 320,
height: 180,
}}
>
<Image
image={bird}
x={0}
y={0}
width={320}
height={180}
fit="contain"
/>
</Canvas>
);
};
 

bird

还有第二个可选参数,可用于通过共享值来控制动画的暂停。

tsx
import React from "react";
import {Pressable} from "react-native";
import {useSharedValue} from "react-native-reanimated";
import {
Canvas,
Image,
useAnimatedImageValue,
} from "@shopify/react-native-skia";
 
export const AnimatedImages = () => {
const isPaused = useSharedValue(false);
// This can be an animated GIF or WebP file
const bird = useAnimatedImageValue(
require("../../assets/birdFlying.gif"),
isPaused
);
return (
<Pressable onPress={() => isPaused.value = !isPaused.value}>
<Canvas
style={{
width: 320,
height: 180,
}}
>
<Image
image={bird}
x={0}
y={0}
width={320}
height={180}
fit="contain"
/>
</Canvas>
</Pressable>
);
};
 
tsx
import React from "react";
import {Pressable} from "react-native";
import {useSharedValue} from "react-native-reanimated";
import {
Canvas,
Image,
useAnimatedImageValue,
} from "@shopify/react-native-skia";
 
export const AnimatedImages = () => {
const isPaused = useSharedValue(false);
// This can be an animated GIF or WebP file
const bird = useAnimatedImageValue(
require("../../assets/birdFlying.gif"),
isPaused
);
return (
<Pressable onPress={() => isPaused.value = !isPaused.value}>
<Canvas
style={{
width: 320,
height: 180,
}}
>
<Image
image={bird}
x={0}
y={0}
width={320}
height={180}
fit="contain"
/>
</Canvas>
</Pressable>
);
};
 

手动 API

要将图像加载为 SkAnimatedImage 对象,我们提供了一个 useAnimatedImage Hook

tsx
import {useAnimatedImage} from "@shopify/react-native-skia";
 
// bird is an SkAnimatedImage
const bird = useAnimatedImage(
require("../../assets/birdFlying.gif")
)!;
// SkAnimatedImage offers 4 methods: decodeNextFrame(), getCurrentFrame(), currentFrameDuration(), and getFrameCount()
// getCurrentFrame() returns a regular SkImage
const image = bird.getCurrentFrame();
// decode the next frame
bird.decodeNextFrame();
// fetch the current frame number
const currentFrame = bird.currentFrameDuration();
// fetch the total number of frames
const frameCount = bird.getFrameCount();
tsx
import {useAnimatedImage} from "@shopify/react-native-skia";
 
// bird is an SkAnimatedImage
const bird = useAnimatedImage(
require("../../assets/birdFlying.gif")
)!;
// SkAnimatedImage offers 4 methods: decodeNextFrame(), getCurrentFrame(), currentFrameDuration(), and getFrameCount()
// getCurrentFrame() returns a regular SkImage
const image = bird.getCurrentFrame();
// decode the next frame
bird.decodeNextFrame();
// fetch the current frame number
const currentFrame = bird.currentFrameDuration();
// fetch the total number of frames
const frameCount = bird.getFrameCount();