Skip to content

Instantly share code, notes, and snippets.

@senadir
Last active September 13, 2019 16:16
Show Gist options
  • Save senadir/365c8f578acd64be85cbcf1c3c068d56 to your computer and use it in GitHub Desktop.
Save senadir/365c8f578acd64be85cbcf1c3c068d56 to your computer and use it in GitHub Desktop.
Basic Drag Block
/**
* 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;
/**
* 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 } }
/>
);
}
/**
* 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;
.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