引用库:https://github.com/sueLan/react-native-anchor-point
参考代码:
import React from "react";
import { Animated, Easing, View } from "react-native";
export class LoadingView extends React.Component {
_rotateAnimatedValue = new Animated.Value(0);
_animation;
componentDidMount() {
this.startAnimation()
}
startAnimation = () => {
this._animation = Animated.loop(
Animated.timing(this._rotateAnimatedValue, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
easing: Easing.ease,
delay: 200
}),
{ iterations: 1000 },
).start();
}
componentWillUnmount() {
if (this._animation) {
this._animation.stop();
this._animation = null
}
}
render() {
const { source, imgWidth = 24, imgHeight = 24, resizeMode, style } = this.props;
const rotateValue = this._rotateAnimatedValue.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '360deg'],
})
return <View>
<Animated.Image
style={{
width: imgWidth,
height: imgHeight,
transform: [{ rotate: rotateValue }],
...style
}}
resizeMode={resizeMode}
source={source} />
</View>
}
}
动画组合代码
startAnimation = () => {
this._animation = Animated.loop(
Animated.sequence([
Animated.timing(this._rotateAnimatedValue, {
toValue: 1,
duration: 1500,
useNativeDriver: true,
easing: Easing.ease,
delay: 200
}),
Animated.timing(this._rotateAnimatedValue, {
toValue: 0,
duration: 1500,
useNativeDriver: true,
easing: Easing.ease
}),
]),
{ iterations: 1000 },
);
this._animation.start();
}
getTransform = () => {
const rotateValue = this._rotateAnimatedValue.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '24deg'],
})
let transform = {
transform: [{ perspective: 400 }, { rotateZ: rotateValue }],
};
return withAnchorPoint(transform, { x: 0, y: 1 }, { width: 46, height: 37 });
};
<Animated.Image
style={[{
width: 46,
height: 37,
position: 'absolute',
right: 8,
bottom: 1
},
this.getTransform()
]}
resizeMode={"stretch"}
source={require("@assets/home/diagnos_search.png")} />
该库的核心代码index.ts 如下:
import type { TransformsStyle } from "react-native";
export interface Point {
x: number;
y: number;
}
export interface Size {
width: number;
height: number;
}
const isValidSize = (size: Size): boolean => {
return size && size.width > 0 && size.height > 0;
};
const defaultAnchorPoint = { x: 0.5, y: 0.5 };
export const withAnchorPoint = (transform: TransformsStyle, anchorPoint: Point, size: Size) => {
if(!isValidSize(size)) {
return transform;
}
let injectedTransform = transform.transform;
if (!injectedTransform) {
return transform;
}
if (anchorPoint.x !== defaultAnchorPoint.x && size.width) {
const shiftTranslateX = [];
// shift before rotation
shiftTranslateX.push({
translateX: size.width * (anchorPoint.x - defaultAnchorPoint.x),
});
injectedTransform = [...shiftTranslateX, ...injectedTransform];
// shift after rotation
injectedTransform.push({
translateX: size.width * (defaultAnchorPoint.x - anchorPoint.x),
});
}
if (!Array.isArray(injectedTransform)) {
return { transform: injectedTransform };
}
if (anchorPoint.y !== defaultAnchorPoint.y && size.height) {
let shiftTranslateY = [];
// shift before rotation
shiftTranslateY.push({
translateY: size.height * (anchorPoint.y - defaultAnchorPoint.y),
});
injectedTransform = [...shiftTranslateY, ...injectedTransform];
// shift after rotation
injectedTransform.push({
translateY: size.height * (defaultAnchorPoint.y - anchorPoint.y),
});
}
return { transform: injectedTransform };
};
网友评论