Created
March 28, 2018 00:20
-
-
Save phpsmarter/4cbc788a6ed34f5cb4f1525964765d87 to your computer and use it in GitHub Desktop.
react svg con
This file contains hidden or 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
const { | |
withStateHandlers, | |
} = Recompose; | |
console.clear(); | |
const CANVAS_WIDTH = 640; | |
const CANVAS_HEIGHT = 480; | |
const CIRCLE_RADIUS = 48; | |
//////////////////////////////////////// | |
// | |
// Drag Snap | |
// | |
interface DraggableState { | |
isDown: boolean; | |
posX: number; | |
posY: number; | |
screenX: number; | |
screenY: number; | |
} | |
interface DraggableHandler { | |
onMouseDown: (e: MouseEvent) => DraggableState; | |
onMouseUp: (e: MouseEvent) => DraggableState; | |
onMouseMove: (e: MouseEvent) => DraggableState; | |
} | |
interface DraggableProps { | |
initX: number; | |
initY: number; | |
color: string; | |
} | |
const DraggableCircleBase: React.StatelessComponent<DraggableState & DraggableHandler & DraggableProps> = | |
({posX, posY, color, onMouseDown, onMouseMove, onMouseUp}) => ( | |
<circle | |
cx={posX} | |
cy={posY} | |
r={CIRCLE_RADIUS} | |
stroke={color} | |
fill={'light' + color} | |
strokeWidth="3" | |
onMouseDown={onMouseDown} | |
onMouseMove={onMouseMove} | |
onMouseUp={onMouseUp} | |
/> | |
); | |
const enhanceWithDraggable = withStateHandlers<DragSnapState, DragSnapHandler, DraggableProps>( | |
({ initX, initY }) => ({ | |
isDown: false, | |
posX: initX, | |
posY: initY, | |
screenX: 0, | |
screenY: 0 | |
}), { | |
onMouseDown: (state: DraggableState) => (e: MouseEvent) => { | |
return { | |
...state, | |
isDown: true, | |
screenX: e.screenX, | |
screenY: e.screenY | |
} | |
}, | |
onMouseMove: (state: DraggableState) => (e: MouseEvent) => { | |
if (!state.isDown) { | |
return { ...state } | |
} | |
const shiftX = e.screenX - state.screenX; | |
const shiftY = e.screenY - state.screenY; | |
return { | |
...state, | |
posX: state.posX + shiftX, | |
posY: state.posY + shiftY, | |
screenX: e.screenX, | |
screenY: e.screenY, | |
}; | |
}, | |
onMouseUp: (state: DraggableState, props: DraggableProps) => (e: MouseEvent) => { | |
return { ...state, isDown: false, screenX: 0, screenY: 0 } | |
}, | |
} | |
); | |
const DraggableCircle = enhanceWithDraggable(DraggableCircleBase); | |
const SVGDrag: React.StatelessComponent<React.Props<{}>> = () => ( | |
<div> | |
<div> | |
<svg style={{ width: CANVAS_WIDTH + 'px', height: CANVAS_HEIGHT + 'px', border: '1px solid silver' }}> | |
<DraggableCircle initX={CANVAS_WIDTH * .25} initY={CANVAS_HEIGHT / 2} color="blue" /> | |
<DraggableCircle initX={CANVAS_WIDTH * .5} initY={CANVAS_HEIGHT / 2} color="pink" /> | |
<DraggableCircle initX={CANVAS_WIDTH * .75} initY={CANVAS_HEIGHT / 2} color="green" /> | |
</svg> | |
</div> | |
</div> | |
); | |
// render both components | |
ReactDOM.render( | |
(<div> | |
<h2>React SVG drag example</h2> | |
<SVGDrag /> | |
</div>), | |
document.querySelector('#root')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment