react可视化编辑器 第一章 拖拽

效果:
在这里插入图片描述
实现可视化编辑器,第一步难点 是 拖拽

提示:链接和图片默认是可拖动的,不需要draggable属性。

在拖放操作的不同阶段使用并可能发生许多事件属性:

  • 在可拖动目标上触发的事件(源元素):
    ondragstart - 当用户开始拖动元素时触发
    ondrag - 拖动元素时触发
    ondragend - 在用户完成拖动元素时触发

  • 在放置目标上触发的事件:
    ondragenter - 当被拖动的元素进入放置目标时触发
    ondragover - 当被拖动的元素超过放置目标时触发
    ondragleave - 当被拖动的元素离开放置目标时触发
    ondrop - 当被拖动的元素放在放置目标上时触发

在这里插入图片描述

这种代码结构更加清楚, demo 和content是俩个完全没有关系的兄弟div

现在需求的 红色拖拽到蓝色中, 这里的方法是定位

情况一:

  • demo的操作逻辑代码
      <div
        id="demo"
        draggable
        onDragStart={(e) => handleDragStart(e, 1)}
        style={{
          width: '100px',
          height: '100px',
          backgroundColor: 'red',
          margin: '30px',
        }}
      >
        demo2
      </div>

  const handleDragStart = (e: DragEvent<HTMLDivElement>, id: number) => {
    e.dataTransfer.setData('text/plain', id.toString());  // 存储id, 和 data-XX一个道理
  };
  • content 的逻辑代码
   <div
        id="content"
        onDrop={handleDrop}
        style={{
          width: '300px',
          height: '300px',
          margin: '30px',
          backgroundColor: 'blue',
          position: 'relative',
        }}
      >
        content
        {demos.map((demo) => (
          <div
            key={demo.id}
            style={{
              width: '100px',
              height: '100px',
              backgroundColor: 'red',
              position: 'absolute',
              left: `${demo.x}px`,
              top: `${demo.y}px`,
            }}
          >
            demo {demo.id}
          </div>
        ))}
      </div>
  const handleDrop = (e: DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    const clientX = e.clientX;
    const clientY = e.clientY;
    const contentStyle = document
      .getElementById('content')
      .getBoundingClientRect();

    const x = clientX - contentStyle.left
    const y = clientY - contentStyle.top;
    const newDemo: Demo = { x, y, id: +new Date() };
    setDemos([...demos, newDemo]);
  };

上面代码测试结果:
在这里插入图片描述

代码测试 ,会有一些偏差,原因是 鼠标拖拽的位置的不是红色div的左上角顶点, 这样的就不会发生偏移, 但是实际情况无法保证每次都是拖拽顶点, 那需要在开始拖拽的计算的鼠标相对于红色div的偏移值

情况二:完整的代码

import React, { useState, DragEvent, useEffect, MouseEvent } from 'react';

interface Demo {
  id: number;
  x: number;
  y: number;
}

const App: React.FC = () => {
  const [demos, setDemos] = useState<Demo[]>([]);

  const handleDragStart = (e: DragEvent<HTMLDivElement>, id: number) => {
    e.dataTransfer.setData('text/plain', id.toString());

    const offsetX = e.clientX - e.currentTarget.getBoundingClientRect().left;
    const offsetY = e.clientY - e.currentTarget.getBoundingClientRect().top;
    e.dataTransfer.setData('offsetX', offsetX.toString());
    e.dataTransfer.setData('offsetY', offsetY.toString());
  };

  const handleDrop = (e: DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    const clientX = e.clientX;
    const clientY = e.clientY;
    const contentStyle = document
      .getElementById('content')
      .getBoundingClientRect();
    const offsetX = e.dataTransfer.getData('offsetX');
    const offsetY = e.dataTransfer.getData('offsetY');
    const x = clientX - contentStyle.left - offsetX;
    const y = clientY - contentStyle.top - offsetY;
    const newDemo: Demo = { x, y, id: +new Date() };
    setDemos([...demos, newDemo]);
  };

  const handleDragOver = (e: DragEvent<HTMLDivElement>) => {
    e.preventDefault();
  };

  const onMouseDown = (e: MouseEvent<HTMLDivElement>) => {
    console.info('onMouseDown', e);
  };

  const onMouseUp = (e: MouseEvent<HTMLDivElement>) => {
    console.info('onMouseUp', e);
  };

  const onDragEnd = (e: MouseEvent<HTMLDivElement>) => {
    console.info('onDragEnd', e);
  };

  return (
    <div>
      <div
        id="demo"
        draggable
        onDragStart={(e) => handleDragStart(e, 1)}
        onDragEnd={onDragEnd}
        style={{
          width: '100px',
          height: '100px',
          backgroundColor: 'red',
          margin: '30px',
        }}
      >
        demo2
      </div>
      <div
        id="content"
        onDrop={handleDrop}
        onDragOver={handleDragOver}
        onMouseDown={onMouseDown}
        onMouseUp={onMouseUp}
        style={{
          width: '300px',
          height: '300px',
          margin: '30px',
          backgroundColor: 'blue',
          position: 'relative',
        }}
      >
        content
        {demos.map((demo) => (
          <div
            key={demo.id}
            style={{
              width: '100px',
              height: '100px',
              backgroundColor: 'red',
              position: 'absolute',
              left: `${demo.x}px`,
              top: `${demo.y}px`,
            }}
          >
            demo {demo.id}
          </div>
        ))}
      </div>
    </div>
  );
};

export default App;

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用React和DataV来构建可视化大屏编辑器React是一个用于构建用户界面的JavaScript库,而DataV是一个由阿里巴巴开发的数据可视化工具,可以帮助你快速创建交互式的大屏展示。 下面是一些步骤,可以帮助你开始构建这样的编辑器: 1. 安装React:使用npm或yarn安装React库。可以通过以下命令进行安装: ``` npm install react ``` 2. 创建React应用:使用create-react-app等工具创建一个新的React应用。运行以下命令: ``` npx create-react-app datav-editor ``` 3. 安装DataV:使用npm或yarn安装DataV库。可以通过以下命令进行安装: ``` npm install @antv/data-set npm install @antv/g2 ``` 4. 创建可视化大屏编辑器组件:在React应用中创建一个新的组件,用于展示和编辑可视化大屏。你可以使用DataV提供的图表组件和数据集处理功能来实现可视化效果。 5. 编辑器功能实现:为编辑器组件添加一些功能,比如增加、删除、移动和调整可视化组件的位置和大小等。你可以使用React的状态管理来保存和更新编辑器状态。 6. 保存和导出:实现保存和导出编辑器中的可视化大屏配置。你可以使用浏览器的本地存储或将配置保存到后端服务器。 7. 预览和发布:添加预览功能,让用户可以在编辑器中实时查看可视化大屏的效果。并实现发布功能,将编辑好的可视化大屏展示给其他用户。 以上是一个简单的步骤,可以帮助你开始构建React和DataV的可视化大屏编辑器。当然,具体的实现还需要根据你的需求进行调整和扩展。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值