简体   繁体   English

Interact.js 中的垂直可滚动拖放区

[英]Vertically Scrollable Dropzone in Interact.js

Use Case:用例:

What i am trying to do is to create a pdf editior, so there are fields such as textbox etc on the right side and a pdf on the left side.我要做的是创建一个 pdf 编辑器,因此右侧有文本框等字段,左侧有 pdf。 the user can drag and drop a field onto the pdf.用户可以将字段拖放到 pdf 上。 (and then write inside the fields and save it which will generate a new pdf, this part isn't relative to the question) (然后在字段中写入并保存,这将生成一个新的 pdf,这部分与问题无关)

See the photo below for better understanding请参阅下面的照片以更好地理解

在此处输入图像描述

Current Effort:目前的努力:

To achieve the task i am using interact.js .为了完成我正在使用的任务interact.js (the code below is a minimal example without the pdf) (下面的代码是一个没有 pdf 的最小示例)

I create an Interactable.js file which serves as a wrapper我创建了一个用作包装器的Interactable.js文件

Interactable.js可交互的.js

import React, { Component, cloneElement } from "react";
import PropTypes from "prop-types";
import { findDOMNode } from "react-dom";
import interact from "interact.js";
export default class Interactable extends Component {
  static defaultProps = {
    draggable: false,
    dropzone: false,
    resizable: false,
    draggableOptions: {},
    dropzoneOptions: {},
    resizableOptions: {},
  };

  render() {
    return cloneElement(this.props.children, {
      ref: (node) => (this.node = node),
      draggable: false,
    });
  }

  componentDidMount() {
    this.interact = interact(findDOMNode(this.node));
    this.setInteractions();
  }

  componentWillReceiveProps() {
    this.interact = interact(findDOMNode(this.node));
    this.setInteractions();
  }

  setInteractions() {
    if (this.props.draggable)
      this.interact.draggable(this.props.draggableOptions)
    if (this.props.dropzone) this.interact.dropzone(this.props.dropzoneOptions)
    if (this.props.resizable)
      this.interact.resizable(this.props.resizableOptions);
  }
}

Interactable.propTypes = {
  children: PropTypes.node.isRequired,
  draggable: PropTypes.bool,
  draggableOptions: PropTypes.object,
  dropzone: PropTypes.bool,
  dropzoneOptions: PropTypes.object,
  resizable: PropTypes.bool,
  resizableOptions: PropTypes.object,
};

I wrap the Dropzone and DragItems into the Interactable component我将DropzoneDragItems包装到Interactable组件中

App.js应用程序.js

import "./App.css";
import Interactable from "./Interactable";

function App() {
  const draggableOptions = {
    onmove: (event) => {
      // console.log(event);
      const target = event.target;
      // keep the dragged position in the data-x/data-y attributes
      const x = (parseFloat(target.getAttribute("data-x")) || 0) + event.dx;
      const y = (parseFloat(target.getAttribute("data-y")) || 0) + event.dy;

      // translate the element
      target.style.webkitTransform = target.style.transform =
        "translate(" + x + "px, " + y + "px)";

      // update the posiion attributes
      target.setAttribute("data-x", x);
      target.setAttribute("data-y", y);
    },
  };
  return (
    <div className="MainContainer">
      <div className="DropzoneContainer">
        <Interactable
          dropzone={true}
          dropzoneOptions={{
            accept: ".drag-item",
            overlap: 0.75,
            ondropactivate: function (event) {
              event.target.classList.add("drop-active");
            },

            ondragenter: function (event) {
              var draggableElement = event.relatedTarget,
                dropzoneElement = event.target;
              dropzoneElement.classList.add("drop-target");
              draggableElement.classList.add("can-drop");
            },

            ondragleave: function (event) {
              event.target.classList.remove("drop-target");
              event.relatedTarget.classList.remove("can-drop");
              event.relatedTarget.textContent = "Dragged out";
            },

            ondrop: function (event) {
              console.log(event);
            },

            ondropdeactivate: function (event) {
              event.target.classList.remove("drop-active");
              event.target.classList.remove("drop-target");
            },
          }}
        >
          <div className="dropzone" id="outer-dropzone">
            <div className="DropzoneContent">
              Dropzone Content here
            </div>
          </div>
        </Interactable>
      </div>
      <div className="dragItems" >
        <Interactable
          draggable={true}
          draggableOptions={draggableOptions}
        >
          <div className="draggable drag-item" >
            Drag Item 1
          </div>
        </Interactable>
        <Interactable
          draggable={true}
          draggableOptions={draggableOptions}
        >
          <div className="draggable drag-item" >
            Drag Item 2
          </div>
        </Interactable>
      </div>
    </div>
  );
}

export default App;

Issue:问题:

Currently the issue that i am facing is that when i drag and drop a drag-item onto the dropzone ,it does not move when i scroll the dropzone .目前我面临的问题是,当我将drag-itemdropzone上时,当我滚动dropzone时它不会移动。 it should be as if it is inside the dropzone .它应该就像在dropzone内一样。 i have tried tweaking with the CSS and taking a closer look at the interact.js documentation but i have had no luck.我尝试使用 CSS 进行调整,并仔细查看 interact.js 文档,但我没有运气。

So if someone could help me out or point me in the right direction, i would really appreciate it, Cheers!因此,如果有人可以帮助我或为我指明正确的方向,我将不胜感激,干杯!

Codesandbox here代码沙盒在这里

Github Repo here Github 回购在这里

Add autoScroll: true in draggableOptions .draggableOptions添加autoScroll: true

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM