Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
1.6 kB
2
Indexable
Never
import React, { useState, useEffect, useRef } from 'react';
import { Box } from '@mui/material';

const DraggableText = () => {
  const [position, setPosition] = useState({ x: '0px', y: '0px' });
  const [dragging, setDragging] = useState(false);
  const boxRef = useRef();

  const onMouseDown = (e) => {
    setDragging(true);
    const rect = boxRef.current.getBoundingClientRect();
    setPosition({
      x: `${rect.right - e.clientX}px`,
      y: `${e.clientY - rect.top}px`,
    });
    e.stopPropagation();
    e.preventDefault();
  };

  const onMouseUp = (e) => {
    setDragging(false);
    e.stopPropagation();
    e.preventDefault();
  };

  const onMouseMove = (e) => {
    if (!dragging) return;
    const rect = boxRef.current.getBoundingClientRect();
    setPosition({
      x: `${rect.right - e.clientX}px`,
      y: `${e.clientY - rect.top}px`,
    });
    e.stopPropagation();
    e.preventDefault();
  };

  useEffect(() => {
    document.addEventListener('mousemove', onMouseMove);
    document.addEventListener('mouseup', onMouseUp);

    return () => {
      document.removeEventListener('mousemove', onMouseMove);
      document.removeEventListener('mouseup', onMouseUp);
    };
  }, [dragging]);

  return (
    <Box
      ref={boxRef}
      onMouseDown={onMouseDown}
      sx={{
        position: 'relative',
        width: '100px',
        height: '100px',
        backgroundColor: 'lightgrey',
        '&::after': {
          content: '"abc"',
          position: 'absolute',
          right: position.x,
          top: position.y,
        }
      }}
    />
  );
};

export default DraggableText;