【2022-03-08】Dragable组件 + Wheel组件

本文介绍了如何使用React实现一个Draggable组件,该组件通过监听鼠标事件实现元素的拖动,同时处理滚轮事件以实现元素的平滑缩放。源码中展示了详细的事件处理和元素定位逻辑,适用于需要自定义交互效果的前端开发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Dragable组件

原理

原生实现:监听鼠标的onMouseDown、onMouseMove、onMouseUp事件,对需要进行拖动的元素进行重新定位。
监听鼠标的滚轮事件onWheel,deltaY > 0向下滚动,deltaY < 0向上滚动。

源码

import React, { useRef } from 'react';
import { useReactive, useThrottleFn } from 'ahooks';

const Draggable = ({ children }) => {
  const state = useReactive({
    start: false,
    diffX: 0,
    diffY: 0,
  });
  const ref = useRef<any>(null);

  const onMouseDown = (e) => {
    state.start = true;
    const event = e || window.event;
    const diffX = event.clientX - ref.current.offsetLeft;
    const diffY = event.clientY - ref.current.offsetTop;

    state.diffX = diffX;
    state.diffY = diffY;
  };

  const onMouseMove = (e) => {
    if (!state.start) return;
    const { diffX, diffY } = state;
    const event = e || window.event;

    // 距离左侧
    let moveX = event.clientX - diffX;
    if (moveX < 0) moveX = 0;
    else if (moveX > window.innerWidth - ref.current.offsetWidth) {
      moveX = window.innerWidth - ref.current.offsetWidth;
    }

    // 距离顶部
    let moveY = event.clientY - diffY;
    if (moveY < 0) moveY = 0;
    else if (moveY > window.innerHeight - ref.current.offsetHeight) {
      moveY = window.innerHeight - ref.current.offsetHeight;
    }

    ref.current.style.left = moveX + 'px';
    ref.current.style.top = moveY + 'px';
  };

  const onMouseUp = (e) => {
    state.start = false;
  };

  const onWheel = (e) => {
    console.log(e);
    const { deltaY } = e;
    const old = ref.current.style.transform;
    ref.current.style.transform = old.replace(/\((.*)+\)/g, (_, p1) => {
      const num = Number(p1);
      if (deltaY > 0) {
        // 向下滚动
        return `(${num + 0.1 > 2 ? 2 : num + 0.1})`;
      }
      // 向上滚动
      return `(${num <= 0.3 ? 0.3 : num - 0.1})`;
    });
  };

  const { run } = useThrottleFn(onMouseMove, { wait: 50 });

  return (
    <div
      ref={ref}
      className="drag-node"
      onMouseDown={onMouseDown}
      onMouseMove={run}
      onMouseUp={onMouseUp}
      onWheel={onWheel}
      style={{
        transform: 'scale(1)',
      }}
    >
      {children}
    </div>
  );
};

export default Draggable;

示例

<Draggable>
	<div style={{ width: 100, height: 100, background: 'red' }}></div>
</Draggable>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值