React-dnd: Touchez le backend

Créé le 27 oct. 2014  ·  25Commentaires  ·  Source: react-dnd/react-dnd

Ce serait tueur s'il y avait un backend tactile qui serait automatiquement activé pour les appareils tactiles.

enhancement

Commentaire le plus utile

Pour ceux qui viennent après moi, voici la voie à suivre https://github.com/LouisBrunner/react-dnd-multi-backend

Tous les 25 commentaires

En effet! J'examinerai cela la semaine prochaine.

J'ai fait quelque chose comme ça en utilisant des événements de pointeur: aucun; de sorte que les éléments sous l'élément en cours de déplacement pourraient capturer la souris sur les événements; Je suis intéressé à voir de quelles autres façons il existe de résoudre ce problème

Que sont les bibliothèques de glisser-déposer de pointe utilisant touchmove? jQuery UI? Nous devons chercher une bonne solution et adopter ses astuces.

Je pense qu'il serait préférable et dans l'esprit de cette bibliothèque d'éviter toute manipulation DOM (comme le font les bibliothèques populaires, que ce soit en clonant un nœud pour l'aperçu, en changeant son translateX / Y, etc.), et en laissant plutôt le consommateur dessiner "glisser la couche" et fournissez aux consommateurs les données nécessaires à cet effet.

En d'autres termes, si le composant Card est glissé avec le backend tactile, react-dnd n'essaiera pas de le déplacer lui-même. C'est à vous de rendre un composant de "couche" en haut de votre application. Ce composant utilisera DragLayerMixin fourni par react-dnd pour en savoir plus sur l'élément courant, sa position, etc. Il décide comment rendre l'élément glissé en fonction de son type et est également 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' />;
  }
});

BTW, cette approche ouvre des possibilités vraiment intéressantes car _pour certaines applications_ faites glisser la couche _est_ ce qui contient des éléments déplaçables. Le calque de glissement ne _ doit pas être_ séparé, bien qu'il le puisse, si nécessaire.

Pour les applications où des éléments sont glissés sur un conteneur, ce conteneur peut utiliser DragLayerMixin et ainsi en savoir plus sur la position actuelle du glisser et déplacer des éléments réels lorsque le glisser se produit:

screen shot 2014-10-28 at 20 30 15

Pour les applications telles que Trello où les éléments sont glissés sur l'écran à travers différents conteneurs, il peut être utile d'avoir un composant de niveau supérieur distinct en utilisant DragLayerMixin pour rendre l'élément actuellement déplacé en position absolue.

Cela a beaucoup de sens. Presque tous les navigateurs, qu'ils soient de bureau ou mobiles, devraient être capables d'animer en douceur un élément autour de l'écran. Cela faciliterait l'ajout d'effets 3D sympas comme le fait Trello lors du déplacement d'une carte.

Cela permettrait également de définir le curseur de la souris tout en faisant glisser et un rendu d'espace réservé plus flexible ... Ce que vous ne pouvez pas vraiment faire avec l'API native DND

Je viens de réaliser que nous pouvons _aussi_ rendre cette API "glisser couche" disponible pour l'API D&D du navigateur. Définissez simplement dragImage sur un pixel transparent comme dans cet exemple et dessinez ce que vous voulez.

@nelix @KyleAMathews

J'ai une preuve de concept ici: http://gaearon.github.io/react-dnd/#/drag -around-experimental

Il clignotera pendant que vous le déplacerez :-) (ne fonctionnera pas encore dans Firefox)

Code source pertinent:

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

Comme vous pouvez le voir, c'est au consommateur de dessiner la couche de glissement et les composants dessus, donc c'est vraiment flexible.

Je vais essayer de terminer cette semaine comme un tremplin pour le support tactile, et après cela, il ne devrait pas être difficile de faire de même pour le mode tactile.

Nous utilisons un calque de glisser un peu comme celui-ci, mais nous utilisons onMouseMove, etc. pour que vous puissiez changer le curseur de la souris ...
Une préoccupation mineure mais très importante pour nous. Il permet également d'utiliser principalement le même code pour les événements tactiles et pointeurs.
Pourtant, le truc de DragLayer est un pas dans la bonne direction pour moi, une fois que vous toucherez le support, je serais prêt à essayer d'étendre cela pour prendre en charge les événements de pointeur et de souris si vous êtes intéressé à avoir ces fonctionnalités?

J'aimerais avoir l'API HTML5 D&D comme backend par défaut, puis activer les backends tactiles / basés sur la souris.

HTML5 D&D serait le plus simple (pas besoin de couche de glissement, tout est géré par navigateur). Activer les mousemove / touchmove vous obligerait à implémenter un calque de glissement pour dessiner ce que vous voulez.

Logique?

Bien sûr, c'est ce que j'espérais.
HTML5 D&D est rapide et (outre les bizarreries) assez simple à utiliser, c'est donc le choix évident par défaut.

Je viens donc d'avoir une demande pour activer ce toucher par glisser-déposer. Quelqu'un a-t-il fait cela et souhaite partager des conseils?

@Crêpe georgette

@nelix a commencé à travailler sur mousemove backend, nous ferons touchmove backend après cela.

Vous pouvez consulter les travaux en cours ici: https://github.com/nelix/react-dnd/commit/8de7f7fe24c7ae397a971c517dada9323e6c27f0 (c'est encore loin d'être terminé et ne fonctionne pas vraiment à ce stade). Nous devons encore déterminer quelles parties restent dans DragDropMixin et lesquelles doivent être déplacées dans backends/HTML5 (et autres backends).

Si vous souhaitez travailler là-dessus, vous pouvez commencer avec ce commit et continuer à implémenter le backend mousemove. Quand cela fonctionne, il ne devrait pas être difficile d'implémenter un backend touchmove similaire.

S'il vous plaît, si vous souhaitez travailler là-dessus, tenez-nous au courant ici ou dans la salle Gitter, afin de ne pas nous retrouver avec deux implémentations.

Voici une preuve de concept du support tactile: https://github.com/gaearon/react-dnd/pull/143

Vous pouvez jouer avec: http://rawgit.com/gaearon/react-dnd/touch-poc/examples/index.html

Il utilise le backend HTML5 sur le bureau et le backend tactile sur mobile.
Seul l'exemple de rendu personnalisé affichera un aperçu du glissement sur mobile.

Cela semble assez prometteur! Des idées sur quand cela pourrait atterrir? :)

Je suis actuellement occupé avec un autre projet et le sera jusqu'en juillet.
Je pourrais peut-être travailler là-dessus quelque part en juillet ou en août, mais je serai heureux si quelqu'un me bat :-)

puisque 1.1 a été mentionné dans ce fil et la v1.1.4 est sortie. Je me demande juste si la preuve de concept ci-dessus est déjà incluse dans 1.1.4?

Nan.

Je n'aurais pas dû utiliser un numéro de version précis car on ne sait jamais quand on va bosse :-)

Je n'ai actuellement pas le temps de travailler là-dessus mais la preuve de concept est dans le PR. Je vais probablement mettre à jour le PR pour refléter l'API actuelle et attendre que quelqu'un la mette en œuvre.

Continuons la discussion sur https://github.com/gaearon/react-dnd/pull/240.

Pour ceux qui viennent après moi, voici la voie à suivre https://github.com/LouisBrunner/react-dnd-multi-backend

J'ai écrit cet extrait:

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)),
    };
  };
}

Ce que j'utilise comme ceci:

DragDropContext(multiBackends(
      ReactDnDHTML5Backend,
      ReactDnDTouchBackend,
  ))

react-dnd-html5-backend et react-dnd-touch-backend écoutent un ensemble disjoint d'événements. (dragstart, dragend, dragenter, dragleave dragover et drop vs touchstart, touchend et touchmove).

Quelques tests de base et cela fonctionne bien, mon glisser-déposer prend désormais en charge les événements tactiles et souris en même temps.

Y a-t-il des raisons pour lesquelles cela ne fonctionnerait pas?

Cette page vous a été utile?
0 / 5 - 0 notes