React Native:动画比例,但让它缩小到角落而不是中心

时间:2016-12-24 20:06:11

标签: react-native

我有一个View,我想缩小到右下角,底部和右侧有一些边距/填充。

我能够让它缩小,但它缩小到中心。 video元素是缩小的元素:

enter image description here

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  View,
  PanResponder,
  Animated,
  Dimensions,
} from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignSelf: 'stretch',
    backgroundColor: '#000000',
  },
  overlay: {
    flex: 1,
    alignSelf: 'stretch',
    backgroundColor: '#0000ff',
    opacity: 0.5,
  },
  video: {
    position: 'absolute',
    backgroundColor: '#00ff00',
    bottom: 0,
    right: 0,
    width: Dimensions.get("window").width,
    height: Dimensions.get("window").height,
    padding: 10,
  }
});

function clamp(value, min, max) {
  return min < max
    ? (value < min ? min : value > max ? max : value)
    : (value < max ? max : value > min ? min : value)
}

export default class EdmundMobile extends Component {

  constructor(props) {
    super(props);
    this.state = {
      pan: new Animated.ValueXY(),
      scale: new Animated.Value(1),
    };
  }

  componentWillMount() {
    this._panResponder = PanResponder.create({
      onMoveShouldSetResponderCapture: () => true,
      onMoveShouldSetPanResponderCapture: () => true,

      onPanResponderGrant: (e, gestureState) => {
        this.state.pan.setOffset({x: this.state.pan.x._value, y: 0});
        this.state.pan.setValue({x: 0, y: 0});
      },

      onPanResponderMove: (e, gestureState) => {
        let width = Dimensions.get("window").width;
        let difference = Math.abs((this.state.pan.x._value + width) / width);
        if (gestureState.dx < 0) {
          this.setState({ scale: new Animated.Value(difference) });
          return Animated.event([
            null, {dx: this.state.pan.x, dy: 0}
          ])(e, gestureState);
        }
      },

      onPanResponderRelease: (e, {vx, vy}) => {
        this.state.pan.flattenOffset();
        if (vx >= 0) {
          velocity = clamp(vx, 3, 5);
        } else if (vx < 0) {
          velocity = clamp(vx * -1, 3, 5) * -1;
        }

        if (Math.abs(this.state.pan.x._value) > 200) {
          Animated.spring(this.state.pan, {
            toValue: {x: -Dimensions.get("window").width, y: 0},
            friction: 4
          }).start()
          Animated.spring(this.state.scale, {
            toValue: 0.2,
            friction: 4
          }).start()
        } else {
          Animated.timing(this.state.pan, {
            toValue: {x: 0, y: 0},
            friction: 4
          }).start()
          Animated.spring(this.state.scale, {
            toValue: 1,
            friction: 10
          }).start()
        }
      }
    });
  }

  render() {
    let { pan, scale } = this.state;
    let translateX = pan.x;
    let swipeStyles = {transform: [{translateX}]};
    let videoScale = scale
    let localVideoStyles = {transform: [{scale: videoScale}]};
    return (
      <View style={styles.container}>
        <Animated.View style={[styles.video, localVideoStyles]}></Animated.View>
        <Animated.View style={[styles.overlay, swipeStyles]} {...this._panResponder.panHandlers}>
        </Animated.View>
      </View>
    );
  }
}

AppRegistry.registerComponent('EdmundMobile', () => EdmundMobile);

1 个答案:

答案 0 :(得分:1)

好的我找到了一个解决方案。有点儿,但我认为它提供了我需要的所有自定义。

因此,不是转换比例,而是通过将page样式附加到状态并更改它们以响应泛响应者的内容来设置动画。

width, height, bottom, top

enter image description here