React-dnd: Toque backend

Creado en 27 oct. 2014  ·  25Comentarios  ·  Fuente: react-dnd/react-dnd

Sería increíble si hubiera un backend táctil que se activara automáticamente para los dispositivos táctiles.

enhancement

Comentario más útil

Para aquellos que vienen después de mí, este parece ser el camino a seguir https://github.com/LouisBrunner/react-dnd-multi-backend

Todos 25 comentarios

¡En efecto! Lo investigaré la semana que viene.

Hice algo como esto usando pointer-events: none; por lo que los elementos debajo del elemento que se arrastra podrían atrapar los eventos del mouse sobre; Estoy interesado en ver qué otras formas hay de abordar esto.

¿Qué son las bibliotecas de arrastrar y soltar de última generación que utilizan touchmove? jQuery UI? Necesitamos buscar una buena solución y adoptar sus trucos.

Creo que sería mejor y en el espíritu de esta biblioteca evitar cualquier manipulación DOM (como hacen las bibliotecas populares, ya sea clonando el nodo para la vista previa, cambiando su translateX / Y, etc.) y, en su lugar, dejar que el consumidor dibuje una "capa de arrastre". y proporcionar al consumidor los datos necesarios para ello.

En otras palabras, si el componente Card se arrastra con el backend táctil, react-dnd no intentará moverlo de alguna manera. Depende de usted renderizar algún componente de "capa" en la parte superior de su aplicación. Este componente usará DragLayerMixin proporcionado por react-dnd para aprender sobre el elemento actual, su posición, etc. Decide cómo renderizar el elemento arrastrado según su tipo y también es 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' />;
  }
});

Por cierto, este enfoque abre posibilidades realmente interesantes porque _para algunas aplicaciones_ capa de arrastre _ es_ lo que contiene elementos que se pueden arrastrar. La capa de arrastre no tiene que estar separada, aunque puede hacerlo si es necesario.

Para las aplicaciones donde los elementos se arrastran sobre algún contenedor, este contenedor puede usar DragLayerMixin y así aprender sobre la posición actual de arrastre y mover elementos reales a medida que se produce el arrastre:

screen shot 2014-10-28 at 20 30 15

Para aplicaciones como Trello, donde los elementos se arrastran a través de la pantalla a través de diferentes contenedores, puede ser útil tener un componente de nivel superior separado usando DragLayerMixin para representar el elemento arrastrado actualmente absolutamente posicionado.

Esto tiene mucho sentido. Casi cualquier navegador, ya sea de escritorio o móvil, debería poder animar sin problemas un elemento alrededor de la pantalla. Esto facilitaría agregar efectos 3D geniales como lo hace Trello al mover una tarjeta.

Esto también permitiría configurar el cursor del mouse mientras se arrastra y una representación de marcador de posición más flexible ... Cosas que realmente no puede hacer con la API nativa de DND

Me acabo de dar cuenta de que _también_ podemos hacer que esta API de "capa de arrastre" esté disponible para la API de D&D del navegador. Simplemente configure dragImage en un píxel transparente como en este ejemplo y dibuje lo que quiera.

@nelix @KyleAMathews

Tengo una prueba de concepto aquí: http://gaearon.github.io/react-dnd/#/drag -around-experimental

Parpadeará mientras lo mueves :-) (todavía no funcionará en Firefox)

Código fuente relevante:

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

Como puede ver, depende del consumidor dibujar la capa de arrastre y los componentes en ella, por lo que es realmente flexible.

Intentaré terminar esto esta semana como un trampolín para tocar el soporte, y después de eso no debería ser difícil hacer lo mismo para el modo táctil.

Usamos una capa de arrastre muy parecida a esta, pero usamos onMouseMove, etc. para que pueda cambiar el cursor del mouse ...
Una preocupación menor pero muy importante para nosotros. También permite usar casi el mismo código para eventos táctiles y de puntero.
Aún así, las cosas de DragLayer son un paso en la dirección correcta para mí, una vez que toque el soporte, estaría dispuesto a intentar extenderlo para admitir eventos de puntero y mouse si está interesado en tenerlos como características.

Me gustaría tener HTML5 D&D API como el backend predeterminado y luego hacer que los backend basados ​​en touch / mousemove opten.

HTML5 D&D sería el más simple (sin necesidad de una capa de arrastre, todo administrado por el navegador). Optar por los mousemove / touchmove requeriría que implementes una capa de arrastre para dibujar lo que quieras.

¿Tiene sentido?

Claro que sí, eso es lo que esperaba que sucediera.
HTML5 D&D es rápido y (además de las peculiaridades) bastante simple de usar, por lo que es la opción obvia por defecto.

Así que acabo de recibir una solicitud para habilitar este toque de arrastrar y soltar. ¿Alguien ha hecho esto y quiere compartir consejos?

@Georgette

@nelix comenzó a trabajar en mousemove backend, después de eso haremos touchmove backend.

Puede ver el trabajo en progreso aquí: https://github.com/nelix/react-dnd/commit/8de7f7fe24c7ae397a971c517dada9323e6c27f0 (todavía está lejos de estar terminado y realmente no funciona en este momento). Todavía necesitamos averiguar qué partes permanecen en DragDropMixin y cuáles deben moverse a backends/HTML5 (y otros backends).

Si desea trabajar en eso, puede comenzar con ese compromiso y seguir implementando mousemove backend. Cuando funciona, no debería ser difícil implementar un backend táctil similar.

Por favor, si desea trabajar en esto, manténganos actualizados aquí o en la sala de Gitter, para que no terminemos con dos implementaciones.

Aquí hay una prueba del concepto de soporte táctil: https://github.com/gaearon/react-dnd/pull/143

Puedes jugar con él: http://rawgit.com/gaearon/react-dnd/touch-poc/examples/index.html

Utiliza backend HTML5 en escritorio y backend táctil en dispositivos móviles.
Solo el ejemplo de

¡Esto parece bastante prometedor! ¿Alguna idea de cuándo podría aterrizar? :)

Actualmente estoy ocupado con otro proyecto y lo estaré hasta julio.
Podría trabajar en esto en algún lugar de julio o agosto, pero estaré feliz si alguien se me adelanta :-)

ya que 1.1 se mencionó en este hilo y v1.1.4 está fuera. Me pregunto si la prueba de concepto anterior ya está incluida en 1.1.4.

No

No debería haber usado un número de versión preciso porque nunca sabes cuándo vas a chocar :-)

Actualmente no tengo tiempo para trabajar en esto, pero la prueba de concepto está en el PR. Probablemente actualizaré el PR para reflejar la API actual y esperaré a que alguien realmente lo implemente.

Continuemos la discusión en https://github.com/gaearon/react-dnd/pull/240.

Para aquellos que vienen después de mí, este parece ser el camino a seguir https://github.com/LouisBrunner/react-dnd-multi-backend

Escribí este fragmento:

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

Que uso así:

DragDropContext(multiBackends(
      ReactDnDHTML5Backend,
      ReactDnDTouchBackend,
  ))

react-dnd-html5-backend y react-dnd-touch-backend escuchan un conjunto de eventos inconexos. (dragstart, dragend, dragenter, dragleave dragover y drop vs touchstart, touchmove y touchmove).

Algunas pruebas básicas y funciona bien, mi arrastrar y soltar ahora admite eventos táctiles y de mouse al mismo tiempo.

¿Hay alguna razón por la que no funcionaría?

¿Fue útil esta página
0 / 5 - 0 calificaciones