Home Reference Source Repository

src/ripples/CenterRipple.js

/**
 * @file melon/CenterRipple
 * @author cxtom<[email protected]>
 */


import React, {Component, PropTypes} from 'react';
import {create} from 'melon-core/classname/cxBuilder';
import RippleCircle from './RippleCircle';
import {spring, TransitionMotion} from 'react-motion';

const cx = create('CenterRipple');

export default class CenterRipple extends Component {

    constructor(props) {

        super(props);

        this.state = {
            now: 't' + 0
        };

        this.willLeave = this.willLeave.bind(this);
    }

    animate() {
        this.setState({
            now: 't' + Date.now()
        });
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.flag === !this.props.flag) {
            this.animate();
        }
    }

    shouldCompoenntUpdate(nextProps, nextState) {
        return this.props.opacity !== nextProps.opacity
            || this.props.scale !== nextProps.scale
            || this.props.flag !== nextProps.flag
            || this.state.now !== nextState.now;
    }

    willLeave(key, valOfKey) {
        return {
            ...valOfKey,
            opacity: spring(0, {stiffness: 60, damping: 15}),
            scale: spring(this.props.scale, {stiffness: 60, damping: 15})
        };
    }

    render() {

        const {opacity, children} = this.props;
        const {now} = this.state;

        const styles = [{
            key: now,
            style: {
                opacity: spring(opacity),
                scale: spring(0)
            }
        }];

        const className = cx(this.props).build();
        const circleClassName = cx().part('circle').build();

        return (
            <TransitionMotion
                willLeave={this.willLeave}
                styles={styles}>
                {interpolatedStyles =>
                    <div className={className}>
                        {interpolatedStyles.map(config => {
                            let {opacity, scale} = config.style;
                            return (
                                <RippleCircle
                                    key={config.key}
                                    className={circleClassName}
                                    opacity={opacity}
                                    scale={scale} />
                            );
                        })}
                        {children}
                    </div>
                }
            </TransitionMotion>
        );

    }

}

CenterRipple.defaultProps = {
    opacity: 0.5,
    scale: 2
};

CenterRipple.propTypes = {
    opacity: PropTypes.number.isRequired,
    scale: PropTypes.number.isRequired,
    flag: PropTypes.bool
};

CenterRipple.displayName = 'CenterRipple';