React-dnd: Toque no backend

Criado em 27 out. 2014  ·  25Comentários  ·  Fonte: react-dnd/react-dnd

Seria matador se houvesse um back-end de toque que fosse ativado automaticamente para dispositivos de toque.

enhancement

Comentários muito úteis

Para aqueles que vêm depois de mim, aqui parece ser o caminho a seguir https://github.com/LouisBrunner/react-dnd-multi-backend

Todos 25 comentários

De fato! Vou examinar isso na próxima semana.

Eu fiz algo assim usando eventos de ponteiro: nenhum; para que os elementos sob o item que está sendo arrastado possam passar por eventos do mouse; estou interessado em ver que outras maneiras existem para lidar com isso

O que são bibliotecas de arrastar e soltar de última geração usando o touchmove? jQuery UI? Precisamos encontrar uma boa solução e adotar seus truques.

Eu acho que seria melhor e no espírito desta biblioteca evitar qualquer manipulação DOM (como as bibliotecas populares fazem, seja clonando o nó para visualização, alterando seu translateX / Y, etc) e, em vez disso, deixe o consumidor desenhar "camada de arrastar" e dar ao consumidor os dados necessários para isso.

Em outras palavras, se o componente Card for arrastado com o backend de toque, o react-dnd não tentará movê-lo de alguma forma. Depende de você renderizar algum componente de "camada" na parte superior do seu aplicativo. Este componente usará DragLayerMixin fornecido por react-dnd para aprender sobre o elemento atual, sua posição, etc. Ele decide como renderizar o item arrastado com base em seu tipo e também é 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, esta abordagem abre possibilidades muito interessantes porque _para alguns aplicativos_ a camada de arrastar _é_ o que contém itens arrastáveis. A camada de arrastar não _decisa_ ser separada, embora possa, se necessário.

Para aplicativos onde os itens são arrastados sobre algum contêiner, este contêiner pode usar DragLayerMixin e, assim, aprender sobre a posição atual de arrastar e mover elementos reais conforme ocorre o arrasto:

screen shot 2014-10-28 at 20 30 15

Para aplicativos como o Trello, onde os itens são arrastados pela tela em diferentes contêineres, pode ser útil ter um componente de nível superior separado usando DragLayerMixin para renderizar o item atualmente posicionado absolutamente arrastado.

Isso faz muitosentido. Quase qualquer navegador, seja desktop ou móvel, deve ser capaz de animar suavemente um item pela tela. Isso tornaria mais fácil adicionar efeitos 3D legais como o Trello faz ao mover um cartão.

Isso também permitiria definir o cursor do mouse enquanto arrasta e uma renderização de espaço reservado mais flexível ... Coisas que você realmente não pode fazer com a API DND nativa

Acabei de perceber que podemos _também_ disponibilizar essa API de "camada de arrasto" para a API de D&D do navegador. Basta definir dragImage para um pixel transparente como neste exemplo e desenhar o que quiser.

@nelix @KyleAMathews

Tenho uma prova de conceito aqui: http://gaearon.github.io/react-dnd/#/drag -around-experimental

Ele piscará enquanto você o move :-) (ainda não funciona no Firefox)

Código-fonte 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 você pode ver, cabe ao consumidor desenhar a camada de arrasto e os componentes nela, por isso é realmente flexível.

Vou tentar terminar isso esta semana como um trampolim para tocar o suporte, e depois disso não deve ser difícil fazer o mesmo para o modo de toque.

Usamos uma camada de arrastar muito parecida com esta, mas usamos onMouseMove etc para que você possa alterar o cursor do mouse ...
Uma preocupação menor, mas muito importante para nós. Ele também permite o uso do mesmo código para eventos de toque e ponteiro.
Ainda assim, as coisas do DragLayer são um passo na direção certa para mim, uma vez que você toque no suporte, eu estaria disposto a tentar estendê-lo para oferecer suporte a eventos de ponteiro e mouse se você estiver interessado em tê-los como recursos.

Eu gostaria de ter a API HTML5 D&D como o back-end padrão e, em seguida, fazer com que os back-ends baseados em toque / mousemove sejam opt-in.

HTML5 D&D seria o mais simples (sem necessidade de arrastar camada, tudo gerenciado pelo navegador). Optar por mover o mouse / touchmove exigiria que você implemente uma camada de arrastar para desenhar o que quiser.

Faz sentido?

Claro que sim, era o que eu esperava que acontecesse.
HTML5 D&D é rápido e (além das peculiaridades) muito simples de usar, então é a escolha óbvia por padrão.

Eu só tinha uma solicitação para ativar esse toque de arrastar e soltar. Alguém já fez isso e quer compartilhar dicas?

@Georgette

@nelix começou a trabalhar no backend de mousemove , faremos touchmove backend depois disso.

Você pode ver o trabalho em andamento aqui: https://github.com/nelix/react-dnd/commit/8de7f7fe24c7ae397a971c517dada9323e6c27f0 (ainda está longe de ser feito e realmente não funciona neste ponto). Ainda precisamos descobrir quais partes permanecem em DragDropMixin e quais precisam ser movidas para backends/HTML5 (e outros back-ends).

Se você gostaria de trabalhar nisso, você pode começar com esse commit e continuar implementando o back-end do mousemove. Quando funcionar, não deve ser difícil implementar um back-end touchmove semelhante.

Por favor, se você gostaria de trabalhar nisso, mantenha-nos atualizados aqui ou na sala do Gitter, para que não fiquemos com duas implementações.

Aqui está uma prova de conceito de suporte de toque: https://github.com/gaearon/react-dnd/pull/143

Você pode brincar com ele: http://rawgit.com/gaearon/react-dnd/touch-poc/examples/index.html

Ele usa back-end de HTML5 no desktop e back-end de toque no celular.
Apenas o exemplo de renderização personalizada mostrará uma visualização de arrastar no celular.

Isso parece bastante promissor! Alguma ideia de quando isso pode pousar? :)

Atualmente estou ocupado com outro projeto e estarei até julho.
Talvez eu consiga trabalhar nisso em algum lugar em julho ou agosto, mas ficarei feliz se alguém me antecipar :-)

já que 1.1 foi mencionado neste tópico e v1.1.4 foi lançado. Só estou me perguntando se a prova de conceito acima já está incluída em 1.1.4?

Não.

Eu não deveria ter usado um número de versão preciso porque você nunca sabe quando vai bater :-)

Atualmente não tenho tempo para trabalhar nisso, mas a prova de conceito está no PR. Provavelmente atualizarei o PR para refletir a API atual e esperarei que alguém realmente o implemente.

Vamos continuar a discussão em https://github.com/gaearon/react-dnd/pull/240.

Para aqueles que vêm depois de mim, aqui parece ser o caminho a seguir https://github.com/LouisBrunner/react-dnd-multi-backend

Eu escrevi este trecho:

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 eu uso assim:

DragDropContext(multiBackends(
      ReactDnDHTML5Backend,
      ReactDnDTouchBackend,
  ))

react-dnd-html5-backend e react-dnd-touch-backend ouvem um conjunto disjunto de eventos. (dragstart, dragend, dragenter, dragleave dragover e drop vs touchstart, touchend e touchmove).

Alguns testes básicos e funciona bem, meu arrastar e soltar agora suporta eventos de toque e mouse ao mesmo tempo.

Há alguma razão para não funcionar?

Esta página foi útil?
0 / 5 - 0 avaliações