12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- import React, { useState, useImperativeHandle, forwardRef } from "react";
- // DraggableButton 组件
- const DraggableButton = forwardRef<HTMLDivElement, { children: React.ReactNode }>(({ children }, ref) => {
- let homePos = localStorage.getItem("homePos");
- let initPos = homePos ? JSON.parse(homePos) : { right: 200, top: 0 };
- const [position, setPosition] = useState(initPos);
- const [offset, setOffset] = useState({ x: 0, y: 0 });
- const handleDragStart = (e: React.DragEvent) => {
- const rect = e.currentTarget.getBoundingClientRect();
- setOffset({
- x: e.clientX - rect.left,
- y: e.clientY - rect.top
- });
- };
- const handleDrag = (e: React.DragEvent | any) => {
- if (e.clientX === 0 && e.clientY === 0) return; // 忽略拖动结束时的最后一个事件
- const newRight = window.innerWidth - (e.clientX - offset.x + e.currentTarget.offsetWidth);
- const newTop = e.clientY - offset.y;
- setPosition({ right: newRight, top: newTop });
- };
- const handleDragEnd = (e: React.DragEvent | any) => {
- const newRight = window.innerWidth - (e.clientX - offset.x + e.currentTarget.offsetWidth);
- const newTop = e.clientY - offset.y;
- setPosition({ right: newRight, top: newTop });
- localStorage.setItem("homePos", JSON.stringify({ right: newRight, top: newTop }));
- };
- // 使用 useImperativeHandle 将 DOM 节点暴露给父组件
- useImperativeHandle(ref, () => divRef.current!);
- const divRef = React.useRef<HTMLDivElement>(null);
- return (
- <div
- ref={divRef}
- draggable
- onDragStart={handleDragStart}
- onDrag={handleDrag}
- onDragEnd={handleDragEnd}
- style={{
- position: 'fixed',
- right: position.right,
- top: position.top,
- cursor: 'move',
- zIndex: 1000
- }}
- >
- {children}
- </div>
- );
- });
- export default DraggableButton;
|