本机Animate图像以“呼吸”进出

时间:2017-04-02 14:57:45

标签: animation react-native

我是新手做反应原生,需要Animate帮助。

目标:动画影像,使其看起来像是在缓慢呼吸。(稍微大一点然后再小一点,然后又一次又一次地回来,就像有人呼吸进出一样)

我的图像存储在newOrder()方法中的数组中:

 newOrder(timeAsProp) {
    const hour = timeAsProp.slice(0, 2);
    let returnValue = [];
    const yud = <Image key="yud" source={require('./img/yud.png')} style={Style.image} />;
    const hey1 = <Image key="hey1" source={require('./img/hey1.png')} style={Style.image} />;
    const vav = <Image key="vav" source={require('./img/vav.png')} style={Style.image} />;
    const hey2 = <Image key="hey2" source={require('./img/hey2.png')} style={Style.image} />;
     return (
<View style={Style.displayContainer}>{returnValue}</View>
);

在render方法中调用,如下所示:

{this.newOrder(parsedTime)}

它的四个单独的图像,在一行上一起渲染和显示。 它看起来像这样:

letters being rendered to one word:

重要的是,整个影像应该齐声呼吸,而不是每个影像本身。 下面是一个屏幕图片,所以你可以看到图像的样子,如果这样可以帮助你理解让它看起来活着的最佳方法:

编辑: 我认为会增加动画的东西有两件事: 1)尺寸越来越大 2)字母上的实际色块稍微移动,可能越来越近,如放大和缩小等等。 我认为这两者一起会使呼吸变得微弱。

所以我有兴趣听取人们的意见如何做到这一点...... thnks!

2 个答案:

答案 0 :(得分:2)

因此,对于无限动画(您可以自行停止),您可以将所有图像的宽度和高度设置为相同的插值动画值。为了产生呼吸效果,一种可能的方法是将两个动画功能联合起来,一个增加,另一个减少。例如:

import React, { Component } from 'react';
import { View, StyleSheet, Animated, Image, Easing } from 'react-native';
import { Constants } from 'expo';

const AnimatedImage = Animated.createAnimatedComponent(Image);

export default class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      size: new Animated.Value(1)
    }
  }

  componentDidMount () {
    this._loopAnimationUp();
  }

  // The animation functions. Initial and end values can be anything (not just 1, 10, but remember to use the same value and flip them:
  _loopAnimationUp() {
    this.state.size.setValue(1);
    Animated.timing(this.state.size, {
      toValue: 10,
      duration: 5000,
      easing: Easing.linear
    }).start((o) => {
      if (o.finished) {
        this._loopAnimationDown();
      }
    });
  }

  _loopAnimationDown() {
    this.state.size.setValue(10);
    Animated.timing(this.state.size, {
      toValue: 1,
      duration: 5000,
      easing: Easing.linear
    }).start((o) => {
      if (o.finished) {
        this._loopAnimationUp();
      }
    });
  }

  render() {
    const size = this.state.size.interpolate({
      inputRange: [1, 10],
      outputRange: [10, 50],
      extrapolate: 'clamp',
    });

    return (
      <View style={styles.container}>
        <AnimatedImage
          style={[styles.image, {
            width: size,
            height: size,
          }]}
          source={{uri: 'http://placekitten.com/g/200/200'}}
        />
        <AnimatedImage
          style={[styles.image, {
            width: size,
            height: size,
          }]}
          source={{uri: 'http://placekitten.com/g/200/200'}}
        />
        <AnimatedImage
          style={[styles.image, {
            width: size,
            height: size,
          }]}
          source={{uri: 'http://placekitten.com/g/200/200'}}
        />
        <AnimatedImage
          style={[styles.image, {
            width: size,
            height: size,
          }]}
          source={{uri: 'http://placekitten.com/g/200/200'}}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    flexDirection: 'row',
  },
  image: {
    justifyContent:'center',
    backgroundColor:'transparent'
  },
});

如果您需要稍后停止动画,可以使用:

this.state.size.stopAnimation();

您可以使用占位符图片查看其here的工作实现。

对于更多的数学倾向,可能有一种方法可以通过单个循环动画并以更复杂的方式使用插值来实现此目的。

答案 1 :(得分:1)

在循环中使用一系列动画。 在这个例子中,我正在呼吸一个文本。 首先将不透明度从1更改为0,然后将不透明度更改回1。 您可以使用此原则来更改其他属性,例如宽度和高度。

import React, {Component} from 'react'
import {
  Animated,
  Easing
} from 'react-native'

export default class MyComponent extends Component {

  constructor(props) {
    super(props);
    this.state = {
      opacity: new Animated.Value(1)
    }
  }

  componentDidMount() {
    Animated.loop(
      Animated.sequence([
        Animated.timing(this.state.opacity, {
          toValue: 0,
          duration: 1000,
          ease: Easing.linear,
          useNativeDriver: true
        }),
        Animated.timing(this.state.opacity, {
          toValue: 1,
          duration: 1000,
          ease: Easing.linear,
          useNativeDriver: true
        })
      ])
    ).start();
  }

  render() {
    return(
      <Animated.View style={{opacity: this.state.opacity}}>
        <Text>I'm breathing</Text>
      </Animated.View>
    );
  }
}