单击事件<->长按时间:手搓播放器

事件分析

事件区分核心:使用onMouseDownonMouseUp和定时器来区分单击事件与长按事件

按下时设置长按事件定时器(并加入长按回调),并记录当前时间戳,

松开事件中如果当前时间戳差值小于定时器则执行单击回调,并清除定时器,如果大于定时器事件,则按下事件中定时器的长按回调已经执行,事件末清除以上定时器

 const mouseDown = (callBack) => {
    mouseTime.current = Date.now();
    clearInterval(timer.current);
    timer.current = null;
    setPlaying(false);
    funcTimer.current.timeOutTimer = setTimeout(() => {
      funcTimer.current.intervalTimer = setInterval(() => {
        callBack();
      }, 100);
    }, 480);
  };
  const mouseUp = (callBack) => {
    const funcType = Date.now() - mouseTime.current >= 500;
    if (funcType) {
      clearInterval(funcTimer.current.intervalTimer);
    } else {
      clearTimeout(funcTimer.current.timeOutTimer);
      callBack();
    }
    funcTimer.current = {};
    mouseTime.current = null;
  };

手搓播放器代码

import React, { useEffect, useRef, useState } from 'react';
import { Slider, Button } from 'antd';
import { PlayCircleOutlined, PauseCircleOutlined, BackwardOutlined, ForwardOutlined, XFilled } from '@ant-design/icons';

const data = [
  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8,
  9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
  8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
];
function Index() {
  const [pointIndex, setPointIndex] = useState(0);
  const [playing, setPlaying] = useState(false);
  const timer = useRef(null);
  const mouseTime = useRef(null);
  const funcTimer = useRef({});

  function formatter(value) {
    return `${value}%`;
  }

  const play = () => {
    if (playing) {
      setPlaying(false);
      clearInterval(timer.current);
      timer.current = null;
    } else {
      setPlaying(true);
      timer.current = setInterval(() => {
        setPointIndex((c) => {
          if (c < data?.length - 1) {
            return c + 1;
          } else {
            setPlaying(false);
            clearInterval(timer.current);
            timer.current = null;
            return 0;
          }
        });
      }, 200);
    }
  };

  const mouseDown = (callBack) => {
    mouseTime.current = Date.now();
    clearInterval(timer.current);
    timer.current = null;
    setPlaying(false);
    funcTimer.current.timeOutTimer = setTimeout(() => {
      funcTimer.current.intervalTimer = setInterval(() => {
        callBack();
      }, 100);
    }, 480);
  };
  const mouseUp = (callBack) => {
    const funcType = Date.now() - mouseTime.current >= 500;
    if (funcType) {
      clearInterval(funcTimer.current.intervalTimer);
    } else {
      clearTimeout(funcTimer.current.timeOutTimer);
      callBack();
    }
    funcTimer.current = {};
    mouseTime.current = null;
  };

  const forwardFunc = () => {
    pointIndex !== data?.length && setPointIndex((c) => c + 1);
  };
  const backFunc = () => {
    pointIndex !== 0 && setPointIndex((c) => c - 1);
  };

  const reset = () => {
    setPointIndex(0);
    setPlaying(false);
    clearInterval(timer.current);
    timer.current = null;
  };

  return (
    <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh', width: '100%' }}>
      <div style={{ width: '700px', display: 'flex' }}>
        <Button
          icon={<BackwardOutlined />}
          onMouseDown={() => mouseDown(backFunc)}
          onMouseUp={() => mouseUp(backFunc)}
        />
        <Button icon={playing ? <PauseCircleOutlined /> : <PlayCircleOutlined />} onClick={play} />
        <Button
          icon={<ForwardOutlined />}
          onMouseDown={() => mouseDown(forwardFunc)}
          onMouseUp={() => mouseUp(forwardFunc)}
        />
        <Button icon={<XFilled style={{ fontSize: 12 }} />} onClick={reset} />
        <Slider
          // tipFormatter={formatter}
          style={{ width: '600px' }}
          value={pointIndex}
          max={data?.length - 1}
          onChange={(e) => {
            setPlaying(false);
            clearInterval(timer.current);
            timer.current = null;
            setPointIndex(e);
          }}
        />
      </div>
    </div>
  );
}

export default Index;

 

posted @   SimoonJia  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示