【问题标题】:react-native Animate image to "breath" in and outreact-native Animate 图像以“呼吸”进出
【发布时间】:2017-04-02 14:57:44
【问题描述】:

我是 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>
);

在渲染方法中调用,像这样:

{this.newOrder(parsedTime)}

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

letters being rendered to one word:

重要的是,图像作为一个整体,应该一致地呼吸在一起,而不是每个图像都独立。 这是一张屏幕图片,您可以看到图像的样子,如果这有助于您了解使其看起来栩栩如生的最佳方法:

编辑: 我认为可以添加到动画中的东西有两件事: 1)尺寸越来越大 2)字母上的实际色块略微移动,可能越来越近,例如放大和缩小或类似的东西。 我认为这两者加在一起会使呼吸成为 3d。

所以我很想听听人们的意见如何做到这一点...... 谢谢!

【问题讨论】:

标签: animation react-native


【解决方案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>
    );
  }
}

【讨论】:

    【解决方案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)大小越来越小2)字母上的实际色块略微移动,可能越来越近,比如放大和缩小或类似的东西那。我认为这两个在一起会使呼吸成为 3d。有什么想法吗?
    • @SimchaBinyaminKatsof 我已经对其进行了编辑以显示一个有效的实现和一个指向可以看到它工作的小吃的链接。它确实是 #1,但我不太确定我是否理解您在 #2 中尝试做的事情。
    • 非常感谢! 1)我希望“呼吸”更加微妙。就像只是从原始尺寸上下移动几毫米。我要编辑哪些值来做到这一点? 2) 我所说的#2 的意思是:我只是想找出一些方法来让“呼吸”更加 3D,而不是 2D。所以它目前的方式,它只是在二维中变得越来越小。但我想要一些方法让它看起来也是 3d 的。就像一个人呼吸时胸部上下移动一样。我可以将它与以前的旧屏幕保护程序 win XP 进行比较,带有一个滚动的放大球
    • @SimchaBinyaminKatsof 对于 #1,在插值中编辑 outputRange。我建议阅读动画如何在 React Native 中工作。特别是interpolate 部分。
    • @SimchaBinyaminKatsof 对于#2,我想我明白你现在在说什么。这超出了我的知识领域,因为它更多地处理 2D/3D 动画,而不是任何特定于本机的反应。您应该用 animation 标记问题,并研究该特定效果的一般实现方式。或者问一个单独的问题,关于这种效果通常是如何实现的。然后尝试在本机反应中实现它。如果您在伪代码中发布/编辑效果,我可以提供有关如何实现它的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-08
    • 2021-11-15
    • 1970-01-01
    • 2019-11-30
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    相关资源
    最近更新 更多