React-dnd: Сенсорный бэкэнд

Созданный на 27 окт. 2014  ·  25Комментарии  ·  Источник: react-dnd/react-dnd

Было бы здорово, если бы существовал сенсорный сервер, который автоматически подключается к сенсорным устройствам.

enhancement

Самый полезный комментарий

Для тех, кто придет после меня, это, кажется, путь вперед https://github.com/LouisBrunner/react-dnd-multi-backend

Все 25 Комментарий

Конечно! Я займусь этим на следующей неделе.

Я сделал что-то подобное, используя события-указатели: none; поэтому элементы, находящиеся под перетаскиваемым элементом, могли ловить мышь над событиями; Мне интересно узнать, какие еще есть способы решить эту проблему

Что такое современные библиотеки перетаскивания с использованием touchmove? jQuery UI? Нам нужно найти хорошее решение и применить его уловки.

Я не использовал ничего из этого в проектах, но поиск в Google обнаружил:

Я думаю, что было бы лучше и в духе этой библиотеки избегать любых манипуляций с DOM (как это делают популярные библиотеки, будь то клонирование узла для предварительного просмотра, изменение его translateX / Y и т. Д.), И вместо этого позволить потребителю рисовать «перетаскивающий слой» и предоставить потребителю необходимые для этого данные.

Другими словами, если компонент Card перетаскивается с помощью сенсорного бэкэнда, response-dnd не будет пытаться как-то переместить его сам. Вы должны отрендерить какой-нибудь «слойный» компонент в верхней части приложения. Этот компонент будет использовать DragLayerMixin предоставленный response-dnd, чтобы узнать о текущем элементе, его позиции и т. Д. Он решает, как визуализировать перетаскиваемый элемент, в зависимости от его типа и также на 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' />;
  }
});

Кстати, этот подход открывает действительно классные возможности, потому что _для некоторых приложений_ слой перетаскивания _ это_ то, что содержит перетаскиваемые элементы. Слой перетаскивания не должен быть разделен, хотя при необходимости можно.

Для приложений, в которых элементы перетаскиваются в какой-либо контейнер, этот контейнер может использовать DragLayerMixin и, таким образом, узнавать о текущей позиции перетаскивания и перемещать реальные элементы по мере перетаскивания:

screen shot 2014-10-28 at 20 30 15

Для таких приложений, как Trello, где элементы перетаскиваются по экрану в разные контейнеры, может быть полезно иметь отдельный компонент верхнего уровня, использующий DragLayerMixin для визуализации абсолютно позиционированного в данный момент перетаскиваемого элемента.

В этом есть большой смысл. Практически любой браузер, будь то настольный или мобильный, должен иметь возможность плавно анимировать элемент на экране. Это упростило бы добавление крутых 3D-эффектов, как это делает Trello при перемещении карты.

Это также позволит установить курсор мыши при перетаскивании и более гибкую визуализацию заполнителей ... То, что вы действительно не можете сделать с собственным API DND

Я только что понял, что мы можем _также_ сделать этот API "перетаскивания" доступным для D&D API браузера. Просто установите dragImage на прозрачный пиксель, как в этом примере, и нарисуйте все, что хотите.

@nelix @KyleAMathews

У меня есть доказательство концепции: http://gaearon.github.io/react-dnd/#/drag -around-experimental

Он будет мигать, пока вы его перемещаете :-) (пока не работает в Firefox)

Соответствующий исходный код:

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

Как видите, рисование перетаскиваемого слоя и компонентов зависит от потребителя, так что это действительно гибко.

Я постараюсь закончить это на этой неделе как ступеньку к сенсорной поддержке, и после этого не должно быть сложно сделать то же самое для сенсорного режима.

Мы используем слой перетаскивания примерно так же, но мы используем onMouseMove и т.д., чтобы вы могли изменить курсор мыши ...
Мелкая, но очень важная для нас проблема. Это также позволяет использовать в основном один и тот же код для событий касания и указателя.
Тем не менее, материал DragLayer - это шаг в правильном направлении для меня, как только вы сделаете поддержку касания, я был бы готов попытаться расширить его для поддержки событий указателя и мыши, если вы заинтересованы в том, чтобы они были функциями?

Я хотел бы иметь HTML5 D&D API в качестве бэкэнда по умолчанию, а затем сделать выбор в пользу бэкэндов на основе сенсорного ввода / перемещения мыши.

HTML5 D&D будет самым простым (не нужно перетаскивать слой, все управляется браузером). Если вы выберете режим mousemove / touchmove, вам потребуется реализовать слой перетаскивания, чтобы рисовать все, что вам нравится.

Имеет смысл?

Конечно, это то, на что я надеялся.
HTML5 D&D быстр и (помимо причуд) довольно прост в использовании, поэтому по умолчанию это очевидный выбор.

Итак, у меня только что был запрос на включение этого перетаскивания. Кто-нибудь делал это и хочет поделиться советами?

@Жоржет

@nelix начал работу над mousemove backend, после этого мы сделаем touchmove backend.

Вы можете посмотреть, как идет работа, здесь: https://github.com/nelix/react-dnd/commit/8de7f7fe24c7ae397a971c517dada9323e6c27f0 (это еще далеко не сделано и на данный момент не работает). Нам все еще нужно выяснить, какие части остаются в DragDropMixin а какие нужно переместить в backends/HTML5 (и другие бэкэнды).

Если вы хотите поработать над этим, вы можете начать с этого коммита и продолжать реализацию backend mousemove. Когда это сработает, реализовать аналогичный бэкэнд touchmove не составит труда.

Пожалуйста, если вы хотите поработать над этим, держите нас в курсе здесь или в комнате Gitter, чтобы мы не получили две реализации.

Вот доказательство концепции сенсорной поддержки: https://github.com/gaearon/react-dnd/pull/143

Вы можете поиграть с ним: http://rawgit.com/gaearon/react-dnd/touch-poc/examples/index.html

Он использует бэкэнд HTML5 на настольных компьютерах и сенсорный бэкэнд на мобильных устройствах.
Предварительный просмотр перетаскивания на мобильном устройстве будет показан только в примере пользовательской визуализации .

Это кажется многообещающим! Есть идеи, когда это может произойти? :)

Я сейчас занят другим проектом и буду до июля.
Возможно, я смогу поработать над этим где-нибудь в июле или августе, но я буду счастлив, если кто-нибудь меня опередит :-)

поскольку 1.1 была упомянута в этой теме, а версия 1.1.4 отсутствует. Мне просто интересно, включено ли доказательство концепции выше в 1.1.4?

Нет.

Мне не следовало использовать точный номер версии, потому что никогда не знаешь, когда вы столкнетесь :-)

В настоящее время у меня нет времени работать над этим, но подтверждение концепции находится в PR. Я, вероятно, обновлю PR, чтобы отразить текущий API, и подожду, пока кто-нибудь действительно его внедрит.

Продолжим обсуждение в https://github.com/gaearon/react-dnd/pull/240.

К вашему сведению: https://github.com/yahoo/react-dnd-touch-backend.

Для тех, кто придет после меня, это, кажется, путь вперед https://github.com/LouisBrunner/react-dnd-multi-backend

Я написал этот фрагмент:

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

Что я использую вот так:

DragDropContext(multiBackends(
      ReactDnDHTML5Backend,
      ReactDnDTouchBackend,
  ))

react-dnd-html5-backend и react-dnd-touch-backend слушают непересекающийся набор событий. (dragstart, dragend, dragenter, dragleave dragover и drop vs touchstart, touchend и touchmove).

Некоторое базовое тестирование, и оно работает нормально, мое перетаскивание теперь поддерживает события касания и мыши одновременно.

Есть ли причины, по которым это не сработает?

Была ли эта страница полезной?
0 / 5 - 0 рейтинги