React-dnd: Berühren Sie das Backend

Erstellt am 27. Okt. 2014  ·  25Kommentare  ·  Quelle: react-dnd/react-dnd

Es wäre mörderisch, wenn es ein Touch-Backend gäbe, das für Touch-Geräte automatisch eingeschaltet würde.

enhancement

Hilfreichster Kommentar

Für diejenigen, die nach mir kommen, scheint hier der Weg nach vorne zu sein: https://github.com/LouisBrunner/react-dnd-multi-backend

Alle 25 Kommentare

Tatsächlich! Ich werde das nächste Woche untersuchen.

Ich habe so etwas mit Zeigerereignissen gemacht: keine; So können die Elemente unter dem Element, das gezogen wird, die Maus über Ereignisse fangen. Ich bin daran interessiert zu sehen, wie es andere Möglichkeiten gibt, dies anzugehen

Was sind hochmoderne Drag & Drop-Bibliotheken mit Touchmove? jQuery-Benutzeroberfläche? Wir müssen uns eine gute Lösung ansehen und ihre Tricks anwenden.

Ich habe keines davon für Projekte verwendet, aber Googeln hat Folgendes gefunden:

Ich denke, es wäre am besten und im Geiste dieser Bibliothek, jede DOM-Manipulation zu vermeiden (wie es gängige Bibliotheken tun, sei es durch Klonen des Knotens für die Vorschau, Ändern von translateX / Y usw.) und stattdessen den Verbraucher "Drag Layer" zeichnen zu lassen. und geben Sie dem Verbraucher die notwendigen Daten dafür.

Mit anderen Worten, wenn die Komponente Card mit dem Touch-Backend gezogen wird, versucht react-dnd nicht, sie selbst zu verschieben. Es liegt an Ihnen, eine "Ebenen" -Komponente oben in Ihrer App zu rendern. Diese Komponente verwendet DragLayerMixin das von react-dnd bereitgestellt wird, um Informationen zum aktuellen Element, seiner Position usw. zu erhalten. Sie entscheidet, wie das gezogene Element basierend auf seinem Typ gerendert wird, und ist auch 100% React.

var App = React.createClass({
  render() {
    return (
      <div>
       {this.props.activeRouteHandler />
       <DragDropLayer />
      </div>
    );
  }
});

var { DragLayerMixin } = require('react-dnd');

var DragDropLayer = React.createClass({
  mixins: [DragLayerMixin],

  render() {

    // With non-native dragging backend, rendering items in the process of dragging is your responsibility. 
    // It's up to you to use translate3d or top/left, render thumbnails or real components, etc.

    var {
      draggedItem,
      draggedItemType,
      clientX,
      clientY
    } = this.getDragLayerState(); // provided by mixin

    if (!draggedItem) {
      return null;
    }

    return (
      <div style={{zIndex: 10000, pointerEvents: 'none', position: 'absolute'}}>
        {draggedItem &&
          <div style={{transform: `translate3d(${clientX}, ${clientY}, 0)`}}>
            {this.renderItem(draggedItemType, draggedItem)}
          </div>
        }
      </div>
    );
  },

  renderItem(type, item) {

    // It's completely up to the consumer to specify how to render different types

    switch (type) {
    case ItemTypes.Card:
      return <Card title={item.title} />;
    case ItemTypes.List:
      return <img src='thumbnail.jpg' />;
  }
});

Übrigens eröffnet dieser Ansatz wirklich coole Möglichkeiten, da für einige Apps die Drag-Ebene das ist, was ziehbare Elemente enthält. Die Drag-Ebene muss nicht getrennt sein, obwohl dies bei Bedarf möglich ist.

Bei Apps, bei denen Elemente auf einen Container gezogen werden, kann dieser Container DragLayerMixin und so die aktuelle Ziehposition kennenlernen und beim Ziehen echte Elemente verschieben:

screen shot 2014-10-28 at 20 30 15

Für Apps wie Trello, bei denen Elemente über verschiedene Container hinweg über den Bildschirm gezogen werden, kann es nützlich sein, eine separate Komponente der obersten Ebene zu verwenden, die DragLayerMixin , um absolut positionierte aktuell gezogene Elemente zu rendern.

Das macht sehr viel Sinn. Fast jeder Browser, egal ob Desktop oder Handy, sollte in der Lage sein, ein Element auf dem Bildschirm reibungslos zu animieren. Dies würde es dann einfach machen, coole 3D-Effekte hinzuzufügen, wie es Trello beim Verschieben einer Karte tut.

Dies würde auch das Setzen des Mauszeigers beim Ziehen und flexibleres Platzieren von Platzhaltern ermöglichen ... Dinge, die Sie mit der nativen DND-API nicht wirklich tun können

Ich habe gerade festgestellt, dass wir diese "Drag Layer" -API auch für die Browser-D & D-API verfügbar machen können. Setzen Sie einfach dragImage auf ein transparentes Pixel wie in diesem Beispiel und zeichnen Sie, was Sie wollen.

@nelix @KyleAMathews

Ich habe hier einen Proof of Concept: http://gaearon.github.io/react-dnd/#/drag -around-experimentell

Es blinkt, während Sie es verschieben :-) (funktioniert in Firefox noch nicht)

Relevanter Quellcode:

https://github.com/gaearon/react-dnd/blob/experiments/examples/_drag-around-experimental/index.js#L14

https://github.com/gaearon/react-dnd/blob/experiments/examples/_drag-around-experimental/DragLayer.js

https://github.com/gaearon/react-dnd/blob/experiments/examples/_drag-around-experimental/Box.js#L69

Wie Sie sehen können, ist es Sache des Verbrauchers, Drag-Layer und Komponenten darauf zu zeichnen, sodass es wirklich flexibel ist.

Ich werde versuchen, dies diese Woche als Sprungbrett für die Touch-Unterstützung zu beenden, und danach sollte es nicht schwierig sein, dasselbe für den Touch-Modus zu tun.

Wir verwenden eine ähnliche Drag-Ebene, aber wir verwenden onMouseMove usw., damit Sie den Mauszeiger ändern können ...
Ein kleines, aber sehr wichtiges Anliegen für uns. Es ermöglicht auch die Verwendung von größtenteils demselben Code für Berührungs- und Zeigerereignisse.
Trotzdem ist das DragLayer-Zeug für mich ein Schritt in die richtige Richtung. Wenn Sie einmal die Unterstützung berühren, würde ich gerne versuchen, diese zu erweitern, um Zeiger- und Mausereignisse zu unterstützen, wenn Sie daran interessiert sind, diese als Funktionen zu verwenden.

Ich möchte die HTML5-D & D-API als Standard-Backend verwenden und dann das Touch-basierte / Mousemove-basierte Backend aktivieren.

HTML5 D & D wäre das einfachste (keine Drag-Ebene erforderlich, alles vom Browser verwaltet). Wenn Sie sich für Mousemove / Touchmove entscheiden, müssen Sie eine Drag-Ebene implementieren, um zu zeichnen, was Sie möchten.

Macht Sinn?

Klar, das habe ich mir erhofft.
HTML5 D & D ist schnell und (abgesehen von den Macken) ziemlich einfach zu bedienen, daher ist es standardmäßig die offensichtliche Wahl.

Ich hatte gerade die Anfrage, diese Drag & Drop-Berührung zu aktivieren. Hat jemand dies getan und möchte Tipps teilen?

@Georgette

@nelix hat mit der Arbeit am mousemove Backend begonnen, danach machen wir das touchmove Backend.

Sie können sich die laufenden Arbeiten hier ansehen: https://github.com/nelix/react-dnd/commit/8de7f7fe24c7ae397a971c517dada9323e6c27f0 (es ist noch lange nicht erledigt und funktioniert derzeit nicht wirklich). Wir müssen noch herausfinden, welche Teile in DragDropMixin verbleiben und welche in backends/HTML5 (und andere Backends) verschoben werden müssen.

Wenn Sie daran arbeiten möchten, können Sie mit diesem Commit beginnen und das Mousemove-Backend weiter implementieren. Wenn es funktioniert, sollte es nicht schwierig sein, ein ähnliches Touchmove-Backend zu implementieren.

Wenn Sie daran arbeiten möchten, halten Sie uns bitte hier oder im Gitterraum auf dem Laufenden, damit wir nicht zwei Implementierungen erhalten.

Hier ist ein Proof of Concept für die Touch-Unterstützung: https://github.com/gaearon/react-dnd/pull/143

Sie können damit spielen: http://rawgit.com/gaearon/react-dnd/touch-poc/examples/index.html

Es verwendet HTML5-Backend auf dem Desktop und Touch-Backend auf Mobilgeräten.
Nur ein benutzerdefiniertes Rendering- Beispiel zeigt eine Drag-Vorschau auf Mobilgeräten an.

Das scheint ziemlich vielversprechend! Irgendwelche Ideen, wann dies landen könnte? :) :)

Ich bin derzeit mit einem anderen Projekt beschäftigt und werde bis Juli sein.
Ich könnte vielleicht irgendwo im Juli oder August daran arbeiten, aber ich würde mich freuen, wenn mich jemand schlägt :-)

da 1.1 in diesem Thread erwähnt wurde und v1.1.4 raus ist. Ich frage mich nur, ob der oben genannte Proof of Concept bereits in 1.1.4 enthalten ist.

Nee.

Ich hätte keine genaue Versionsnummer verwenden sollen, weil du nie weißt, wann du stoßen wirst :-)

Ich habe derzeit keine Zeit, daran zu arbeiten, aber der Proof of Concept befindet sich in der PR. Ich werde wahrscheinlich die PR aktualisieren, um die aktuelle API wiederzugeben, und darauf warten, dass jemand sie tatsächlich implementiert.

Lassen Sie uns die Diskussion unter https://github.com/gaearon/react-dnd/pull/240 fortsetzen.

Für diejenigen, die nach mir kommen, scheint hier der Weg nach vorne zu sein: https://github.com/LouisBrunner/react-dnd-multi-backend

Ich habe diesen Ausschnitt geschrieben:

function multiBackends(...backendFactories) {
  return function(manager) {
    const backends = backendFactories.map(b => b(manager));
    return {
      setup: (...args) =>
          backends.forEach(b => b.setup.apply(b, args)),
      teardown: (...args) =>
          backends.forEach(b => b.teardown.apply(b, args)),
      connectDropTarget: (...args) =>
          backends.forEach(b => b.connectDropTarget.apply(b, args)),
      connectDragPreview: (...args) =>
          backends.forEach(b => b.connectDragPreview.apply(b, args)),
      connectDragSource: (...args) =>
          backends.forEach(b => b.connectDragSource.apply(b, args)),
    };
  };
}

Was ich so benutze:

DragDropContext(multiBackends(
      ReactDnDHTML5Backend,
      ReactDnDTouchBackend,
  ))

react-dnd-html5-backend und react-dnd-touch-backend hören sich eine disjunkte Reihe von Ereignissen an. (Dragstart, Dragend, Dragenter, Dragleave Dragover und Drop gegen Touchstart, Touchend und Touchmove).

Einige grundlegende Tests und es funktioniert einwandfrei. Mein Drag & Drop unterstützt jetzt gleichzeitig Berührungs- und Mausereignisse.

Gibt es Gründe, warum es nicht funktionieren würde?

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen