Drag and Drop Made Easy With RxJS

A quick introduction to a popular feature

Nicholas Cunningham
3 min readJul 11, 2019
Photo by Jack Ross on Unsplash

If you are new to RxJS, you have been missing out!

No worries, though. Now is a great opportunity to start getting involved. In this piece, you will learn how easy it is to create a drag and drop for any element.

I won’t go in-depth about RxJS today. I just wanted to make something quickly, as this feature is regularly requested.

Let’s begin with the element which you would like to be dragged.

Now that we have the element set up, it is time to wire up the JavaScript/TypeScript. I will be using TypeScript, however the same can be applied using JavaScript.

First, we should find the element we would like to drag.

Now for the easy part — getting RxJS to handle our streams. These are what we are considering:

  1. When the user starts to drag the element.
  2. When the user is dragging the element.
  3. When the user has dropped the element.

This is how we would do it:

I used document for our target on mousemove, because the user has the option of moving the mouse outside of our application. I still want to be able to track it so that when they re-enter, the box will still be moving.

There are many ways to handle this, but for this example, I will use this approach.

Drag me

Now, we have our element to drag and the events which we are interested in all wired up. Let’s compose a drag Observable to push out the positions so that we can change/animate the movement.

If you understand what’s going on here, that’s great! Look how easy that is!
I’ll try to explain so that everyone can understand.

What we are doing here is composing the observables. This means I am combining them in such a way that we get values when we need to.

We start off with, as that will tell us when to start tracking for the positions. I’ll explain the switchMap later. Inside that flattening operator (unwrap the observable and return the value) we are subscribing to mousemove$ because I want all the values (positions) while the user is moving the mouse after they have mousedown$.

To find where the box should be moved to, simply find the delta between the starting mousedown and the current position of the mouse given by mousemove$. For further reading, check out OffsetX and ClientX.

Next, we have a takeUntil and we bind it to mouseup$. This keeps streaming all the events from mousemove$, and, when the user releases the mouse (i.e. mouseUp), it stops tracking the mouse move event.

This is a big benefit to using RxJS since you can actively compose streams in different ways all towards your specific use case.

Lastly, we should subscribe and apply the deltas:

That’s all!

See it in action!

By the way, in the stackblitz, there is a little Easter egg. See if you can find and understand it. If you don’t, just research!

Keep on sharing the knowledge. It will only make us stronger.

--

--

Responses (3)