Создание компонента изображения с асинхронной загрузкой в ​​React Native - Часть II

Мы добавляем анимацию в заполнитель во второй части нашей серии статей о создании асинхронного компонента изображения в React Native.

Добавление анимации в изменения пользовательского интерфейса - приятный штрих, который обеспечивает лучший опыт для пользователей, а Animated API React Native делает анимацию проще, чем когда-либо. 😎

Во второй части этой серии вы добавите анимацию разнесения для перехода заполнителя, покидающего вид, и изображения, входящего после его загрузки из сети.

Предыдущий

Перейти к источнику

Подготовка к анимации

Чтобы добиться эффекта разнесения, нам нужно будет анимировать непрозрачность заполнителя и изображения вместе с масштабом заполнителя. Анимация этих стилей позволяет нам использовать параметр useNativeDriver в наших анимациях, освобождая поток JS для других задач.

Мы также сделаем заполнитель Animated.View, а изображение - Animated.Image, чтобы они поддерживали анимированные стили.

constructor(props: Props) {
  super(props)
  this.state = {
    loaded: false,
    imageOpacity: new Animated.Value(0.0),
    placeholderOpacity: new Animated.Value(1.0),
    placeholderScale: new Animated.Value(1.0)
  }
}
render() {
  const {
    placeholderColor,
    style,
    source
  } = this.props
  const {
    imageOpacity,
    loaded,
    placeholderOpacity,
    placeholderScale
  } = this.state
  return (
    <View
      style={style}>
      <Animated.Image
        source={source}
        resizeMode={'contain'}
        style={[
          style,
          {
            opacity: imageOpacity,
            position: 'absolute',
            resizeMode: 'contain'
          }
        ]}
        onLoad={this._onLoad} />
      {!loaded &&
        <Animated.View
          style={[
            style,
            {
              backgroundColor: placeholderColor,
              opacity: placeholderOpacity,
              position: 'absolute',
              transform: [{ scale: placeholderScale }]
            }
        ]} />
      }
    </View>
  )
}

Создание анимации

Анимация состоит из двух анимационных последовательностей для достижения ее внешнего вида. Сначала создается впечатление, что заполнитель взрывается, а затем взрывается при загрузке изображения. 💣 💥

Для имплозии мы уменьшаем масштаб заполнителя и начинаем снижать его непрозрачность. Затем для взрыва мы увеличиваем эти свойства, одновременно выполняя параллельную анимацию, увеличивая непрозрачность изображения. Анимация упрощает!

_onLoad = () => {
  const {
    placeholderScale,
    placeholderOpacity,
    imageOpacity
  } = this.state
  Animated.sequence([
    //
    // Implode
    //
    Animated.parallel([
      Animated.timing(placeholderScale, {
        toValue: 0.7,
        duration: 100,
        useNativeDriver: true
      }),
      Animated.timing(placeholderOpacity, {
        toValue: 0.66,
        duration: 100,
        useNativeDriver: true
      }),
    ]),
    //
    // Explode
    //    
    Animated.parallel([
      Animated.parallel([
        Animated.timing(placeholderOpacity, {
          toValue: 0,
          duration: 200,
          useNativeDriver: true
        }),
        Animated.timing(placeholderScale, {
          toValue: 1.2,
          duration: 200,
          useNativeDriver: true
        }),
      ]),  
      Animated.timing(imageOpacity, {
        toValue: 1.0,
        delay: 200,
        duration: 300,
        useNativeDriver: true
      })
    ])
  ]).start(() => {
    this.setState(() => ({ loaded: true }))
  })
}

Посмотреть источник здесь

Следующие шаги

В оставшейся части этой серии мы сделаем этот компонент еще лучше.

Спасибо за чтение! Мы с нетерпением ждем возможности поделиться с этой серией другими материалами и не стесняйтесь задавать любые вопросы ниже. 🚀

Знаете ли вы, что мы каждую неделю подбираем для вас лучшие ресурсы по React Native и связанным с ним фреймворкам? Подпишитесь на нашу еженедельную новостную рассылку React Native, чтобы каждую неделю получать ее на свой почтовый ящик. 🙌🏻