Make slider handles stick to the cursor

This commit is contained in:
adroitwhiz 2020-07-31 12:29:58 -04:00
parent 4f86762737
commit a436c6f3a8

View file

@ -17,15 +17,21 @@ class SliderComponent extends React.Component {
'handleMouseUp', 'handleMouseUp',
'handleMouseMove', 'handleMouseMove',
'handleClickBackground', 'handleClickBackground',
'setBackground' 'setBackground',
'setHandle'
]); ]);
// Distance from the left edge of the slider handle to the mouse down/click event
this.handleClickOffset = 0;
} }
handleMouseDown () { handleMouseDown (event) {
document.addEventListener('mousemove', this.handleMouseMove); document.addEventListener('mousemove', this.handleMouseMove);
document.addEventListener('mouseup', this.handleMouseUp); document.addEventListener('mouseup', this.handleMouseUp);
document.addEventListener('touchmove', this.handleMouseMove, {passive: false}); document.addEventListener('touchmove', this.handleMouseMove, {passive: false});
document.addEventListener('touchend', this.handleMouseUp); document.addEventListener('touchend', this.handleMouseUp);
this.handleClickOffset = getEventXY(event).x - this.handle.getBoundingClientRect().left;
} }
handleMouseUp () { handleMouseUp () {
@ -41,20 +47,26 @@ class SliderComponent extends React.Component {
} }
handleClickBackground (event) { handleClickBackground (event) {
// Move slider handle's center to the cursor
this.handleClickOffset = HANDLE_WIDTH / 2;
this.props.onChange(this.scaleMouseToSliderPosition(event)); this.props.onChange(this.scaleMouseToSliderPosition(event));
} }
scaleMouseToSliderPosition (event){ scaleMouseToSliderPosition (event){
const {x} = getEventXY(event); const {x} = getEventXY(event);
const backgroundBBox = this.background.getBoundingClientRect(); const backgroundBBox = this.background.getBoundingClientRect();
const scaledX = x - backgroundBBox.left; const scaledX = x - backgroundBBox.left - this.handleClickOffset;
return Math.max(0, Math.min(100, 100 * scaledX / backgroundBBox.width)); return Math.max(0, Math.min(100, 100 * scaledX / (backgroundBBox.width - HANDLE_WIDTH)));
} }
setBackground (ref) { setBackground (ref) {
this.background = ref; this.background = ref;
} }
setHandle (ref) {
this.handle = ref;
}
render () { render () {
const halfHandleWidth = HANDLE_WIDTH / 2; const halfHandleWidth = HANDLE_WIDTH / 2;
const pixelMin = halfHandleWidth; const pixelMin = halfHandleWidth;
@ -76,6 +88,7 @@ class SliderComponent extends React.Component {
> >
<div <div
className={styles.handle} className={styles.handle}
ref={this.setHandle}
style={{ style={{
left: `${handleOffset}px` left: `${handleOffset}px`
}} }}