【问题标题】:React native svg heart size animation反应原生 svg 心脏大小动画
【发布时间】:2019-12-17 11:33:34
【问题描述】:

我正在尝试使用 SVG 图像在 ReactNative expo 中制作一个脉动的 svg 心脏。

我设法使心脏用动画值调整大小的唯一方法是将其绑定到样式:fontSize。

这似乎正确地改变了大小,但动画真的很不稳定。

代码如下:

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"
      />
    );
  }
}

我也尝试绑定宽度和高度,但它们也不稳定 + 它们会更改容器大小,而不是图标。

有没有更好的方法来做到这一点?谢谢

【问题讨论】:

  • 你试过用lottie代替svg吗?因为 rn 没有为 svg 提供很多选项
  • 我还没有。我正在尝试尽可能使用原始解决方案

标签: react-native animation svg expo react-animated


【解决方案1】:

似乎动画 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>
      </>
    );
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-16
    • 1970-01-01
    • 1970-01-01
    • 2022-06-13
    • 2018-07-20
    • 2022-01-04
    • 1970-01-01
    相关资源
    最近更新 更多