React-dnd: 通常のドラッグでの悪いスクリーンショット、カスタムドラッグプレビューでの途切れ途切れの動き

作成日 2016年05月08日  ·  22コメント  ·  ソース: react-dnd/react-dnd

多くの人と同じように、私はソート可能なカードのリストを持っています。 私の場合、各カードはブログ投稿のコンテンツブロックであり、これらの一部はreact-codemirrorレンダリングされたコードスニペットです。 スニペットのドラッグプレビューには、コードミラーのコードエディタ内のテキストの幅と高さに等しい大きな白い背景が含まれていました。 これは望ましくなかったので、CSSで修正しようとしましたが、運がありませんでした。さらにドキュメントを読むと、新しいクラスやスタイルを適用する前にdndがdomノードのスクリーンショットを作成しているため不可能だと思います(修正してください)もちろんそれが間違っている場合)

cssを機能させることができなかったため、カスタムドラッグレイヤーを使用して、プレビュー用に別の何かを表示してみました。 これは、ドラッグが以前は非常にスムーズだった場所で本当に途切れ途切れになることを除いて、うまく機能します。

これが私が今説明した問題を示すビデオです:

https://drive.google.com/file/d/0Bzbw-6Q_sVTySUNiNmJGcFVIQ00/view?usp=sharing

そして、私はあなたもいくつかのコードを見たいと思うでしょう。 これが私のカスタムドラッグレイヤーです

import React, { Component, PropTypes } from 'react'
import { DragLayer } from 'react-dnd'

function collect(monitor) {
  return {
    item: monitor.getItem(),
    currentOffset: monitor.getSourceClientOffset(),
    isDragging: monitor.isDragging()
  }
}

const layerStyles = {
  position: 'fixed',
  pointerEvents: 'none',
  zIndex: 100,
  left: 0,
  top: 0,
  width: '20%',
  height: '100%'
}

function getItemStyles(props) {
  var currentOffset = props.currentOffset
  if (!currentOffset) {
    return {
      display: 'none'
    }
  }

  var x = currentOffset.x
  var y = currentOffset.y
  var transform = 'translate(' + x + 'px, ' + y + 'px)'
  return {
    transform: transform,
    WebkitTransform: transform
  }
}

class CardDragLayer extends Component {
  static propTypes = {
    item: PropTypes.object
  }

  render() {
    const { item, isDragging } = this.props

    if (!isDragging)
      return false

    return (
      <div style={layerStyles}>
        <div className='drag-preview' style={getItemStyles(this.props)}>
          <i className='fa fa-hand-scissors-o fa-6'></i>
        </div>
      </div>
    )
  }
}

export default DragLayer(collect)(CardDragLayer)

ドラッグソースとドロップターゲットの構成オプションは次のとおりです

export const cardSource = {
  beginDrag(props) {
    return {
      index: props.index
    }
  }
}

export const cardTarget = {
  hover(props, monitor, component) {
    const dragIndex = monitor.getItem().index
    const hoverIndex = props.index

    if (dragIndex === hoverIndex)
      return

    props.swap(dragIndex, hoverIndex)
    monitor.getItem().index = hoverIndex;
  }
}

export function collectSource(connect, monitor) {
  return {
    connectDragSource: connect.dragSource(),
    connectDragPreview: connect.dragPreview(),
    isDragging: monitor.isDragging()
  }
}

export function collectTarget(connect) {
  return {
    connectDropTarget: connect.dropTarget()
  }
}

そして、これがドラッグされているCardコンポーネントです

import React, { PropTypes, Component } from 'react'
import { Snippet, Markdown } from './Show'
import { DragSource, DropTarget } from 'react-dnd'
import { getEmptyImage } from 'react-dnd-html5-backend'
import { cardSource, cardTarget, collectSource, collectTarget } from './dragDropConfig'
import classnames from 'classnames'

class SnippetCard extends Component {
  options() {
    return {
      readOnly: true,
      scrollbarStyle: 'null',
      viewportMargin: Infinity
    }
  }

  render() {
    const { language, text } = this.props
    return(
      <Snippet
        options={this.options()}
        language={language.value}
        text={text.value} />
    )
  }
}

class MarkdownCard extends Component {
  render() {
    const { text } = this.props
    return (
      <div className='markdown-card'>
        <div className='card-content'>
          <Markdown text={text.value} />
        </div>
      </div>
    )
  }
}

const components = {
  snippet: SnippetCard,
  markdown: MarkdownCard
}

class Card extends Component {
  static propTypes = {
    connectDragSource: PropTypes.func.isRequired,
    connectDropTarget: PropTypes.func.isRequired,
    index: PropTypes.number.isRequired,
    block: PropTypes.object.isRequired,
    swap: PropTypes.func.isRequired
  }

  componentDidMount() {
    const { connectDragPreview } = this.props
    connectDragPreview(getEmptyImage(), {
      captureDraggingState: true
    })
  }

  render() {
    const { isDragging, block, connectDragSource, connectDropTarget } = this.props
    const Component = components[block.format.value]
    const classes = classnames('card', {
      dragging: isDragging
    })

    return connectDragSource(connectDropTarget((
      <div className={classes}>
        <div className='card-header'>
          <div>
            <label>
              {block.format.value}
            </label>
          </div>
          <Component {...block} />
        </div>
      </div>
    )))
  }
}

const Source = DragSource('card', cardSource, collectSource)(Card)
export default DropTarget('card', cardTarget, collectTarget)(Source)

それ以上のコードが必要な場合はお知らせください。これで十分だと思います。

a)cssを使用して白い背景を非表示にする方法、またはb)カスタムドラッグプレビュードラッグをよりスムーズにする方法の提案をいただければ幸いです。

この作業はreact / reduxを使用したアプリの構築に関するスクリーンキャストコースの一部であり、ソート可能なコンテンツブロックカードがどのように実装されているかを示すために、react-dndでおそらく2〜3本の短いビデオを作成する予定です。 それらをできるだけ早くリリースしたいと思っています!

needs info wontfix

最も参考になるコメント

ええ、問題の原因となっているコンポーネントを見つけるためにすべてのコンポーネントを削除することから始め、それを見つけたら、速度低下の原因となっている部分にドリルダウンし、次にstyle受け入れることができる最も外側の要素にドリルダウンしました私たちが書いたstyle={{transform: translate3d(0, 0, 0)}}

全てのコメント22件

カスタムdragLayer(Webサイトの例を実行するだけ)でも途切れに気づきました: http ://gaearon.github.io/react-dnd/examples-drag-around-custom-drag-layer.html

Chromeではすべて問題ありませんが、Firefoxではアニメーションが途切れます。 (Linux Mint、Firefox 46.0.1の場合)

ちなみに素晴らしい図書館!

@sslotskyこれを理解したことはありますか?

そうでない場合は、これに飛び込んで、CSSに何か賢いことができるかどうか、あるいは、途切れを減らすためにできることがあるかどうかを確認できます。 他の人々は、カスタムドラッグレイヤーのパフォーマンスには多くの要望が残されていると報告しています。

いいえ、まだ理解していません。 次のビデオの録画に取り掛かるときの解決策は素晴らしいでしょう!

私たちもこれを見ています、更新のためにこの問題を購読します

@kesneこれを存続させるためにコメントするだけです。 共有する価値のあるアップデートがあれば、ぜひ聞いてみたいと思います:)

ええ、私もこれに対する解決策が大好きです。 ドラッグ可能なオブジェクトの単なるスクリーンショット以上のものを実装しようとしていますが、本質的には非常に単純な反応コンポーネントです。

これも投げます。 同じ問題が発生しています。

私もこれに遭遇しています..単純なドラッグアンドドロップが正常に機能しています。 しかし、私には複雑すぎる実装があり、これが起こっています。

同じ問題があります。 誰かが何らかの解決策や回避策を思いついたのですか?

@ alexey-belousこのライブラリを廃棄し、 https://github.com/bevacqua/react-dragulaを使用しました

ここでの同じ問題は、さらなるコメントについて喜んでいるでしょう。

私はこの問題を調査していて、domノードをドラッグするスクリーンショットはブラウザとは関係なくWindowsでのみ透過的であることがわかりました。

getItemStyles(props)メソッドからconsole.log()を削除するだけで、品質を大幅に向上させることができました。 これはOPの助けにはなりませんが、他の誰かがここでつまずいたのかもしれません。

だから私はこれを複製して開発サーバーを実行しました、そしてカスタムドラッグプレビューの例も途切れ途切れです。 ただし、( npm run build-site実行して)サイトを構築すると、サイトは通常のマークアップ(Reactコンポーネント参照なし)に変換され、ドラッグプレビューの例がスムーズに実行されます。

したがって、私の仮説は、ReactDOM.renderToString( )カスタムドラッグプレビューのドラッグアンドドロップのパフォーマンスが向上します。

これはまだ大きな問題です... :(

592運が良かったようですが、まだフォークと編集ができていません。 多分誰か他の人が私がする前にそれに到達することができます。

@gaearon私たちはあなたを愛しています! ぶら下げたままにしないでください! 私たちを正しい方向に向けてください、そして私たちはそれを修正すると確信しています:)

カスタムドラッグレイヤーでの途切れ途切れのアニメーションに問題があり、それが非常に複雑なDOMツリーが原因であることがわかりました。

私は、表形式のデータの最大数千の行と列を表示できるテーブルコンポーネントを備えたアプリで作業しています。これにより、セルごとに4つのDOM要素などが作成されます。 テーブルが空の場合、ドラッグレイヤーは正常に機能していましたが、テーブルに表示されるデータの量が増えると、カスタムドラッグレイヤーのパフォーマンスが低下しました。 (この場合、テーブルはドラッグソースまたはドロップターゲットの操作にはまったく関与しません)。

この場合、Firefoxのパフォーマンスは変化しませんでしたが、Chromeのパフォーマンスは、DOMツリーの複雑さが増すにつれて劇的に悪化しました。

空の3D変換プロパティでテーブルをスタイリングすることで、テーブルをChromeの独自の合成レイヤーにプッシュすることで、この問題を解決することができました: transform: translate3d(0, 0, 0)

その後、パフォーマンスはデモページと同等でした。 このライブラリの意味はわかりませんが、アプリケーションのDOMツリーの複雑な部分を別々の合成レイヤーにプッシュすることで、パフォーマンスの問題を修正できる可能性があります。

@mgerringそれをどのように行ったかについてもっと情報がありますか? アプリで試してみたい

ええ、問題の原因となっているコンポーネントを見つけるためにすべてのコンポーネントを削除することから始め、それを見つけたら、速度低下の原因となっている部分にドリルダウンし、次にstyle受け入れることができる最も外側の要素にドリルダウンしました私たちが書いたstyle={{transform: translate3d(0, 0, 0)}}

このコメントを#592に残すつもりでしたが、ここにも当てはまると思います

@mgerringソリューションは私のために働いた。

@ alexey-belousこのライブラリを廃棄し、 https://github.com/bevacqua/react-dragulaを使用しました
+1

この問題は、最近のアクティビティがないため、自動的に古いものとしてマークされています。 それ以上のアクティビティが発生しない場合は閉じられます。 貢献していただきありがとうございます。

このページは役に立ちましたか?
0 / 5 - 0 評価