react 24小时时间轴优化

在这里插入图片描述

JS

import React, { useState, useEffect } from 'react'
import styles from './style.less'
import { Slider } from 'antd';
import { PlusOutlined, MinusOutlined } from '@ant-design/icons';

const end = 1440  // 总长度
const stepCount = 60  // 步长
const contentStyle = {  // 是背景渐变 而不是给文字添加颜色 所需要的属性
    cursor: 'pointer',
    WebkitBackgroundClip: 'text',
    WebkitTextFillColor: 'transparent',
    // background: 'linear-gradient(to right, rgba(182, 54, 128) 0%, rgba(16, 202, 100, ) 100%)'  // 不知道为何不生效 我单独 在 className 写入了
};
const index = () =>
{
    const [currentTime, setCurrentTime] = useState('18:00')
    useEffect(() =>
    {  // 发送数据请求 设置订阅/启动定时器 手动更改 DOM 等 ~
        setCurrentTime(ThisTime())
        return () =>
        {  // 组件卸载之前 做一些收尾工作 比如清楚定时器/取消订阅 等 ~
        }
    }, [])  // 检测数组内变量 如果为空 则监控全局
    // 获取实时小时
    const ThisTime = () =>
    {
        let newThisTime = new Date().getHours().toString().padStart(2, '0').padEnd(5, ':00')
        return newThisTime
    }
    // 当数据改变时 得到的是步长数 转换为加工过的时间
    const handleChange = async value =>
    {
        try
        {
            let newValue = parseFloat(tipFormatter(value))  // 当前小时  08:00  => 8
            let newThisTime = parseFloat(ThisTime())  // 实时小时
            if (newValue <= newThisTime)
            {
                setCurrentTime(tipFormatter(value))
            }
        } catch (err)
        {
            console.log(err);
        }
    }
    // 时间包装
    const tipFormatter = value =>
    {
        let newValue = (value / 60).toString().padStart(2, '0').padEnd(5, ':00')
        return newValue
    }
    // 时间转为步长
    const TimeToStep = currentTimeStr =>
    {
        let currentTime = currentTimeStr.split(':');
        if (currentTime.length === 2)
        {
            // 最新的步长数
            let newStep = currentTime[0] * 60 + currentTime[1] * 1
            return newStep
        } else
        {
            return 0;
        }
    }
    // 时间减1
    const reduceClick = () =>
    {
        let CurrentStep = TimeToStep(currentTime)  // 当前时间
        let CurrentTimeStep = TimeToStep(ThisTime())  // 实时时间
        if (CurrentStep <= CurrentTimeStep && CurrentStep > 0)
        {
            setCurrentTime(tipFormatter((CurrentStep -= 60)));
        } else
        {
            setCurrentTime('00:00');
        }
    }
    // 时间加1
    const subjoinClick = () =>
    {
        let CurrentStep = TimeToStep(currentTime)  // 当前时间
        let CurrentTimeStep = TimeToStep(ThisTime())  // 实时时间
        if (CurrentStep < CurrentTimeStep && CurrentStep >= 0)
        {
            setCurrentTime(tipFormatter(Number((CurrentStep += 60))));
        } else
        {
            // 如果当前时间 大于等于时间轴 则显示这个时间
            setCurrentTime(ThisTime());
        }
    }

    const SliderDom = () =>
    {
        const marks = new Array
        let newValue = parseFloat(currentTime)  // 当前小时  08:00  => 8
        let newThisTime = parseFloat(ThisTime())  // 实时小时
        console.log(newValue, newThisTime);
        for (let index = 0; index <= end / stepCount; index++)
        {
            let ladder = (end / (end / stepCount)) * Number(index)  // 总长度 / 60 = 24小时
            console.log(index, 'index');
            marks[ladder] = ({
                style: {
                    color: 'red',  // 因为设置过背景颜色颜色了 所以这里不会生效 而且仿佛还只有 color 会生效
                    // textAlign: 'right'  // 没生效 ~ 
                },
                // index 也对应着 所处的每个小时 所以 要拿 index 判断 而不是 newValue !
                label: (<strong style={contentStyle} className={index <= newThisTime ? styles.active : index % 2 === 0 ? styles.marksEven : styles.marksOdd} >
                    {tipFormatter((end / 24) * index)
                    }</strong>),
            })
        }
        return (
            <Slider
                className={styles.Slider}
                marks={marks}
                max={end}
                step={stepCount}
                value={TimeToStep(currentTime)}  // 时间转换后的步长
                onChange={handleChange}
                tipFormatter={tipFormatter}
                disabled={false}  // 禁止点击 否
            />
        )
    }
    return (
        <div className={styles.container}>
            <div className={styles.reduce} onClick={reduceClick}>
                <MinusOutlined width={100} />
            </div>
            {SliderDom()}
            <div className={styles.subjoin} onClick={subjoinClick}>
                <PlusOutlined className={styles.subjoin} />
            </div>
        </div>
    )
}

export default index

CSS

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;

  .active {
    background: linear-gradient(to right, rgb(126, 228, 9) 0%, rgb(211, 19, 77) 100%);
  }

  .marksEven {
    // 偶数
    background: linear-gradient(to right, rgba(182, 54, 128) 0%, rgba(16, 202, 100, ) 100%);

  }

  .marksOdd {
    // 奇数
    display: none;
    // background: linear-gradient(to right, rgb(231, 120, 157, .3) 0%, rgb(254, 225, 64, .1) 100%);
  }

  //   .active,
  //   .marksEven,
  //   .marksOdd {
  //     cursor: pointer;
  //     -webkit-background-clip: text;
  //     -webkit-text-fill-color: transparent;
  //   }


  .Slider {
    background: #262626;
    margin: 0px 5px 0px 5px;
    height: 40px;
    width: 80%;
  }

  .reduce,
  .subjoin {
    width: 40px;
    height: 40px;
    line-height: 40px;
    background: #262626;
    text-align: center;
    cursor: pointer;
    border-radius: 8px 8px 8px 8px;
  }

  // antd 样式
  :global {
    .ant-slider-rail {
      height: 1px !important;
      background: #fff !important;
      top: 7px !important;
    }

    // 显示的距离
    .ant-slider-track {
      height: 1px !important;
      background: transparent !important;
    }

    // 字体颜色
    // .ant-slider-mark-text {
    //   color: #fff !important;
    // }


    .ant-slider-handle:focus {
      outline: none !important;
      box-shadow: none !important;
    }

    .ant-slider:hover .ant-slider-handle:not(.ant-tooltip-open) {
      border: none;
    }

    .ant-slider-dot {
      width: 1px !important;
      height: 8px !important;
      border: 0px solid rgb(85, 62, 62) !important;
      margin-left: 0px !important;
    }

    // .ant-slider-handle {
    //   width: 1px !important;
    //   height: 30px !important;
    //   border: none;
    //   background: rgb(202, 12, 25);
    //   margin-top: -10px !important;
    //   transform: none !important;
    // }

    // .ant-slider-mark {
    //   top: 20px !important;
    // }
    // .ant-slider-mark {
    //   position: absolute;
    //   top: 14px;
    //   left: 0;
    //   width: 100%;
    //   font-size: 28px;
    // }
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

臧小川

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值