Moving react-draggable to side of screen?
Implementing the assistive touch behavior in onStop
handler sounds a good approach.
Please check my implementation and follow the comments:
const Draggable = ReactDraggableclass Example extends React.Component { constructor(props) { super(props) this.state = { position: { x:0, y:0 }} } onStop(event, data) { // Viewport (wrapper) const documentElement = document.documentElement const wrapperHeight = (window.innerHeight || documentElement.clientHeight) const wrapperWidth = (window.innerWidth || documentElement.clientWidth) // Draggable element center coordinates (x,y) // Here we assume that the Draggable Button (from the question) // is a rectangle. But we can easily change it with whatever // figure we want and fine-tune the calculation. // Credits: https://stackoverflow.com/a/18932029/4312466 const center = { x: data.x + (data.node.clientWidth / 2), y: data.y + (data.node.clientHeight / 2) } // The margin from the draggable's center, // to the viewport sides (top, left, bottom, right) const margin = { top: center.y - 0, left: center.x - 0, bottom: wrapperHeight - center.y, right: wrapperWidth - center.x } // When we get the nearest viewport side (below), then we can // use these metrics to calculate the new draggable sticky `position` const position = { top: { y: 0, x: data.x }, left: { y: data.y, x: 0 }, bottom: { y: (wrapperHeight - data.node.clientHeight), x: data.x }, right: { y: data.y, x: (wrapperWidth - data.node.clientWidth)} } // Knowing the draggable's margins to the viewport sides, // now we can sort them out and get the smaller one. // The smallest margin defines the nearest viewport side to draggable. const sorted = Object.keys(margin).sort((a,b) => margin[a]-margin[b]) const nearestSide = sorted[0] this.setState({ position: position[nearestSide] }) } render() { return <Draggable position={this.state.position} onStop={(event, data) => this.onStop(event, data)} > <div className='handle'>Drag</div> </Draggable> }}ReactDOM.render( <Example />, document.getElementById('container'))
body { overflow-x: hidden; overflow-y: hidden; padding: 0; margin: 0;}.handle { width: 40px; height: 40px; line-height: 40px; background-color: #2662c1; color: #fff; cursor: move; text-align: center;}.handle:not(.react-draggable-dragging) { -webkit-transition: -webkit-transform 0.5s ease-out; /* Safari */ transition: transform 0.5s ease-out;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script><script src="https://unpkg.com/react-draggable@3.0.5/dist/react-draggable.js"></script><div id="container"> <!-- This element's contents will be replaced with your component. --></div>