Reactive Programming in frontend — Learn by building — Implement a Free Drawing with Canvas and React

Indie Dev
3 min readDec 5, 2021

I am learning how to to build UI/Data/Event flow handler with RFP. I think the best way to learn is by crafting and building. This is one of my first baby steps to study RP concepts.

I choose RxJS + React as a combo to go through my journey. The first thing I want to build is to turn a Canvas become a Free Drawing place.

Canvas Drawing

So … how to solve it? I tried to imagine that, whenever we move the cursor from the point A to point A1, we will draw a line from A to A1. And continue moving — not release the mouse, just keep moving, we will have another move set from A1->A2, A2->A3, A3->A4, eg… until we release the mouse. So we need to track the Points every movement (Start/End) and draw them on the canvas.

Therefore, I decided to divide the problems into 2 small sub-problems:

  • UI drawing
  • Movement tracking — track the points when move

How to draw a line on canvas

It is easy to draw a line in canvas. We just need 2 Points — Start/End Point then we can use canvas function to draw

function drawALine(canvasEl, startPoint, endPoint) {
const context = canvasEl.getContext("2d");
context.beginPath();
context.moveTo(startPoint.x, startPoint.y);
context.lineTo(endPoint.x, endPoint.y);
context.stroke();
context.closePath()
}

Try it in browser, you can see the result. So .. We solve the first problem.Move next

How to track the position when moving

Using React Hook

We can solve this by using the native approach — addEventListener and a variable to track the the first mouse down , and start drawing when moving, reset that var when leave/mouse up.

We can solve it by using hook — useRef.

With this approach, I tried to introduce to a pointer Ref to track the position. And we see that we have lots of code to attach/remove event listeners.

Yeah, but it is good enough to draw. But it is not enough — I tried to solve it by using Reactive concepts.

Using RxJS

Imagine that we create a stream to stream all the Mouse events (down/move/up/leave).

For each mouse down event, we will take all mousemove events until we have mouseup/mouseleave events. And we will pair 2 points prev/current and call the draw

So, we can use some operators like takeUntil, pairwise

(1,2,3) -> pairwise [(1,2),(2,3)]

So tada, it looks like a pure function chain. I think this approach is prettier than the old one.

That’s all for the first day with RFP concepts !.

--

--