React Native Animated для масштабирования изображения

У меня 2 проблемы с API Animated.

1-й: Я могу показать изображение слева направо с помощью следующего кода. Я хочу масштабировать изображение с позиции X=40 (leftPadding), Y=100(topPadding), height:20, width:20 до X=20, Y=10, height:250, width:300. Как мне этого добиться?

Мой код:

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

class MyTestComp extends Component {
  componentWillMount() {
    this.animatedValue = new Animated.Value(0);
  }
  buttonPress(){
  this.animatedValue.setValue(0);
    Animated.timing(this.animatedValue,{
      toValue:1,
      duration:1000,
      Easing: Easing
    }).start()
  }

  render() {

    const translateX = this.animatedValue.interpolate({
      inputRange: [0, 1],
      outputRange: [-500, 1]
    })

    const transform = [{translateX}];

    return (
      <View>
        <Text>MyTestComp</Text>
        <Animated.View style = {transform}>
        <Image
          source = {require('./assets/17.jpg')}
          style = {{width:300, height:250}}
        />
        </Animated.View>
        <View style = {{marginTop:10}}>
          <Button title = "Click Me" onPress = {()=> this.buttonPress()} />
        </View>
      </View>
    );
  }
}


export default MyTestComp;

2-й: Каждый раз, когда я запускаю анимацию, я получаю исключение:

React Native Animated для масштабирования изображения

Я не могу найти никакой документации по этому поводу. Как использовать опору transform.

Большое спасибо.

Если ваш код был идентичен тому, что вы разместили здесь, то я думаю, что ваша проблема была просто синтаксической ошибкой. style = {transform} должен был быть style = {{ transform }}.

Derrick Beining 09.03.2019 22:25
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
6
1
35 672
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Думаю, это то, что вам нужно:

Анимация на самом деле очень плавная, не выглядит так в GIF, потому что GIF составляет 4 кадра в секунду. Вот код (поскольку все ваши числа являются константами, я просто жестко закодировал их все в приведенном ниже коде):

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

const backgroundImage = require('....')

class App extends Component {
    constructor(props) {
        super(props)
        this.animatedValue = new Animated.Value(0)
    }

    handleAnimation = () => {
        Animated.timing(this.animatedValue, {
            toValue: 1,
            duration: 1000,
            easing: Easing.ease
        }).start()
    }

    render() {
        return (
            <View style = {{ flex: 1 }}>
                <TouchableOpacity onPress = {this.handleAnimation}>
                    <Text>Transform</Text>
                </TouchableOpacity>
                <Animated.Image
                    source = {backgroundImage}
                    resizeMode='cover'
                    style = {{
                        position: 'absolute',
                        left: 40,
                        top: 100,
                        height: 20,
                        width: 20,
                        transform: [
                            {
                                translateX: this.animatedValue.interpolate({
                                    inputRange: [0, 1],
                                    outputRange: [0, 120]
                                })
                            },
                            {
                                translateY: this.animatedValue.interpolate({
                                    inputRange: [0, 1],
                                    outputRange: [0, 25]
                                })
                            },
                            {
                                scaleX: this.animatedValue.interpolate({
                                    inputRange: [0, 1],
                                    outputRange: [1, 15]
                                })
                            },
                            {
                                scaleY: this.animatedValue.interpolate({
                                    inputRange: [0, 1],
                                    outputRange: [1, 12.5]
                                })
                            }
                        ]
                    }}
                />
            </View>
        )
    }
}

export default App

Некоторое объяснение:

  1. После анимации ширина изображения становится 300, что на 280 пикселей больше, так как изображение увеличивается от центра, поэтому координата x изображения сдвинута влево 140 px или -140 px, и мы хотим, чтобы координата x сдвигалась только влево 20 px, следовательно, мы должны сдвинуть его вправо 120 px, поэтому диапазон вывода x равен [0, 120]

  2. По той же причине, почему диапазон вывода y равен [0, 25]

  3. ширина теперь 300 по сравнению с предыдущим 20, который в 15 раз больше

  4. высота теперь 250 по сравнению с предыдущим 20, который в 12.5 раз больше

Что мне делать в случае неопределенной ширины? Скажем, я хочу, чтобы ширина соответствовала всему экрану, и я могу найти ширину из Dimensions. Но как мне рассчитать outputRange для ScaleX? Спасибо.

Somename 28.04.2018 13:11

Я получил, что работал, использовал ((width-150)/2)-20, где ширина => let width = Dimensions.get('window').width

Somename 28.04.2018 21:58

Другие вопросы по теме