zoukankan      html  css  js  c++  java
  • React 动画按钮组件

     标题,下划线 动画

     禁用

    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
            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" />
    </svg>
    
    const UnChecked = <div style={{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"/>
        </svg>
    </div>
    
    const DisableChecked = <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="rgba(0, 0, 0, 0.3)" />
        <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="rgba(0, 0, 0, 0.3)" />
    </svg>
    const DisableUnChecked = <div style={{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" fill='rgba(0, 0, 0, 0.3)' />
        </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) => {
            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: disabled ? 'rgba(0, 0, 0, 0.3)'  : transform ? 'rgba(14,119,209)':'rgba(0, 0, 0, 0.3)'
                    }} >{floatingLabelText}</span>
                    <div className={'radioBox'} style={{
                        borderBottom: disabled ? '2px dotted rgba(0 ,0 ,0 ,.3)' : errorText ? '2px solid #f44336' : '1px solid rgba(178,178,178,.4)'
                    }}
                    >
                        {options.map(item=>(
                            <div
                                key={item.value}
                                className={'radioItem'}
                                onClick={()=>{
                                    if (disabled){
                                        return
                                    }
                                    this.handleChange(item)
                                }}
                            >
                                {checked === item.value ? ( disabled ? DisableChecked: Checked) : ( disabled ? DisableUnChecked: UnChecked)} <span style={{color:disabled?'rgba(0, 0, 0, 0.3)':'#333'}}>{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;
             100%;
            transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;
         } 
    `
    
    export default RadioButtons;
  • 相关阅读:
    EditText被输入法覆盖的解决方法
    计算屏幕大小
    [转]在adt-bundle-linux建立工程找不到ADB & R文件
    3.18 迷茫的方向
    安卓笔记:Fragment
    安卓学习笔记:转Android LayoutInflater详解
    Android布局大全(转)
    第二章 Android基本应用开发与解析
    Datetime中offset-naive与offset-aware时间的计算
    Python日期操作datetime
  • 原文地址:https://www.cnblogs.com/it-Ren/p/14043728.html
Copyright © 2011-2022 走看看