Como muitos, tenho uma lista de cartas classificáveis. No meu caso, cada cartão é um bloco de conteúdo de uma postagem de blog e alguns deles são trechos de código renderizados com react-codemirror
. A visualização do arrasto para os fragmentos incluiu um grande fundo branco que era igual à largura e à altura do texto dentro do editor de código do codemirror. Isso era indesejável, então tentei consertá-lo com CSS, mas não tive sorte e, conforme leio mais documentação, penso que não é possível porque o dnd está fazendo uma captura de tela do nó dom antes que novas classes ou estilos possam ser aplicados a ele (corrija-me se isso estiver errado, é claro)
Como não consegui fazer o css funcionar, tentei usar uma camada de arrastar personalizada para mostrar algo diferente para a visualização. Isso funciona muito bem, exceto que o arrasto se torna muito agitado, onde antes era bastante suave.
Aqui está um vídeo que demonstra o problema que acabei de descrever:
https://drive.google.com/file/d/0Bzbw-6Q_sVTySUNiNmJGcFVIQ00/view?usp=sharing
E suponho que você também queira ver algum código. Aqui está minha camada de arrastar personalizada
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)
Aqui estão as opções de configuração para a fonte de arrastar e destino de soltar
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()
}
}
E aqui está o componente Card
que está sendo arrastado
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)
Deixe-me saber se você precisar ver mais código do que isso, estou pensando que deve ser suficiente.
Sugestões para a) como eu poderia usar css para ocultar o fundo branco ou b) fazer o arrasto de visualização de arrasto personalizado mais suavemente seriam muito apreciadas!
Observe que este trabalho é parte de um curso de screencast sobre a construção de aplicativos com react / redux e que estou planejando fazer provavelmente 2-3 vídeos curtos em react-dnd para mostrar como os cartões de bloco de conteúdo classificáveis são implementados. Esperando liberá-los o mais rápido possível!
Também notei instabilidade com o dragLayer personalizado (apenas executando o exemplo do site): http://gaearon.github.io/react-dnd/examples-drag-around-custom-drag-layer.html
Está tudo bem no Chrome, mas a animação é instável no Firefox. (no linux mint, firefox 46.0.1)
A propósito, biblioteca incrível!
@sslotsky Você já descobriu isso?
Do contrário, posso mergulhar nisso e ver se há algo inteligente em CSS que podemos fazer ou, alternativamente, qualquer coisa que possamos fazer para reduzir a instabilidade. Outras pessoas relataram que o desempenho da camada de arrasto personalizado deixa muito a desejar.
Não, ainda não descobri. Uma solução seria ótima para quando eu pudesse gravar o próximo vídeo!
Também estamos vendo isso, inscrevendo-nos neste problema para quaisquer atualizações
@kesne Apenas comentando para manter isso vivo. Se você tiver alguma atualização que valha a pena compartilhar, tenho certeza de que adoraríamos saber dela :)
Sim, eu adoraria uma solução para isso também. Estou procurando implementar mais do que simplesmente uma captura de tela do objeto arrastável, mas essencialmente um componente de reação super simples.
Vou acrescentar isso também. Também estamos vendo o mesmo problema.
Também estou enfrentando isso .. Arrastar e soltar simples funcionando bem. Mas tenho uma implementação muito complexa e isso está acontecendo.
Tem o mesmo problema. Alguém encontrou alguma solução ou solução alternativa?
@ alexey-belous Nós descartamos esta biblioteca e fomos com https://github.com/bevacqua/react-dragula
Mesmo problema aqui, ficaria feliz com quaisquer comentários adicionais.
Estive investigando esse problema e descobri que a captura de tela de arrastar o nó dom é transparente apenas no Windows, independentemente do navegador.
Consegui melhorar muito a qualidade apenas removendo um console.log () do meu método getItemStyles (props). Isso não ajuda o OP, mas talvez alguém mais tropeçando aqui.
Então, eu clonei isso e executei o servidor de desenvolvimento e o exemplo de visualização de arrastar personalizado também está instável. No entanto, quando eu construo o site (executando npm run build-site
), o site é convertido para marcação regular (sem referências ao componente React) e agora o exemplo de visualização de arrastar está funcionando sem problemas.
Portanto, minha hipótese é que ReactDOM.renderToString (
Este ainda é um problema importante ... :(
@gaearon nós amamos você cara! Não nos deixe esperando! Mostre-nos a direção certa e tenho certeza que vamos consertar isso :)
Eu estava tendo um problema com a animação instável em uma camada de arrastar personalizada e descobri que era por causa de uma árvore DOM extremamente complexa.
Eu trabalho em um aplicativo que tem um componente de tabela que pode exibir até milhares de linhas e colunas de dados tabulares, o que cria algo como 4 elementos DOM por célula ou algo assim. Quando a tabela estava vazia, a camada de arrasto funcionava bem, mas conforme a quantidade de dados exibidos na tabela aumentava, o desempenho da camada de arrasto personalizada ficava mais lento. (Neste caso, a tabela não está envolvida de forma alguma com a operação das fontes de arrastar ou destinos de soltar).
Nesse caso, o desempenho no Firefox não mudou, enquanto o desempenho no Chrome piorou drasticamente quanto mais a complexidade da árvore DOM aumentava.
Consegui resolver o problema empurrando a tabela para sua própria camada de composição no Chrome, estilizando-a com uma propriedade de transformação 3D vazia: transform: translate3d(0, 0, 0)
Depois disso, o desempenho foi comparável à página de demonstração. Não tenho certeza de quais são as implicações para esta biblioteca, mas empurrando partes complexas da árvore DOM do seu aplicativo em camadas de composição separadas, você pode consertar seus problemas de desempenho.
@mgerring Você tem mais informações sobre como fez isso? Eu gostaria de experimentar no meu aplicativo
Sim, começamos removendo todos os componentes para encontrar aquele que estava causando o problema e, assim que o encontramos, detalhamos a parte que estava causando a desaceleração e, em seguida, o elemento mais externo que pode aceitar um style
param que escrevemos: style={{transform: translate3d(0, 0, 0)}}
Eu pretendia deixar este comentário no nº 592, mas acho que se aplica aqui também
A solução
@ alexey-belous Nós descartamos esta biblioteca e fomos com https://github.com/bevacqua/react-dragula
+1
Este problema foi marcado automaticamente como obsoleto porque não teve atividades recentes. Ele será fechado se nenhuma outra atividade ocorrer. Obrigado por suas contribuições.
Comentários muito úteis
Sim, começamos removendo todos os componentes para encontrar aquele que estava causando o problema e, assim que o encontramos, detalhamos a parte que estava causando a desaceleração e, em seguida, o elemento mais externo que pode aceitar um
style
param que escrevemos:style={{transform: translate3d(0, 0, 0)}}