React-dnd: рдбреНрд░реИрдЧ рдХреЗ рджреМрд░рд╛рди рдХрд░реНрд╕рд░ рдХреЛ рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝ рдХрд░реЗрдВ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 5 рдирд╡ре░ 2015  ┬╖  15рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: react-dnd/react-dnd

рд╢рд╛рдирджрд╛рд░ рдкреБрд╕реНрддрдХрд╛рд▓рдп! рдЗрд╕реЗ рдПрдХ рд╕рд╛рде рд░рдЦрдиреЗ рдореЗрдВ рдЖрдкрдХреА рд╕рднреА рдХрдбрд╝реА рдореЗрд╣рдирдд рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдореЗрд░рд╛ рдПрдХ рддреНрд╡рд░рд┐рдд рдкреНрд░рд╢реНрди рд╣реИ: рдХреНрдпрд╛ рдХрд░реНрд╕рд░ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ рдЬреИрд╕реЗ рдХрд┐ рдбреНрд░реИрдЧ рдСрдкрд░реЗрд╢рди рдХреЗ рджреМрд░рд╛рди, рдХрд░реНрд╕рд░ рд╣рдореЗрд╢рд╛ рдПрдХ рд╣реА рдЪреАрдЬрд╝ рдкрд░ рд╕реЗрдЯ

рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдЪрд╛рд╣реЗ рдЖрдк рдбреНрд░реЙрдк рдЬреЛрди рд╕реЗ рдЕрдзрд┐рдХ рд╣реЛрдВ рдпрд╛ рдирд╣реАрдВ, рдХрд░реНрд╕рд░ рд╕рдорд╛рди рд░рд╣рддрд╛ рд╣реИред рдпрд╣ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдиреЛрдЯ рдХреЛ рдЦреАрдВрдЪрддреЗ рд╕рдордп рдЯреНрд░реИрд▓реЛ рдХреЗ рдХрд░реНрд╕рд░ рдХреЗ рд╕рдорд╛рди рд╣реИред

рдЕрдЧреНрд░рд┐рдо рдореЗрдВ рдзрдиреНрдпрд╡рд╛рдж!

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдХрд┐рд╕реА рдХреЛ рднреА рдпрд╣ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣реЗ?

рд╕рднреА 15 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдЖрдк рд╕рдВрднрд╡рддрдГ рдкреВрд░реЗ рд╢рд░реАрд░ рдкрд░ cursor рд╢реИрд▓реА (рдпрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд░реВрдЯ div ) рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрдмрдХрд┐ isDragging true ред isDragging рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рд╕реБрдирдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдк DragLayer рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдзрдиреНрдпрд╡рд╛рдж, рдХрд╛рд╢ рдХрд┐ рдХрд╛рдо рдХрд░рддрд╛! рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдХрд░реНрд╕рд░ рд╢реИрд▓реА рдХреЛ рдХреБрдЫ (рдореИрдВ рдХреНрд░реЛрдо рдкрд░ рд╣реВрдБ) рджреНрд╡рд╛рд░рд╛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдХрд░реНрд╕рд░ рд╢реИрд▓реА рдХреЛ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝.рдмреЙрдбреА рдкрд░ рд╕реЗрдЯ рдХрд░рддреЗ рд╕рдордп рдФрд░ рдЗрд╕реЗ "рдорд╣рддреНрд╡рдкреВрд░реНрдг" рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдХреЛрдИ рдЕрдиреНрдп рд╡рд┐рдЪрд╛рд░?

рд╢рд╛рдпрдж рдпрд╣ рд╕рд┐рд░реНрдл HTML5 рдбреНрд░реИрдЧ рдФрд░ рдбреНрд░реЙрдк рдПрдкреАрдЖрдИ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдПрдХрдорд╛рддреНрд░ рд╕рдорд╛рдзрд╛рди рдПрдХ рдХрд╕реНрдЯрдо рдмреИрдХрдПрдВрдб рдмрдирд╛рдирд╛ рд╣реИ рдЬреЛ HTML5 рдбреНрд░реИрдЧ рдФрд░ рдбреНрд░реЙрдк рдИрд╡реЗрдВрдЯ рдХреЗ рдмрдЬрд╛рдп рдорд╛рдЙрд╕ рдИрд╡реЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред

рдореИрдВ рдЙрдореНрдореАрдж рдХрд░ рд░рд╣рд╛ рдерд╛ рдХрд┐ рдЖрдк рдРрд╕рд╛ рдирд╣реАрдВ рдХрд╣реЗрдВрдЧреЗ :) рдзрдиреНрдпрд╡рд╛рдж!

рдореБрдЭреЗ рдЕрднреА рдЗрд╕ рдореБрджреНрджреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдпрд╣ рдЦреАрдВрдЪрддреЗ рд╕рдордп рдЖрдЗрдХрди рдХреЛ рдмрджрд▓рдиреЗ рдореЗрдВ рдЕрд╕рдорд░реНрде рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ :(

рдХрд┐рд╕реА рдХреЛ рднреА рдпрд╣ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣реЗ?

рдЗрд╕ рдкрд░ рднреА рдЬрд╛рдХрд░ рджреЗрдЦрд╛ред рд╣рд╛рдБ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рджреБрдЦ рдХреА рдмрд╛рдд рд╣реИ рдХрд┐ рдПрдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╕реАрдорд╛ рд╣реИ рдХрд┐ DataTransfer.effectAllowed рд▓рд┐рдП рдПрдкреАрдЖрдИ рдХреЗрд╡рд▓ рдореБрдЯреНрдареА рднрд░ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ:

https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/effectAllowed

рддреЛ рдЗрд╕рдХреЗ рдЖрд╕рдкрд╛рд╕ рдЬрд╛рдиреЗ рдХрд╛ рдПрдХрдорд╛рддреНрд░ рддрд░реАрдХрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ @gaearon рдиреЗ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдПрдХ рдЕрд▓рдЧ рдХрд╕реНрдЯрдо рдмреИрдХрдПрдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ: / рдпрд╣ HTML5 рдмреИрдХрдПрдВрдб рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдиреЗ рд▓рд╛рдпрдХ рдХреБрдЫ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╕рд╣рдЬ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рд╡реИрд╕реЗ рдПрдХ рдмрд╣реБрдд рдЧрд▓рдд рд▓реЗрдХрд┐рди рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рд╕рдорд╛рдзрд╛рди рд╢рд░реАрд░ рдореЗрдВ dragging рд╡рд░реНрдЧ рдЬреЛрдбрд╝ рд░рд╣рд╛ рд╣реЛрдЧрд╛ рддрд╛рдХрд┐ рд╢рд░реАрд░ рдФрд░ рд╢рд░реАрд░ рдХреЗ рдЕрдВрджрд░ рдкреНрд░рддреНрдпреЗрдХ DOM рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ cursor: grabbing !important ред рдЗрд╕рд╕реЗ рдЬреНрдпрд╛рджрд╛ рдХреБрдЫ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред
рдЗрд╕реА рд╕реЗ рдореЗрд░рд╛ рдХрд╛рдо рдмрдирд╛ рд╣реИ:

:global {
    body.dragging,
    body.dragging * {
        cursor: url('./assets/cursors/grabbing.cur'), move !important;
    }
}

JS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рдФрд░ рддрд░реАрдХрд╛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ:

window.addEventListener('drag', () => {
  document.body.style.cursor = 'grabbing';
}, true)

рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рд▓рдЧрд╛рддрд╛рд░ рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИ ...

рдореБрдЭреЗ рдпрд╣рд╛рдВ рд╕реБрдЭрд╛рдП рдЧрдП рдХрд┐рд╕реА рднреА рд╕рдорд╛рдзрд╛рди рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рдкрд░ рдХреБрдЫ рднреА рдЕрдкрдбреЗрдЯ?

TouchBackend рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдирд╛ рдФрд░ рдХрд░реНрд╕рд░ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП css рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд┐рдпрд╛ред

<DndProvider backend={TouchBackend} options={{ enableTouchEvents: false, enableMouseEvents: true }}>
  <div className=`my-app ${isDragging ? 'dragging' : ''}`>
      .... draglayers here
  </div>
</DndProvider>
.dragging {
  cursor: grabbing
}

TouchBackend рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдирд╛ рдФрд░ рдХрд░реНрд╕рд░ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП css рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд┐рдпрд╛ред

<DndProvider backend={TouchBackend} options={{ enableTouchEvents: false, enableMouseEvents: true }}>
  <div className=`my-app ${isDragging ? 'dragging' : ''}`>
      .... draglayers here
  </div>
</DndProvider>
.dragging {
  cursor: grabbing
}

рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛

+1

рдХреЛрдИ рдЗрд╕реЗ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣рд╛?

TouchBackend рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдирд╛ рдФрд░ рдХрд░реНрд╕рд░ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП css рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд┐рдпрд╛ред

<DndProvider backend={TouchBackend} options={{ enableTouchEvents: false, enableMouseEvents: true }}>
  <div className=`my-app ${isDragging ? 'dragging' : ''}`>
      .... draglayers here
  </div>
</DndProvider>
.dragging {
  cursor: grabbing
}

рдЯрдЪрдмреИрдХ рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдирд╛ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░ рдЧрдпрд╛

DnD рдкреНрд░рджрд╛рддрд╛:

import { DndProvider } from 'react-dnd';
import { TouchBackend } from 'react-dnd-touch-backend';

...
<DndProvider backend={TouchBackend} options={{enableMouseEvents: true}}>
...
</DndProvider>

рдбреНрд░реИрдЧ рд╣реИрдВрдбрд▓рд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:

    import { useDrag, useDrop } from 'react-dnd';
    ....

    const [...] = useDrag({
      ...
      begin: () => {
        document.body.classList.add('dragging');
        ...
     },
      end: () => {
        document.body.classList.remove('dragging');
        ...
      },
    });

рд╕реАрдПрд╕рдПрд╕ рдлрд╝рд╛рдЗрд▓

   body.dragging: {
      cursor: crosshair !important;
   },
рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
5 / 5 - 1 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

rubayethossain picture rubayethossain  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

yaoyuande picture yaoyuande  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

gocreating picture gocreating  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

croraf picture croraf  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

dwjohnston picture dwjohnston  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ