Last active
September 13, 2019 16:16
-
-
Save senadir/365c8f578acd64be85cbcf1c3c068d56 to your computer and use it in GitHub Desktop.
Basic Drag Block
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* External dependencies | |
*/ | |
import { useDrop } from 'react-dnd'; | |
/** | |
* Internal dependencies | |
*/ | |
import Dot from './dot'; | |
function DotDragArea( { dots, setDots, children } ) { | |
const [ , dropRef ] = useDrop( { | |
accept: 'dot', | |
drop( { id, x, y }, monitor ) { | |
const delta = monitor.getDifferenceFromInitialOffset(); | |
const newX = Math.round( x + delta.x ); | |
const newY = Math.round( y + delta.y ); | |
moveDot( id, newX, newY ); | |
return undefined; | |
}, | |
} ); | |
const moveDot = ( id, x, y ) => { | |
setDots( { ...dots, [ id ]: { x, y } } ); | |
}; | |
return ( | |
<div ref={ dropRef } style={ { position: 'relative' } }> | |
{ Object.entries( dots ).map( ( [ key, { x, y } ] ) => ( | |
<Dot key={ key } id={ key } x={ x } y={ y } /> | |
) ) } | |
{ children } | |
</div> | |
); | |
} | |
export default DotDragArea; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* External dependencies | |
*/ | |
import { useDrag } from 'react-dnd'; | |
import classnames from 'classnames'; | |
/** | |
* Internal dependencies | |
*/ | |
import types from '../shared'; | |
export default function Dot( { id, x, y } ) { | |
const [ { isDragging }, dragRef ] = useDrag( { | |
item: { id, x, y, type: types.DOT }, | |
collect: ( monitor ) => { | |
return { isDragging: monitor.isDragging() }; | |
}, | |
} ); | |
if ( isDragging ) { | |
return <div ref={ dragRef } />; | |
} | |
return ( | |
<div | |
ref={ dragRef } | |
id={ id } | |
className={ | |
classnames( [ | |
'wp-block-taggable-image-dot', | |
{ 'is-dargging': isDragging }, | |
] ) } | |
style={ { left: x, top: y } } | |
/> | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* External dependencies | |
*/ | |
import uuid from 'uuid/v1'; | |
import { DndProvider } from 'react-dnd'; | |
import HTML5Backend from 'react-dnd-html5-backend'; | |
/** | |
* WordPress dependencies | |
*/ | |
import { useRef, useState } from '@wordpress/element'; | |
/** | |
* Internal dependencies | |
*/ | |
import DotDragArea from './components/dot-drag-area'; | |
function Edit() { | |
const imageRef = useRef( null ); | |
const [ dots, setDots ] = useState( {} ); | |
const addTag = ( { target, clientX, clientY } ) => { | |
if ( target === imageRef.current ) { | |
const rect = target.getBoundingClientRect(); | |
const { x, y } = { | |
x: ( clientX - rect.left ) + imageRef.current.offsetLeft, | |
y: ( clientY - rect.top ) + imageRef.current.offsetTop, | |
}; | |
setDots( { ...dots, [ uuid() ]: { x, y } } ); | |
} | |
}; | |
return ( | |
<div className="wp-block-taggable-image-container"> | |
<DndProvider backend={ HTML5Backend }> | |
<DotDragArea dots={ dots } setDots={ setDots }> | |
<img | |
src="https://images.unsplash.com/photo-1568271675068-f76a83a1e2d6?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80" | |
onClick={ addTag } | |
alt="" | |
ref={ imageRef } | |
style={ { display: 'block' } } | |
/> | |
</DotDragArea> | |
</DndProvider> | |
</div> | |
); | |
} | |
export default Edit; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.wp-block-taggable-image-container { | |
position: relative | |
} | |
img.wp-block-taggable-image { | |
display: block; | |
margin-left: auto; | |
margin-right: auto | |
} | |
.wp-block-taggable-image-dot { | |
position: absolute; | |
height: 24px; | |
width: 24px; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
transform: translate(-14px, -14px) | |
} | |
.wp-block-taggable-image-dot::before, | |
.wp-block-taggable-image-dot::after { | |
border-radius: 100%; | |
content: " "; | |
pointer-events: none; | |
position: absolute | |
} | |
.wp-block-taggable-image-dot::before { | |
-webkit-animation: nux-pulse 1.6s infinite cubic-bezier(0.17, 0.67, 0.92, 0.62); | |
animation: nux-pulse 1.6s infinite cubic-bezier(0.17, 0.67, 0.92, 0.62); | |
background: rgba(0, 115, 156, 0.9); | |
height: 24px; | |
transform: scale(.33333); | |
width: 24px | |
} | |
.wp-block-taggable-image-dot::after { | |
background: #00739c; | |
height: 8px; | |
width: 8px | |
} | |
@-webkit-keyframes nux-pulse { | |
100% { | |
background: rgba(0, 115, 156, 0); | |
transform: scale(1) | |
} | |
} | |
@keyframes nux-pulse { | |
100% { | |
background: rgba(0, 115, 156, 0); | |
transform: scale(1) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment