react 时间轴组件

在这里插入图片描述
js

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

function index() {
  const marks = {
    0: {
      style: {
        color: TextGraying(0),
        cursor: ProhibitClick(0),
      },
      label: '00:00',
    },
    // 60: '01:00',
    120: {
      style: {
        color: TextGraying(120),
        cursor: ProhibitClick(120),
      },
      label: '02:00',
    },
    // 180: '03:00',
    240: {
      style: {
        color: TextGraying(240),
        cursor: ProhibitClick(240),
      },
      label: '04:00',
    },
    // 300: '05:00',
    360: {
      style: {
        color: TextGraying(360),
        cursor: ProhibitClick(360),
      },
      label: '06:00',
    },
    // 420: '07:00',
    480: {
      style: {
        color: TextGraying(480),
        cursor: ProhibitClick(480),
      },
      label: '08:00',
    },
    // 540: '09:00',
    600: {
      style: {
        color: TextGraying(600),
        cursor: ProhibitClick(600),
      },
      label: '10:00',
    },
    // 660: '11:00',
    720: {
      style: {
        color: TextGraying(720),
        cursor: ProhibitClick(720),
      },
      label: '12:00',
    },
    // 780: '13:00',
    840: {
      style: {
        color: TextGraying(840),
        cursor: ProhibitClick(840),
      },
      label: '14:00',
    },
    // 900: '15:00',
    960: {
      style: {
        color: TextGraying(960),
        cursor: ProhibitClick(960),
      },
      label: '16:00',
    },
    // 1020: '17:00',
    1080: {
      style: {
        color: TextGraying(1080),
        cursor: ProhibitClick(1080),
      },
      label: '18:00',
    },
    // 1140: '19:00',
    1200: {
      style: {
        color: TextGraying(1200),
        cursor: ProhibitClick(1200),
      },
      label: '20:00',
    },
    // 1260: '21:00',
    1320: {
      style: {
        color: TextGraying(1320),
        cursor: ProhibitClick(1320),
      },
      label: '22:00',
    },
    // 1380: '23:00',
    1440: {
      style: {
        color: TextGraying(1440),
        cursor: ProhibitClick(1440),
      },
      label: '24:00',
    },
  };
  const [InitialTime, setInitialTime] = useState('12:00');

  useEffect(() => {
    setInitialTime(ThisTime()); // 传入当前时间
    let perSecond = setInterval(() => {
      // console.log(321);
    }, 1000);
    return () => {
      clearInterval(perSecond);
    };
  }, []);
  function ThisTime() {
    return new Date().getHours() + ':00'; // 获取当前小时
  }
  function TextGraying(data) {
    return parseFloat(tipFormatter(data)) <=
      parseFloat(tipFormatter(ThisTime()))
      ? '#fff'
      : 'pink';
  }
  function ProhibitClick(data) {
    return parseFloat(tipFormatter(data)) <=
      parseFloat(tipFormatter(ThisTime()))
      ? ''
      : 'not-allowed';
  }
  // 时间转换为数值
  function LineConversionTime(currentTimeStr) {
    // console.log(currentTimeStr);
    let currentTime = currentTimeStr.split(':');
    if (currentTime.length === 2) {
      return Number(currentTime[0]) * 60 + Number(currentTime[1]);
    } else {
      return 0;
    }
  }
  // 数值转换为时间
  function tipFormatter(NumberOfSteps) {
    if (isNaN(NumberOfSteps)) {
      return NumberOfSteps;
    } else {
      if (
        NumberOfSteps !== '0' &&
        NumberOfSteps !== '' &&
        NumberOfSteps !== null
      ) {
        return (
          (Math.floor(NumberOfSteps / 60).toString().length < 2
            ? '0' + Math.floor(NumberOfSteps / 60).toString()
            : Math.floor(NumberOfSteps / 60).toString()) +
          ':' +
          ((NumberOfSteps % 60).toString().length < 2
            ? '0' + (NumberOfSteps % 60).toString()
            : (NumberOfSteps % 60).toString())
        );
      } else {
        return '';
      }
    }
  }
  // 数值转换为时间
  function onChange(NumericalValue) {
    if (parseFloat(tipFormatter(NumericalValue)) <= parseFloat(ThisTime())) {
      // 字符串转换为数字类型 14:00 => 14
      let CurrentTime = tipFormatter(NumericalValue);
      setInitialTime(CurrentTime);
    } else {
      return null;
    }
  }
  // 时间减1
  function reduceClick() {
    let CurrentStep = LineConversionTime(InitialTime);
    if (CurrentStep <= LineConversionTime(ThisTime()) && CurrentStep > 0) {
      setInitialTime(tipFormatter((CurrentStep -= 60)));
    } else {
      setInitialTime('00:00');
    }
  }
  // 时间加1
  function subjoinClick() {
    let CurrentStep = LineConversionTime(InitialTime);
    if (CurrentStep >= 0 && CurrentStep < LineConversionTime(ThisTime())) {
      setInitialTime(tipFormatter(Number((CurrentStep += 60))));
    } else {
      // 如果当前时间 大于等于时间轴 则显示这个时间
      setInitialTime(ThisTime());
    }
  }
  return (
    <div className={styles.container}>
      <div className={styles.reduce} onClick={reduceClick}>
        <MinusOutlined width={100} />
      </div>
      <Slider
        className={styles.Slider}
        marks={marks}
        min={0}
        max={1440}
        step={60}
        value={LineConversionTime(InitialTime)}
        tipFormatter={(value) => tipFormatter(value)}
        onChange={(value) => onChange(value)}
        disabled={false}
        defaultValue={60}
      />
      <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;

  .Slider {
    flex: 1;
    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;
    // }
  }
}
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
React 中,我们通常使用组件来组织和渲染页面。但是,如果不使用组件,仍然可以使用 React 的核心库(ReactReactDOM)来构建页面。 以下是一个简单的例子,展示了如何使用 React 来构建一个物流跟踪时间轴: ```js // 创建一个时间轴的数据结构 const timelineData = [ { id: 1, date: '2021-01-01', event: 'Shipment dispatched' }, { id: 2, date: '2021-01-03', event: 'In transit to destination' }, { id: 3, date: '2021-01-05', event: 'Arrived at destination' }, { id: 4, date: '2021-01-07', event: 'Out for delivery' }, { id: 5, date: '2021-01-08', event: 'Delivered' }, ]; // 创建一个根节点 const root = document.getElementById('root'); // 渲染时间轴 ReactDOM.render( <div> {timelineData.map(({ id, date, event }) => ( <div key={id}> <div>{date}</div> <div>{event}</div> </div> ))} </div>, root ); ``` 在这个例子中,我们首先创建了一个时间轴的数据结构 `timelineData`,包含了几个物流事件的日期和描述。然后我们创建了一个根节点 `root`,并使用 `ReactDOM.render()` 方法将时间轴渲染到根节点上。 在渲染时间轴的过程中,我们使用了 JavaScript 中的 `map()` 方法来遍历 `timelineData` 数组,并对每个物流事件创建了一个包含日期和描述的 `<div>` 元素。由于没有使用组件,所以所有的代码都写在了一个大的 `<div>` 元素内部。 这个例子只是一个简单的示例,实际的物流时间轴可能需要更复杂的布局和样式。但是,使用 React 的核心库仍然可以帮助我们组织和渲染页面,即使不使用组件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

臧小川

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

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

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

打赏作者

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

抵扣说明:

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

余额充值