Skip to content

Instantly share code, notes, and snippets.

@crazypixel
Last active March 3, 2020 18:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save crazypixel/da3d6e156948afa8b7fc2a387ea28cec to your computer and use it in GitHub Desktop.
Save crazypixel/da3d6e156948afa8b7fc2a387ea28cec to your computer and use it in GitHub Desktop.
import React from 'react';
import styled, { css } from 'styled-components';
export default class Draggable extends React.Component {
state = {
isDragging: false,
originalX: 0,
originalY: 0,
translateX: 0,
translateY: 0,
lastTranslateX: 0,
lastTranslateY: 0
};
componentWillUnmount() {
window.removeEventListener('mousemove', this.handleMouseMove);
window.removeEventListener('mouseup', this.handleMouseUp);
}
handleMouseDown = ({ clientX, clientY }) => {
window.addEventListener('mousemove', this.handleMouseMove);
window.addEventListener('mouseup', this.handleMouseUp);
if (this.props.onDragStart) {
this.props.onDragStart();
}
this.setState({
originalX: clientX,
originalY: clientY,
isDragging: true
});
};
handleMouseMove = ({ clientX, clientY }) => {
const { isDragging } = this.state;
const { onDrag } = this.props;
if (!isDragging) {
return;
}
this.setState(prevState => ({
translateX: clientX - prevState.originalX + prevState.lastTranslateX,
translateY: clientY - prevState.originalY + prevState.lastTranslateY
}), () => {
if (onDrag) {
onDrag({
translateX: this.state.translateX,
translateY: this.state.translateY
});
}
});
};
handleMouseUp = () => {
window.removeEventListener('mousemove', this.handleMouseMove);
window.removeEventListener('mouseup', this.handleMouseUp);
this.setState(
{
originalX: 0,
originalY: 0,
lastTranslateX: this.state.translateX,
lastTranslateY: this.state.translateY,
isDragging: false
},
() => {
if (this.props.onDragEnd) {
this.props.onDragEnd();
}
}
);
};
render() {
const { children } = this.props;
const { translateX, translateY, isDragging } = this.state;
return (
<Container
onMouseDown={this.handleMouseDown}
x={translateX}
y={translateY}
isDragging={isDragging}
>
{children}
</Container>
);
}
}
const Container = styled.div.attrs({
style: ({ x, y }) => ({
transform: `translate(${x}px, ${y}px)`
}),
})`
cursor: grab;
${({ isDragging }) =>
isDragging && css`
opacity: 0.8;
cursor: grabbing;
`};
`;
@TeacherNan
Copy link

good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment