Friday, June 20, 2014

Om examples: Scrubbing Calculator component

I'm starting to get the hang of Om.  While I've used cljs & jayq for a while, understanding the right way to use om + core.async has taken a bit of doing.  They're both great libraries, and have fairly small APIs, but I've been hungry for fairly simple examples.  In that vein, here are a couple, the second inspired by Bret Victor's Scrubbing Calculator.

Update: git repo with examples

Prelude: simple clock

Simple enough, derived from the animation example in om examples.

Scrubbing Int, Approach one: all local state

Two utility functions:

My first attempt entirely used internal state.  Not terribly useful, but it set the stage.

It works entirely in the span element.  Click and drag changes the value. If you drag out of the element before you release the mouse button, the state becomes inconsistent.  The snippet below will let you tune the sensitivity if you use it in the :onMouseMove handler.

Now

Approach two: Moving out the state

So here I've switched things to use an external atom for the value, and moved most of the logic into event listeners under IWillMount.  This works correctly even if you drag off the span element.  It's pretty much everything I set out to do with this.

The only drawback is the event listeners should be connected in the handler for onMouseDown, and removed when "mouseup" is received. I'll update it when I've figured out how to remove existing listeners.

Afterward: Stuff you should be looking at

3 comments:

C. Minos Niu said...

Thanks for the post. But it 's rather difficult to try these ideas without a Leiningen project. I tried to add the dependencies myself, lein-cljsbuild compiles but the final .html shows nothing.

Could you also share an executable project with all dependencies? Thanks!

babui said...

I've created a project with the code of the examples.

You can access it via
https://www.dropbox.com/sh/9oqauimp511efmu/AADrLJhLTLRFdykUmuGDH7K8a

Juan Manuel

Jason Whitlark said...

I added the code to a lein project, using devcards. Hope that helps.