React native 反应本机svg心脏大小动画
我正在尝试使用svg图像在ReactNative expo中制作一个脉动的svg心脏 我唯一能够使心脏使用动画值调整大小的方法是将其绑定到style:fontSize 这似乎可以正确地更改大小,但动画确实不稳定 代码如下:React native 反应本机svg心脏大小动画,react-native,animation,svg,expo,react-animated,React Native,Animation,Svg,Expo,React Animated,我正在尝试使用svg图像在ReactNative expo中制作一个脉动的svg心脏 我唯一能够使心脏使用动画值调整大小的方法是将其绑定到style:fontSize 这似乎可以正确地更改大小,但动画确实不稳定 代码如下: import React, { Component } from 'react'; import { Animated } from 'react-native'; import { SimpleLineIcons } from '@expo/vector-icons';
import React, { Component } from 'react';
import { Animated } from 'react-native';
import { SimpleLineIcons } from '@expo/vector-icons';
const AnimatedIcon = Animated.createAnimatedComponent(SimpleLineIcons);
const TARGET_FONT_SIZE = 16;
const GROWN_FONT_SIZE = 24;
class GrowingHeart extends Component<any, any> {
size = new Animated.Value(TARGET_FONT_SIZE);
constructor(props) {
super(props);
Animated.sequence([
Animated.timing(this.size, {
duration: 1000,
toValue: GROWN_FONT_SIZE
}),
Animated.timing(this.size, {
duration: 1000,
toValue: GROWN_FONT_SIZE
})
]).start();
}
render() {
return (
<AnimatedIcon
style={{ fontSize: this.size }}
size={20}
name="heart"
color="red"
/>
);
}
}
import React,{Component}来自'React';
从“react native”导入{Animated};
从“@expo/vector icons”导入{SimpleLineIcons};
const AnimatedIcon=Animated.createAnimatedComponent(SimpleLineIcons);
常量目标字体大小=16;
const-GROWN\u-FONT\u-SIZE=24;
类GrowingHeart扩展组件{
大小=新的动画值(目标字体大小);
建造师(道具){
超级(道具);
动画序列([
动画。计时(此尺寸{
持续时间:1000,
toValue:字体大小
}),
动画。计时(此尺寸{
持续时间:1000,
toValue:字体大小
})
]).start();
}
render(){
返回(
);
}
}
我也试着绑定宽度和高度,但它们也是起伏的+它们改变容器大小,而不是图标
有更好的方法吗?谢谢看来动画api还是垃圾(如果我弄错了,请纠正我) 我用reanimated重新写了这篇文章,效果很好。下面的代码并不完整,但显示了心脏是如何生长的,没有起伏,而是非常平滑
import React, { Component } from 'react';
import { TouchableOpacity } from 'react-native-gesture-handler';
import Animated, { Easing } from 'react-native-reanimated';
import { SimpleLineIcons } from '@expo/vector-icons';
const {
createAnimatedComponent,
debug,
set,
get,
block,
eq,
Value,
cond,
greaterThan,
startClock,
timing,
Clock,
Code,
clockRunning,
stopClock
} = Animated;
const AnimatedIcon = createAnimatedComponent(SimpleLineIcons);
const TARGET_FONT_SIZE = 16;
const GROWN_FONT_SIZE = 20;
class GrowingHeart extends Component<any, any> {
size = new Value(TARGET_FONT_SIZE);
clock = new Clock();
updatingValue = new Value(0);
clockState = {
finished: new Value(0),
position: new Value(5),
time: new Value(0),
frameTime: new Value(0)
};
clockConfig = {
duration: new Value(500),
toValue: new Value(GROWN_FONT_SIZE),
easing: Easing.linear
};
constructor(props) {
super(props);
}
render() {
const { color } = this.props;
const { updatingValue, size, clock, clockConfig, clockState } = this;
return (
<>
<Code>
{() =>
block([
cond(
// animation not triggered
eq(0, updatingValue),
[],
[
cond(
clockRunning(clock),
[],
[
set(clockState.finished, 0),
set(clockState.time, 0),
set(clockState.position, TARGET_FONT_SIZE),
set(clockState.frameTime, 0),
set(clockConfig.toValue, GROWN_FONT_SIZE),
startClock(clock)
]
),
cond(
greaterThan(0, updatingValue),
// is decreasing
[debug('going down', updatingValue)],
// is growing
[
timing(clock, clockState, clockConfig),
set(size, clockState.position)
]
),
cond(clockState.finished, [stopClock(clock)])
]
)
])
}
</Code>
<TouchableOpacity
onPress={() => {
this.updatingValue.setValue(1);
}}
>
<AnimatedIcon
style={{ fontSize: this.size }}
name="heart"
color={color}
/>
</TouchableOpacity>
</>
);
}
}
似乎动画api仍然是垃圾(如果我弄错了,请纠正我) 我用reanimated重新写了这篇文章,效果很好。下面的代码并不完整,但显示了心脏是如何生长的,没有起伏,而是非常平滑
import React, { Component } from 'react';
import { TouchableOpacity } from 'react-native-gesture-handler';
import Animated, { Easing } from 'react-native-reanimated';
import { SimpleLineIcons } from '@expo/vector-icons';
const {
createAnimatedComponent,
debug,
set,
get,
block,
eq,
Value,
cond,
greaterThan,
startClock,
timing,
Clock,
Code,
clockRunning,
stopClock
} = Animated;
const AnimatedIcon = createAnimatedComponent(SimpleLineIcons);
const TARGET_FONT_SIZE = 16;
const GROWN_FONT_SIZE = 20;
class GrowingHeart extends Component<any, any> {
size = new Value(TARGET_FONT_SIZE);
clock = new Clock();
updatingValue = new Value(0);
clockState = {
finished: new Value(0),
position: new Value(5),
time: new Value(0),
frameTime: new Value(0)
};
clockConfig = {
duration: new Value(500),
toValue: new Value(GROWN_FONT_SIZE),
easing: Easing.linear
};
constructor(props) {
super(props);
}
render() {
const { color } = this.props;
const { updatingValue, size, clock, clockConfig, clockState } = this;
return (
<>
<Code>
{() =>
block([
cond(
// animation not triggered
eq(0, updatingValue),
[],
[
cond(
clockRunning(clock),
[],
[
set(clockState.finished, 0),
set(clockState.time, 0),
set(clockState.position, TARGET_FONT_SIZE),
set(clockState.frameTime, 0),
set(clockConfig.toValue, GROWN_FONT_SIZE),
startClock(clock)
]
),
cond(
greaterThan(0, updatingValue),
// is decreasing
[debug('going down', updatingValue)],
// is growing
[
timing(clock, clockState, clockConfig),
set(size, clockState.position)
]
),
cond(clockState.finished, [stopClock(clock)])
]
)
])
}
</Code>
<TouchableOpacity
onPress={() => {
this.updatingValue.setValue(1);
}}
>
<AnimatedIcon
style={{ fontSize: this.size }}
name="heart"
color={color}
/>
</TouchableOpacity>
</>
);
}
}
您是否尝试过使用lottie而不是svg?因为rn没有为svgI提供很多选择,但svgI还没有。我正在尝试尽可能地使用原始解决方案您是否尝试过使用lottie而不是svg?因为rn没有为svgI提供很多选择,但svgI还没有。我尽量用原液