首页 > 其他 > 详细

React 动画按钮组件

时间:2020-11-26 22:14:47      阅读:30      评论:0      收藏:0      [点我收藏+]

 标题,下划线 动画

技术分享图片

 

import React from react
import {RadioButton, RadioButtonGroup} from material-ui/RadioButton
import MenuItem from material-ui/MenuItem
import get from lodash/get
import styled from "styled-components";
const Checked = <svg t="1606281388606" className="icon" viewBox="0 0 1024 1024" version="1.1"
                       xmlns="http://www.w3.org/2000/svg" p-id="2858" width="30" height="30">
    <path
        d="M512 810.667c-164.693 0-298.667-134.016-298.667-298.667s133.973-298.667 298.667-298.667c164.651 0 298.667 134.016 298.667 298.667s-134.016 298.667-298.667 298.667zM512 253.184c-142.72 0-258.859 116.096-258.859 258.816s116.139 258.816 258.859 258.816c142.763 0 258.816-116.181 258.816-258.816 0-142.763-116.053-258.816-258.816-258.816z"
        p-id="2859" fill="#00bcd4"></path>
    <path
        d="M682.667 512c0 94.257-76.41 170.667-170.667 170.667s-170.667-76.41-170.667-170.667c0-94.257 76.41-170.667 170.667-170.667s170.667 76.41 170.667 170.667z"
        p-id="2860" fill="#00bcd4"></path>
</svg>

const UnChecked = <div style={{width:30,height:30,marginTop:1}}>
    <svg t="1606281728538" className="icon" viewBox="0 0 1024 1024" version="1.1"
         xmlns="http://www.w3.org/2000/svg" p-id="3340" width="29" height="29">
        <path
            d="M512 810.667c-164.693 0-298.667-134.016-298.667-298.667s133.973-298.667 298.667-298.667c164.651 0 298.667 134.016 298.667 298.667s-134.016 298.667-298.667 298.667zM512 253.184c-142.72 0-258.859 116.096-258.859 258.816s116.139 258.816 258.859 258.816c142.763 0 258.816-116.181 258.816-258.816 0-142.763-116.053-258.816-258.816-258.816z"
            p-id="3341"></path>
    </svg>
</div>

let font = 16;

class RadioButtons extends React.Component {
    constructor(props) {
        const {defaultValue} = props;
        super(props);
        this.state = {
            checked: defaultValue,
            tp:40,
            lf:5,
            transform:false
        }
    }


    handleChange(e, key, v) {
        const {onChange} = this.props;
        this.setState({
            checked:e.value,
            transform:true,
        })
        setTimeout(()=>{
            this.setState({
                transform:false
            })
        },400)
        if (typeof onChange === function) {
            onChange(e.value);
        }
    }


    componentDidMount() {
        // 标题动画
        const {defaultValue,onChange} = this.props;
        setTimeout(()=>{
            this.setState({
                fs:14,
                tp:15,
                lf:0
            })
        },10)
        if(defaultValue){
            onChange(defaultValue)
        }
    }


    diff(obj1, obj2) {
        let o1 = obj1 instanceof Object;
        let o2 = obj2 instanceof Object;
        if (!o1 || !o2) {/*  判断不是对象  */
            return obj1 === obj2;
        }

        if (Object.keys(obj1).length !== Object.keys(obj2).length) {
            return false;
            //Object.keys() 返回一个由对象的自身可枚举属性(key值)组成的数组,例如:数组返回下表:let arr = ["a", "b", "c"];console.log(Object.keys(arr))->0,1,2;
        }

        for (let attr in obj1) {
            let t1 = obj1[attr] instanceof Object;
            let t2 = obj2[attr] instanceof Object;
            if (t1 && t2) {
                return this.diff(obj1[attr], obj2[attr]);
            } else if (obj1[attr] !== obj2[attr]) {
                return false;
            }
        }
        // 如果相等,返回true
        return true;
    }

    componentWillReceiveProps(nextProps, nextContext) {
        if(!this.diff(nextProps.defaultValue,this.props.defaultValue)){
            this.setState({
                checked: nextProps.defaultValue
            },()=>{
                this.props.onChange(nextProps.defaultValue &&nextProps.defaultValue);
            })
        }
        if(!this.diff(nextProps.options,this.props.options)){
            this.setState({
                checked:nextProps.options && nextProps.options[0].value
            },()=>{
                this.props.onChange(nextProps.options &&nextProps.options[0].value);
            })
        }
    }

    render() {
        const {
            value,
            disabled,
            options,
            optionText,
            optionValue,
            floatingLabelText,
            errorText
        } = this.props;
        const {checked,transform} = this.state;
        return (
            <RadioButtons.Root>
                <span className={radioTitle} style={{
                    top:this.state.tp,
                    left:this.state.lf,
                    color: transform ? rgba(14,119,209):rgba(0, 0, 0, 0.3)
                }} >{floatingLabelText}</span>
                <div className={radioBox} style={{
                    borderBottom: errorText ? 2px solid #f44336 : 1px solid rgba(178,178,178,.4)
                }}
                >
                    {options.map(item=>(
                        <div
                            key={item.value}
                            className={radioItem}
                            onClick={this.handleChange.bind(this,item)}
                        >
                            {checked === item.value ? Checked : UnChecked} <span>{item.text}</span>
                        </div>
                    ))}
                </div>
                <hr className={transformLine} style={{
                    transform: transform ? scaleX(1) :scaleX(0)
                }}/>
                <div className={errorText}>{errorText}</div>
            </RadioButtons.Root>

        )
    }
}

setTimeout(()=>{
    font = 12
},1000)
RadioButtons.Root = styled.div`
      position:relative;
      padding-top: 10px;
      margin-top: 20px;
      margin-bottom: 8px;
     .radioTitle {
        transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
        z-index: 1;
        transform: scale(0.75) translate(0px, -28px);
        transform-origin: left top;
        pointer-events: none;
        user-select: none;
        position: absolute;
     }
     .radioBox {
        display:flex;
        align-items: center;
        justify-content: space-around;
     }
     .radioItem {
        display:flex;
        align-items: center;
     }
     .errorText {
        position: relative;
        bottom: -5px;
        font-size: 12px;
        line-height: 12px;
        color: rgb(244, 67, 54);
        transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
     }
     .transformLine {
        border-top: none rgb(14, 119, 209);
        border-left: none rgb(14, 119, 209);
        border-right: none rgb(14, 119, 209);
        border-bottom: 2px solid rgb(14, 119, 209);
        bottom: 8px;
        box-sizing: content-box;
        margin: 0px;
        bottom:0;
        position: absolute;
        width: 100%;
        transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
     } 
`

export default RadioButtons;

 

React 动画按钮组件

原文:https://www.cnblogs.com/it-Ren/p/14043728.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!