在react-native中写红包动画

平时没有写技术文章的习惯,但是这次写红包的动画还是挺有意思的,记录一下,如果有需要,可以参考一下。

UI给的红包效果如下:

看到红包效果后,本来想直接让设计师导出json格式的动画数据,然后用lottie加载的,发现不行;想想算了,直接用JS写吧,于是就开始了漫长的写动画调UI的过程。

动画大致分为两个部分,点击拆红包后向服务端发请求,开始抖动红包动画,拿到请求响应后停止抖动,并开始拆红包动画。

UI部分的代码如下,数据部分和style部分都没给出。


/* global Promise */

// @flow

import React from 'react';
import { connect } from 'dva';
import {
    Text,
    View,
    StyleSheet,
    Animated,
    TouchableOpacity,
    TouchableWithoutFeedback,
} from 'react-native';
import { Modal } from 'antd-mobile';
import icon_close from '../assets/other/icon_close.png';
import icon_redPackage from '../assets/other/icon_redPackage.png';
import icon_redPackage_open from '../assets/other/icon_redPackage_open.png';
import icon_redPackage_close from '../assets/other/icon_redPackage_close.png';

type RedPackage = {
    id: String;
    name: String;
    integral: number;
};

type Props = {
    visible: boolean;
    isOpen: boolean;
    totalIntegral: number,
    redPackages: RedPackage[];
    currentRedPackage: ?RedPackage;
    isOrderResult: boolean;             // 是否是提交订单给的红包
    dispatch: () => Promise;
};

@connect(state => state.redPackage)
export default class RedPackageModal extends React.Component {

    render() {
        const { visible } = this.props;
        return (
            
                {this._renderContent()}
            
        );
    }

    _renderContent = () => {

        const {
            visible,
            redPackages,
            totalIntegral,
            isOpen,
            isOrderResult,
            currentRedPackage,
            shake,
            progress,
            dispatch
        } = this.props;

        if (!visible || !redPackages || !redPackages.length) return null;
        const { integral } = currentRedPackage || {};
        const total = totalIntegral + (isOrderResult ? 0 : integral);
        return (
            
                 {
                    if (isOpen) return;
                    // 开启红包抖动动效
                    const shakeAnimation = Animated.loop(Animated.timing(shake, {
                        toValue: 2,
                        duration: 100,
                    }));
                    shakeAnimation.start();
                    // 请求拆红包接口
                    dispatch({
                        type: 'redPackage/openRedPackage'
                    }).then(() => {
                        // 结束抖动动效
                        shakeAnimation.stop();
                        // 动画结束后,防止图片倾斜,将倾斜度置为0
                        Animated.timing(shake, {
                            toValue: 0,
                            duration: 10,
                        }).start();
                        // 开始拆红包动效
                        Animated.timing(progress, {
                            toValue: 2,
                            duration: 600,
                        }).start();
                    });
                }}>
                    
                        
                        
                        
                            
                        
                        
                            
                                
                                    恭喜发财 大吉大利
                                    
                                        本次获得
                                        {integral}
                                        积分
                                    
                                    {isOrderResult ? '(发货后到账)' : ''}
                                    您当前共有{total}积分
                                    {
                                        // 如果有多个红包,在最后一个红包显示积分商城按钮,防止流程被打断
                                        redPackages.length <= 1 ? (
                                             {
                                                // 跳转到积分商城
                                                dispatch({
                                                    type: 'redPackage/onGoToStore'
                                                });
                                            }}>
                                                积分商城
                                            
                                        ) : null
                                    }
                                
                            
                        
                    
                
                {`您有${redPackages.length}个红包待领取`}
                {
                    // 在红包开启后显示关闭按钮
                    isOpen && currentRedPackage ? (
                         {
                            dispatch({
                                type: 'redPackage/onClose',
                            });
                        }}>
                            
                        
                    ) : null
                }
            
        );
    };
}

你可能感兴趣的:(在react-native中写红包动画)