Skip to content

Support moving the segment. #55

Description

@mrybinski

Excellent library! Really easy to use. I starred it and will watch closely.
I can see you're working on the new version, I didn't check it out yet, I just used the latest from npm. So if you already want to add that feature, great!
It would be awesome if you can support segment moving. I forked your lib locally and prototyped the moving (but only assuming there are 2 handles). As you will see, I forked the master, not the beta, that's why I didn't create PR.

My prototype assumes there are 2 handles, but it can be easily extended, to support moving segments between any values (and only moving the ones that have handles on each end).
Let me know if that is something you would like to support. If so, I can spend some free time working on the beta version PR, unless you want to work on this yourself.
For now, I will use my fork of your lib, and include your license message.
Here's the video, and below code that I used.

Screen.Recording.2023-01-11.at.11.44.47.mov

In short, I added this event on segment press:

const handleSegmentPress = React.useCallback(
		(e) => {
			const clientX = e.type === 'touchmove' ? e.changedTouches[0].clientX : e.clientX;

			const onDrag = e => handleSegmentDrag(e, clientX);
			const handleRelease = e => {
				const {
					tempValues,
					values,
					onChange = () => {},
				} = getLatest();

				document.removeEventListener('mousemove', onDrag);
				document.removeEventListener('touchmove', onDrag);
				document.removeEventListener('mouseup', handleRelease);
				document.removeEventListener('touchend', handleRelease);
				const sortedValues = sortNumList(tempValues || values);
				onChange(sortedValues);
				onDrag(sortedValues);
				setTempValues();
			};

			document.addEventListener('mousemove', onDrag);
			document.addEventListener('touchmove', onDrag);
			document.addEventListener('mouseup', handleRelease);
			document.addEventListener('touchend', handleRelease);
		},
		[getLatest, handleSegmentDrag]
	);

and this is handleSegmentDrag:

const handleSegmentDrag = React.useCallback(
		(e, initialX) => {
			const clientX = e.type === 'touchmove' ? e.changedTouches[0].clientX : e.clientX;
			const initial = getValueForClientX(initialX);
			const newValue = getValueForClientX(clientX);
			const diff = newValue - initial;
			if (diff) {
				let actualDiff = 0;
				if (diff > 0) {
					const last = values[values.length - 1];
					const newRoundedLastValue = roundToStep(last + diff);

					actualDiff = newRoundedLastValue - last;
					
				} else {
					const first = values[0];
					const newRoundedFirstValue = roundToStep(first + diff);
					actualDiff = newRoundedFirstValue - first;
				}

				if (actualDiff) {
					setTempValues(values.map(v => v += actualDiff));
				}
			}
			
		},
		[getValueForClientX, roundToStep, values]
	);

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions