React-dnd: Tangkapan layar yang buruk pada tarikan biasa, gerakan berombak pada pratinjau seret khusus

Dibuat pada 8 Mei 2016  ·  22Komentar  ·  Sumber: react-dnd/react-dnd

Seperti banyak orang, saya memiliki daftar kartu yang dapat diurutkan. Dalam kasus saya, setiap kartu adalah blok konten dari posting blog dan beberapa di antaranya adalah cuplikan kode yang dirender dengan react-codemirror . Pratinjau seret untuk cuplikan menyertakan latar belakang putih besar yang sama dengan lebar dan tinggi teks dalam editor kode codemirror. Ini tidak diinginkan jadi saya mencoba memperbaikinya dengan CSS tetapi tidak berhasil, dan ketika saya membaca lebih banyak dokumentasi, saya pikir itu tidak mungkin karena dnd sedang mengambil tangkapan layar simpul dom sebelum kelas atau gaya baru dapat diterapkan padanya (tolong perbaiki saya jika itu salah tentu saja)

Karena saya tidak dapat menjalankan css, saya mencoba menggunakan lapisan seret khusus untuk menampilkan sesuatu yang berbeda untuk pratinjau. Ini berfungsi dengan baik kecuali menyeret menjadi sangat berombak di mana sebenarnya cukup mulus sebelumnya.

Berikut adalah video yang menunjukkan masalah yang baru saja saya jelaskan:

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

Dan saya kira Anda juga ingin melihat beberapa kode. Ini adalah lapisan seret khusus saya

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)

Berikut adalah opsi konfigurasi untuk sumber drag & drop target

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()
  }
}

Dan inilah komponen Card yang sedang diseret

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)

Beri tahu saya jika Anda perlu melihat kode lebih dari itu, saya pikir ini sudah cukup.

Saran untuk a) bagaimana saya bisa menggunakan css untuk menyembunyikan latar belakang putih atau b) membuat drag preview drag kustom lebih lancar akan sangat dihargai!

Perhatikan bahwa pekerjaan ini adalah bagian dari kursus screencast tentang membangun aplikasi dengan react/redux dan saya berencana untuk membuat 2-3 video pendek tentang react-dnd untuk menunjukkan bagaimana kartu blok konten yang dapat diurutkan diimplementasikan. Berharap untuk merilisnya sesegera mungkin!

needs info wontfix

Komentar yang paling membantu

Ya, kami mulai dengan menghapus setiap komponen untuk menemukan komponen yang menyebabkan masalah, dan setelah kami menemukannya, menelusuri bagian yang menyebabkan pelambatan, lalu pada elemen terluar yang dapat menerima style param yang kami tulis: style={{transform: translate3d(0, 0, 0)}}

Semua 22 komentar

Saya telah memperhatikan choppiness juga dengan dragLayer khusus (hanya menjalankan contoh situs web): http://gaearon.github.io/react-dnd/examples-drag-around-custom-drag-layer.html

Semuanya baik-baik saja di Chrome tetapi animasinya berombak di Firefox. (di linux mint, firefox 46.0.1)

Omong-omong, perpustakaan yang luar biasa!

@sslotsky Apakah Anda pernah mengetahui hal ini?

Jika tidak, saya dapat mempelajari ini dan melihat apakah ada sesuatu yang pintar dalam CSS yang dapat kita lakukan, atau alternatif lain yang dapat kita lakukan untuk mengurangi choppiness. Orang lain telah melaporkan bahwa kinerja lapisan seret kustom meninggalkan banyak hal yang diinginkan.

Tidak, masih belum menemukan jawabannya. Sebuah solusi akan sangat bagus ketika saya merekam video berikutnya!

Kami juga melihat ini, berlangganan masalah ini untuk pembaruan apa pun

@kesne Hanya berkomentar untuk menjaga ini tetap hidup. Jika Anda memiliki pembaruan yang layak dibagikan, saya yakin kami akan senang mendengarnya :)

Ya, saya juga ingin solusi untuk ini. Saya ingin menerapkan lebih dari sekadar tangkapan layar dari objek yang dapat diseret, tetapi pada dasarnya komponen reaksi yang sangat sederhana.

Saya akan memberikan ini juga. Kami juga melihat masalah yang sama.

Saya juga mengalami ini.. Seret dan lepas sederhana berfungsi dengan baik. Tetapi saya memiliki implementasi yang terlalu rumit, dan ini sedang terjadi.

Punya masalah yang sama. Apakah ada yang datang dengan beberapa solusi atau solusi?

@alexey-belous Kami menghapus perpustakaan ini dan menggunakan https://github.com/bevacqua/react-dragula

Masalah yang sama di sini, akan senang dengan komentar lebih lanjut.

Saya telah menyelidiki masalah ini dan menemukan bahwa tangkapan layar menyeret simpul dom transparan hanya di Windows terlepas dari browser.

Saya dapat sangat meningkatkan kualitas hanya dengan menghapus console.log() dari metode getItemStyles(props) saya. Ini tidak membantu OP, tetapi mungkin orang lain tersandung di sini.

Jadi saya mengkloning ini dan menjalankan server dev dan contoh pratinjau drag kustom juga berombak. Namun, ketika saya membangun situs (dengan menjalankan npm run build-site ) situs tersebut diubah menjadi markup biasa (tanpa referensi komponen Bereaksi) dan sekarang contoh pratinjau seret berjalan dengan lancar.

Jadi hipotesis saya adalah bahwa ReactDOM.renderToString( ) meningkatkan kinerja seret dan lepas untuk pratinjau seret khusus.

Ini masih masalah besar... :(

592 Sepertinya ada sedikit keberuntungan, tapi saya belum bisa fork dan edit. Mungkin orang lain bisa mendapatkannya sebelum saya melakukannya.

@gaearon kami mencintaimu

Saya mengalami masalah dengan animasi berombak pada lapisan seret khusus dan menemukan itu karena pohon DOM yang sangat kompleks.

Saya bekerja pada aplikasi yang memiliki komponen tabel yang dapat menampilkan hingga ribuan baris dan kolom data tabular, yang membuat sesuatu seperti 4 elemen DOM per sel atau lebih. Saat tabel kosong, lapisan seret berfungsi dengan baik, tetapi karena jumlah data yang ditampilkan dalam tabel meningkat, kinerja lapisan seret khusus melambat. (Dalam hal ini, tabel tidak terlibat sama sekali dengan pengoperasian sumber seret atau jatuhkan target).

Dalam hal ini, kinerja di Firefox tidak berubah, sementara kinerja di Chrome menjadi lebih buruk secara dramatis dengan semakin meningkatnya kompleksitas pohon DOM.

Saya dapat mengatasi masalah ini dengan mendorong tabel ke dalam lapisan pengomposisiannya sendiri di Chrome, dengan menatanya dengan properti transformasi 3D kosong: transform: translate3d(0, 0, 0)

Setelah itu, kinerjanya sebanding dengan halaman demo. Saya tidak yakin apa implikasinya untuk pustaka ini, tetapi dengan mendorong bagian kompleks dari pohon DOM aplikasi Anda ke dalam lapisan pengomposisian yang terpisah, Anda mungkin dapat memperbaiki masalah kinerja Anda.

@mgerring Apakah Anda memiliki info lebih lanjut tentang bagaimana Anda melakukannya? Saya ingin mencobanya di aplikasi saya

Ya, kami mulai dengan menghapus setiap komponen untuk menemukan komponen yang menyebabkan masalah, dan setelah kami menemukannya, menelusuri bagian yang menyebabkan pelambatan, lalu pada elemen terluar yang dapat menerima style param yang kami tulis: style={{transform: translate3d(0, 0, 0)}}

Saya bermaksud meninggalkan komentar ini di #592 tetapi saya pikir itu juga berlaku di sini

@mgerring solusi bekerja untuk saya.

@alexey-belous Kami menghapus perpustakaan ini dan menggunakan https://github.com/bevacqua/react-dragula
+1

Masalah ini secara otomatis ditandai sebagai basi karena tidak ada aktivitas terbaru. Ini akan ditutup jika tidak ada aktivitas lebih lanjut yang terjadi. Terima kasih atas kontribusi Anda.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat