12-6 RN之图片的缩放动画和渐变色

58 阅读1分钟

在本节中,我们将实现点击弹幕按钮时,频道图片的缩放动画和展示透明渐变色的效果。

1. 保存频道页面的图片

首先,在跳转到详情页时,我们需要将频道页面的图片保存到 playerstate 中,以便在频道详情页中使用。

onItemPress = (data: IProgram, index: number) => {
  const { dispatch, navigation, list, route } = this.props;
  dispatch({
    type: 'player/setState',
    payload: {
      thumbnailUrl: route.params.item.image,
    },
  });
  navigation.navigate('ProgramDetail', { id: data.id });
};

models/player.ts 中添加 thumbnailUrl 属性:

export interface PlayerModelState {
  ...
  thumbnailUrl: string;
}

2. 获取图片并展示

Detail 组件中,从 player 中获取图片的 URL 并渲染图片和弹幕按钮。

const mapStateToProps = ({ player }: RootState) => ({
  thumbnailUrl: player.thumbnailUrl,
});

render() {
  const { thumbnailUrl } = this.props;
  return (
    <View style={styles.container}>
      <View style={styles.imageView}>
        <Animated.Image
          style={[
            styles.image,
            {
              transform: [
                {
                  scale: this.anim,
                },
              ],
            },
          ]}
          source={{ uri: thumbnailUrl }}
        />
      </View>
      <Touchable onPress={this.danmu} style={styles.danmuBtn}>
        <Text style={styles.danmuText}>弹幕</Text>
      </Touchable>
    </View>
  );
}

设置图片和弹幕按钮的样式:

const IMAGE_WIDTH = 180;
const PADDING_TOP = (viewportWidth - IMAGE_WIDTH) / 2;

const styles = StyleSheet.create({
  container: {
    paddingTop: PADDING_TOP,
  },
  imageView: {
    alignItems: 'center',
  },
  image: {
    width: IMAGE_WIDTH,
    height: IMAGE_WIDTH,
    borderRadius: 8,
  },
  danmuBtn: {
    marginLeft: 10,
    height: 20,
    width: 40,
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 10,
    borderColor: '#fff',
    borderWidth: 1,
  },
  danmuText: {
    color: '#fff',
  },
});

3. 实现图片缩放动画

使用 Animated 实现图片缩放动画。当点击弹幕按钮时,缩放动画触发并展示渐变色背景。

interface IState {
  barrage: boolean;
}

state = {
  barrage: false,
};

const SCALE = viewportWidth / IMAGE_WIDTH;
anim = new Animated.Value(1);

danmu = () => {
  const { barrage } = this.state;
  this.setState({ barrage: !barrage });
  Animated.timing(this.anim, {
    toValue: !barrage ? SCALE : 1,
    duration: 100,
  }).start();
};

4. 渐变色背景

在点击弹幕按钮后,展示一个渐变色背景。使用 LinearGradient 组件来实现渐变效果。

{barrage && (
  <LinearGradient
    colors={[
      'rgba(128, 104, 102, 0.5)',
      'rgba(128, 104, 102, 0.8)',
      '#807c66',
      '#807c66',
    ]}
    style={styles.linear}
  />
)}

linear: {
  position: 'absolute',
  top: 0,
  height: viewportWidth,
  width: viewportWidth,
}

5. 总结

本节中,我们实现了点击弹幕按钮时,频道图片的缩放动画和展示渐变色的效果。在下一节中,我们将完成弹幕功能的实现。