webamp/js/DraggableWindow.jsx
2016-07-31 17:01:42 -07:00

77 lines
2.3 KiB
JavaScript

import {cloneElement, Children, Component} from 'react';
// Many of the ideas of how to build this as a React componant were stolen
// from: https://github.com/mzabriskie/react-draggable Thanks! @mzabriskie
class DraggableWindow extends Component {
constructor(props) {
super(props);
this.handleMouseDown = this.handleMouseDown.bind(this);
this.state = {};
}
handleMouseDown(e) {
if (!e.target.classList.contains(this.props.handleClass)) {
// Prevent going into drag mode when clicking any of the title
// bar's icons by making sure the click was made directly on the
// handle
return true;
}
// If the element was 'absolutely' positioned we could simply use
// offsetLeft / offsetTop however the element is 'relatively'
// positioned so we're using style.left. parseInt is used to remove the
// 'px' postfix from the value
const winStart = {
left: parseInt(this.body.offsetLeft || 0, 10),
top: parseInt(this.body.offsetTop || 0, 10)
};
// Get starting mouse position
const mouseStart = {
left: e.clientX,
top: e.clientY
};
// Mouse move handler function while mouse is down
const handleMove = (moveEvent) => {
// Calculate difference offsets between current and starting positions
const diff = {
left: moveEvent.clientX - mouseStart.left,
top: moveEvent.clientY - mouseStart.top
};
// These margins were only useful for centering the div, now we
// don't need them
this.setState({
marginLeft: '0px',
marginTop: '0px',
left: `${winStart.left + diff.left}px`,
top: `${winStart.top + diff.top}px`,
position: 'absolute'
});
};
// Mouse button up
function handleUp() {
removeListeners();
}
function removeListeners() {
window.removeEventListener('mousemove', handleMove);
window.removeEventListener('mouseup', handleUp);
}
window.addEventListener('mousemove', handleMove);
window.addEventListener('mouseup', handleUp);
return false;
}
render() {
return cloneElement(Children.only(this.props.children), {
ref: (body) => this.body = body,
onMouseDown: this.handleMouseDown,
style: {...this.props.children.props, ...this.state}
});
}
}
module.exports = DraggableWindow;