首页 > 其他分享 >react hooks实现对元素拖拽及鼠标滚轮缩放

react hooks实现对元素拖拽及鼠标滚轮缩放

时间:2024-07-11 11:19:24浏览次数:20  
标签:scale const 缩放 hooks useCallback react useState currentTarget

page.jsx

import './index.less';

import { useDrag, useZoom } from './hooks';

const DragZoom = () => {
    const { handleMouseDown, handleMouseMove, handleMouseUp } = useDrag();
    const { handleWheel, scale } = useZoom();

    return (
        <div className="drag-zoom">
            <div className="area">
                <div
                    onm ouseDown={handleMouseDown}
                    onm ouseMove={handleMouseMove}
                    onm ouseUp={handleMouseUp}
                    onWheel={handleWheel}
                    className="element"
                    style={{
                        transform: `scale(${scale})`,
                    }}
                />
            </div>
        </div>
    );
};

export default DragZoom;

index.less

.drag-zoom {
    width: 100vw;
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    .area {
        width: 500px;
        height: 500px;
        border: 1px solid #ddd;
        position: relative;
        overflow: hidden;
        .react-draggable {
            border: 1px solid goldenrod;
        }
        .element {
            position: absolute;
            width: 100px;
            height: 100px;
            cursor: grab;
            transition: transform 0.3s ease;
            background: paleturquoise;
        }
    }
}

hooks.js

import { useCallback, useState } from 'react';

// 拖拽
export function useDrag() {
    const [isDragging, setIsDragging] = useState(false);
    const [initialPosition, setInitialPosition] = useState({ x: 0, y: 0 });
    const [initialMousePosition, setInitialMousePosition] = useState({ x: 0, y: 0 });

    const handleMouseDown = useCallback((e) => {
        setIsDragging(true);
        setInitialMousePosition({ x: e.clientX, y: e.clientY });
        setInitialPosition({ x: e.currentTarget.offsetLeft, y: e.currentTarget.offsetTop });
    }, []);

    const handleMouseMove = useCallback(
        (e) => {
            if (isDragging) {
                const dx = e.clientX - initialMousePosition.x;
                const dy = e.clientY - initialMousePosition.y;
                e.currentTarget.style.left = `${initialPosition.x + dx}px`;
                e.currentTarget.style.top = `${initialPosition.y + dy}px`;
            }
        },
        [isDragging, initialMousePosition, initialPosition]
    );

    const handleMouseUp = useCallback(() => {
        setIsDragging(false);
    }, []);

    return {
        handleMouseDown,
        handleMouseMove,
        handleMouseUp,
    };
}

// 缩放
export function useZoom(initialScale = 1) {
    const [scale, setScale] = useState(initialScale);

    const handleWheel = useCallback(
        (e) => {
            if (e.deltaY !== 0) {
                const newScale = scale + (e.deltaY > 0 ? -0.05 : 0.05);
                setScale(newScale < 0.5 ? 0.5 : newScale); // 防止缩放过小
                e.currentTarget.style.transform = `scale(${newScale})`;
            }
        },
        [scale]
    );

    return {
        handleWheel,
        scale,
    };
}

 

标签:scale,const,缩放,hooks,useCallback,react,useState,currentTarget
From: https://www.cnblogs.com/zion0707/p/18295696

相关文章

  • [email protected](53)[email protected](2)- action
    目录1,特点1.1,payload1.2,type1.3,bindActionCreators1,特点是一个平面对象(plain-object)。换句话说,就是通过字面量创建的对象,它的__proto__指向Object.prototype。该对象有2个属性:constaction={ type:'add', payload:3}1.1,payload表示额外需要传递的附......
  • 使用Java9 Flow API进行Reactive Programming
    importjava.util.concurrent.Flow;importjava.util.concurrent.Flow.Publisher;importjava.util.concurrent.Flow.Subscriber;publicclassReactiveExample{publicstaticvoidmain(String[]args){//创建一个发布者,发布一系列的数字Publisher......
  • react或vue中页面多个echarts,只有最后一个能自适应的处理方法
    页面多个echarts时,自适应绑定方式必须是addEventListenerwindow.addEventListener("resize",()=>{myChart.resize();myChart2.resize();})myChart,myChart2是echart实例   ......
  • 【vueUse库Reactivity模块各函数简介及使用方法--上篇】
    vueUse库是一个专门为Vue打造的工具库,提供了丰富的功能,包括监听页面元素的各种行为以及调用浏览器提供的各种能力等。其中的Browser模块包含了一些实用的函数,以下是这些函数的简介和使用方法:vueUse库Sensors模块各函数简介及使用方法vueUseReactivity函数1.com......
  • 【vueUse库Reactivity模块各函数简介及使用方法--中篇】
    vueUse库是一个专门为Vue打造的工具库,提供了丰富的功能,包括监听页面元素的各种行为以及调用浏览器提供的各种能力等。其中的Browser模块包含了一些实用的函数,以下是这些函数的简介和使用方法:vueUse库Sensors模块各函数简介及使用方法vueUseReactivity函数1.rea......
  • 组合API-reactive函数
      <template><divclass="container"><div>{{obj.name}}</div><div>{{obj.age}}</div><button@click="updateName">修改数据</button></div></template><script......
  • 【React】React18 Hooks 之 useContext
    目录useContext1、Provider和useContext2、Provider和Consumer3、Provider嵌套4、React.createContext提供的Provider和class的contextType属性5、读、写Context(1)父组件修改Context(2)子组件修改Context好书推荐useContext官方地址使用Context深度传递数据通......
  • 使用react物料
    1.win安装node.js2.安装axios报错,进入到C:\ProgramFiles\nodejs\node_modules\npm目录 成功!安装json-servernpminstalljson-server-g   原文:https://ice.work/docs/guide/about  ......
  • [email protected](52)[email protected](1)- 核心概念
    目录1,MVC2,前端MVC的困难3,Flux4,Redux1,MVC是一个解决方案,用于降低UI和数据关联的复杂度。在早期前后端未做分离时,服务端会响应一个完整的HTML,包含页面需要的所有数据。而浏览器仅承担渲染页面的作用,整体流程也就是服务端渲染。其中服务端的处理流程:处理请求,并将......
  • vue3 watch使用方式,如何监听reactive子属性 ref数据等
    代码<template><divclass="box">childB</div></template><scriptlang="ts"setup>import{reactive,watch,ref}from"vue";constdata1=reactive({msg:"childB",abc:"sl......