Re: [ClojureScript] [ANN] Ominate - animate your Om components

2014-05-06 Thread Jack Schaedler
Agree with everything Dylan said. It looks like the React team are working on 
this issue too:

Scroll down to the 'Animations' header:
http://facebook.github.io/react/blog/


As a random thought, QML has an interesting set of mechanisms for declaratively 
specifying animations that should trigger on property and state changes. The 
situation is probably a bit more complex in the Om->React->Mutable Dom 
situation, but there might be some inspiration or at least things to learn from 
the QML implementation:

http://qt-project.org/doc/qt-4.8/qdeclarativeanimation.html

Just a random thought!


On Tuesday, May 6, 2014 8:33:32 PM UTC+2, Dylan Butman wrote:
> I've thought about React and Om animation a lot and have been meaning to 
> strip the animation code out of some of my projects and get it organized. I 
> wrote https://github.com/pleasetrythisathome/react.animate for react a little 
> while ago, and haven't quite got around to porting all the functionality to 
> cljs. 
> 
> Your easing functions are definitely helpful. 
> 
> To me it seems like an anti pattern and a generally dangerous thing to do to 
> mutate the DOM directly. The whole point of using something like React or Om 
> is that the DOM is the result of a pure render function that takes props 
> (app-state) and component state as inputs. If you mutate the DOM yourself, 
> this is no longer true.
> 
> For my uses, I'd greatly prefer a more minimal library that will transition 
> two values with an easing function over a set duration. Automatic 
> interpolation of standard data types would also be great (like the d3 
> interpolators I use in react.animate)
> 
> I'll spend some time tonight and the next few days on getting something going 
> and then we can compare notes!
> 
> The big question for me has always been how to deal with the add/remove item 
> from a list enter/exit animation that Jack is talking about. 
> 
> Ideally animation could shouldn't pollute your application, and should be an 
> arbitrary addition. 
> 
> It's straightforward to init-state at some state (say :width 0) and then 
> start a transition to :width 100 in IWillMount, which would happen for any 
> entering component. IWillUnmount is called when a component exits, but since 
> the component is actually unmounted right after it'd be useful to call a 
> transition here. 
> 
> ReactTransitionGroup http://facebook.github.io/react/docs/animation.html 
> tries to solve this by providing methods like componentWillLeave(callback) 
> where you are intended to call the callback when you're done with whatever 
> animation to actually trigger DOM removal. 
> 
> You could definitely do something similar with Om, but I think there are 
> probably more elegant ways...I need to spend some time experimenting and see 
> what happens...

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.


Re: [ClojureScript] [ANN] Ominate - animate your Om components

2014-05-05 Thread Jack Schaedler
HI Daniel,

Apologies in advance for the probably stupid question:

My main use case is to animate elements as they enter and leave the Dom. 
Something similar to the way that CSSTransitionGroups work, but hopefully with 
more of the power you are providing with the easing functions and timing 
mechanisms. I just had a go at incorporating the Ominate library with Goya and 
I'm not entirely sure about the best way to proceed for this use case. I tried 
using the :watch config option, but didn't have much luck. Should I be 
explicitly sending a request to trigger the animation via the channel, or is 
the watch facility sufficient for this use-case? Do you have an example of this 
behavior somewhere I could look at?

Sorry again, it's late here and my head is starting to swim a bit. Let me know 
if the question makes sense!


On Monday, May 5, 2014 10:09:53 AM UTC+2, Daniel Kersten wrote:
> Excuse the typos in my previous mail, typing on a phone. 
> 
> I wanted to add that I think it makes sense to move all of the public 
> animation state into the child components local state rather than passing it 
> in as a cursor as IMHO app state should be reserved for domain data while 
> local state makes sense for transient visual data like animation. Also, the 
> child will never transact! it (as it would be overwritten next frame anyway), 
> so a cursor seems unnecessary. 
> 
> 
> I'll make that change to animated-components later. 
> 
> On 5 May 2014 08:57, "Daniel Kersten"  wrote:
> 
> 
> I think there's definitely merit in your suggestion as it allows components 
> to animate themselves, plays nicer with Om and React and potentially will 
> have smoother animation too,  but I'm not yet sure what it should look like.
> 
> 
> 
> I've rewritten ominate to use your approach in the animated-components branch 
> (I'll be pushing an update soon that puts its features almost on par with 
> master, the only thing missing is auto repeating animations). Would love your 
> feedback on it. 
> 
> 
> 
> Does it really make sense to wrap a component that knows it's being animated 
> in animation logic rather than providing something that can be used 
> internally?
> 
> It seems odd to require the component consumer to know Scott the nitty gritty 
> animation details when the component itself also has to know about it. 
> 
> On the other hand, I can see a lot of value in using animated components as 
> wrappers to other components that don't know their being animated kind of 
> like om component versions of my existing animation functions. 
> 
> 
> 
> Again would love feedback especially on api design.
> 
> Over all, I see three types of animation: a component that animates itself 
> internally (eg your example code), a component which is animated that 
> contains sub components (possibly by rendering animated borders or overlays 
> around or over the sub component) and post processing a component by 
> modifying and animating a dom node after rendering (eg, the code in master). 
> 
> 
> 
> I think the code in animated-components could easily address second and 
> third, but as I said above, I'm unsure about how the first should look. I'll 
> give that use case some hammock time :-)
> 
> Re easing functions - absolutely, go for it! Move them into their own lib if 
> you wish (but note that not all currently work...). I ported them from 
> another library anyway (url in comments in the source).
> 
> 
> 
> I am wondering if they should be rewritten though. I saw another library 
> which has a set of functions (eg quadratic, cubic, sine etc) and a separate 
> set of functions for ease-in, ease-out, ease-in-out. I already provide 
> composable functions for reversing and such, maybe in/out should simply 
> compose with the interpolation functions too? Seems more flexible. Definitely 
> should be it's own library then, though.
> 
> 
> 
> On 5 May 2014 03:37, "Dave Della Costa"  wrote:
> 
> 
> I was more just curious if there was a benefit to one over the other!  I
> 
> can see it potentially being useful to have animations outside of
> 
> Om/React's control flow--but in that case it would probably make more
> 
> sense as a separate library.
> 
> 
> 
> In any case glad it sparked some ideas.
> 
> 
> 
> I'll probably put my simpler version out as a simple Om component, since
> 
> I need something minimal (and I'll probably reference/include your handy
> 
> easing functions if you don't mind).  But I'll keep my eye on ominate to
> 
> see how it goes...good luck with it!
> 
> 
> 
> DD
> 
> 
> 
> (2014/05/05 4:01), Daniel Kersten wrote:
> 
> > So, I've spent the past 45 minutes thinking about this and here's what
> 
> > I've come up with:
> 
> >
> 
> >   * I love the idea of animated components - components that react to a
> 
> >     certain bit of app-state to animate themselves
> 
> >   * I like the idea of animated wrapper components - that is, components
> 
> >     which wrap non-animated components in order to make them animated
> 
> 

[ClojureScript] Re: [ANN] Ominate - animate your Om components

2014-05-04 Thread Jack Schaedler
Very cool. I tried to use the CSSTransitionGroup on Goya, but it left a bit to 
be desired. I'm going to try incorporating this tonight!


On Sunday, May 4, 2014 2:48:37 PM UTC+2, Daniel Kersten wrote:
> Just pushed an update which adds the ability to watch app-state changes to 
> trigger animations and specify a notify function that gets called when the 
> animation completes. Also "upgraded" the documentation :)
> 
> 
> 
> 
> 
> On 4 May 2014 01:25, Daniel Kersten  wrote:
> 
> 
> 
> Hey everyone,
> 
> 
> I've just pushed my little Om project to Clojars and Github :)
> It's still early in development, but I'd love some feedback on how it should 
> progress.
> 
> 
> 
> 
> 
> Ominate allows you to animate any Om component by wrapping the component in 
> (ominate ...) before passing it to build, specifying duration, easing 
> function and animation.
> 
> 
> https://github.com/danielytics/ominate
> 
> 
> 
> 
> 
> 
> ---
> 
> 
> Animations are simply functions which take in a value between 0 and 1 and the 
> DOM node of the component being animated and then do "something" to the DOM 
> node (typically changing it's style). Additionally, animations may provide 
> begin and end functions which get applied to the DOM node before and after 
> the animation runs, allowing them to modify the node to prepare for the 
> animation and then clean up again afterwards.
> 
> 
> 
> 
> 
> 
> Currently, Ominate is only packaged with two animations: fading (changing 
> opacity over time) and color-fading (blending? - placing a color overlay 
> above the component and then fading that). I plan on adding many more 
> animations after I've finalized the API. Right now, animations are triggered 
> by putting a value on a channel.
> 
> 
> 
> 
> 
> I'm still deciding what the final API should look like. Feedback and 
> suggestions welcome!
> 
> 
> Some ideas I'm thinking about:
> I would like to allow animations to be triggered by app state change, perhaps 
> by passing a cursor to Ominate and a predicate function to apply to the 
> cursor - when it returns true, the animation is triggered.
> 
> 
> Ominate should also report animation completion back to the user - a callback 
> passed to (ominate ...) is probably the best way to do this.It would be cool 
> if different animations can be "sent" to the component rather than only 
> supporting preset animations.

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.


[ClojureScript] Re: Om: where to organize shared state?

2014-05-02 Thread Jack Schaedler
My feeling is that your app-state atom should contain everything that would be 
saved into a document if your user did a File->Save in a conventional desktop 
application. Given that, it wouldn't seem appropriate to put things like 
channels or flags for tracking mouse/hover state and that sort of thing into 
the app-state atom. I feel that that sort of thing should live in component 
local state.
I agree that things get a bit trickier in the case you outlined with the 
'current-cat' example. You can pass multiple cursors to a component 
(https://github.com/swannodette/om/wiki/Cursors), so the cat-viewer component 
could rely on two cursors: one cursor to the list of kitties, and another to 
the :cat-viewer-widget entry which would allow it to transact! directly on the 
app state and set the current cat itself.

An alternative approach is to have the cat-viewer-widget just pass an event on 
a channel when someone selects a cat. A parent component would then be 
responsible for pulling this event off the channel and transacting! on the app 
state to set the current cat.

In my project, I have the exact same situation, except I'm displaying and 
selecting colors instead of cats 
(https://github.com/jackschaedler/goya/blob/master/src/cljs/goya/appstate.cljs 
See :palette and :paint-color). I've decided to go with the second option, 
creating a parent component which has a cursor to basically the entire 
application state (which is less than ideal), and this component builds a child 
component whose job is to render the list of colors and pass any 
clicks/selections on those colors to the parent component via an async channel:

https://github.com/jackschaedler/goya/blob/master/src/cljs/goya/components/palette.cljs#L18

The parent component is then responsible for transacting! on the app-state - 
It's acting sort of like a controller for all child components, waiting for 
children to send events or requests over the channels it created in its 
component local state.

As for the 'should you transact! or let someone else do it for you' question, I 
think that just needs to be worked out on a case by case basis. I've mixed and 
matched a bit, and I don't see any benefit to letting another component 
transact! on your behalf if you can do it via your own cursor 
(https://github.com/jackschaedler/goya/blob/master/src/cljs/goya/components/canvastools.cljs#L26)

Those are my very un-informed two cents coming from a complete beginner :) 
Hopefully that's somehow helpful!




On Friday, May 2, 2014 7:32:40 AM UTC+2, Elliot Block wrote:
> There seems to be a few types of shared state in an Om system:
> 
> 1. "model"-ish data, e.g. if your app's about cats, a list of cats.
> 2. "view"-ish data, like whether a given UI panel is shown or hidden
> 3. coordination-ish data, like async channels so that components can talk to 
> each other, e.g. to show or hide panels, to switch the cat being displayed.
> 
> Which one or more of these is supposed to go in the global app-state atom?
> 
> Suppose that you put both model and view state in the app-state atom:
> 
> (def app-state
>   (atom {:cats {"Fluffy" {:age 7}
> "Scratchy" {:age 5}}
>  :cat-viewer-widget {:current-cat "Fluffy"}}))
> 
> How do you provide a cursor to the cat viewer widget without giving it a 
> completely global cursor, or without hopelessly intermixing the model and 
> view data?
> 
> Alternatively, suppose that only the "model" data lives in `app-state` atom.  
> Presumably then the view state is component-local, but then that just implies 
> you need a globally addressable async channel to talk to it.  Where does one 
> put the async channels so that other components can talk to them?  Options 
> include:
> 
> - Include channels in `app-state` atom
> - :shared global component state
> - Some other var in scope in the namespace
> 
> (This also raises the question of, when you should prefer to om/transact! 
> directly vs. use a channel to ask some other process to transact! for you?  
> But I'll leave that one for now.)
> 
> Haven't been able to find a write-up on this in the past few days.  Any 
> guidance greatly appreciated.  Thank you!
> 
> - Elliot

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.


Re: [ClojureScript] Om: where to organize shared state?

2014-05-02 Thread Jack Schaedler
My feeling is that your app-state atom should contain everything that would be 
saved into a document if your user did a File->Save in a conventional desktop 
application. Given that, it wouldn't seem appropriate to put things like 
channels or flags for tracking mouse/hover state and that sort of thing into 
the app-state atom. I feel that that sort of thing should live in component 
local state.

I agree that things get a bit trickier in the case you outlined with the 
'current-cat' example. You can pass multiple cursors to a component 
(https://github.com/swannodette/om/wiki/Cursors), so the cat-viewer component 
could rely on two cursors: one cursor to the list of kitties, and another to 
the :cat-viewer-widget entry which would allow it to transact! directly on the 
app state and set the current cat itself.

An alternative approach is to have the cat-viewer-widget just pass an event on 
a channel when someone selects a cat. A parent component would then be 
responsible for pulling this event off the channel and transacting! on the app 
state to set the current cat.

In my project, I have the exact same situation, except I'm displaying and 
selecting colors instead of cats 
(https://github.com/jackschaedler/goya/blob/master/src/cljs/goya/appstate.cljs 
See :palette and :paint-color). I've decided to go with the second option, 
creating a parent component which has a cursor to basically the entire 
application state (which is less than ideal), and this component builds a child 
component whose job is to render the list of colors and pass any 
clicks/selections on those colors to the parent component via an async channel:

https://github.com/jackschaedler/goya/blob/master/src/cljs/goya/components/palette.cljs#L18

The parent component is then responsible for transacting! on the app-state - 
It's acting sort of like a controller for all child components, waiting for 
children to send events or requests over the channels it created in its 
component local state.

As for the should you transact! or let someone else do it for you, I think that 
just seems like it has to be worked out on a case by case basis. I've mixed and 
matched a bit, and I don't see any benefit to letting another component 
transact! on your behalf if you can do it via your own cursor 
(https://github.com/jackschaedler/goya/blob/master/src/cljs/goya/components/canvastools.cljs#L26)

Those are my very un-informed two cents coming from a complete beginner :) 
Hopefully that's somehow helpful!




On Friday, May 2, 2014 8:19:00 AM UTC+2, Sean Corfield wrote:
> On Thu, May 1, 2014 at 10:32 PM, Elliot Block  wrote:
> 
> > 1. "model"-ish data, e.g. if your app's about cats, a list of cats.
> 
> > 2. "view"-ish data, like whether a given UI panel is shown or hidden
> 
> > 3. coordination-ish data, like async channels so that components can talk 
> > to each other, e.g. to show or hide panels, to switch the cat being 
> > displayed.
> 
> 
> 
> My understanding so far is:
> 
> 
> 
> 1. app-state, cursors
> 
> 2. local component state
> 
> 3. :opts (shared readonly data)
> 
> 
> 
> If that's not right, I look forward to being educated!
> 
> -- 
> 
> Sean A Corfield -- (904) 302-SEAN
> 
> An Architect's View -- http://corfield.org/
> 
> World Singles, LLC. -- http://worldsingles.com/
> 
> 
> 
> "Perfection is the enemy of the good."
> 
> -- Gustave Flaubert, French realist novelist (1821-1880)

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.


Re: [ClojureScript] Re: ANN: Om 0.6.1, moving towards independently addressable components

2014-04-28 Thread Jack Schaedler
No problem. If you'd like me to test any changes, just let me know!

On Monday, April 28, 2014 9:46:38 PM UTC+2, David Nolen wrote:
> Thanks for the report! This seems like a bug, I went ahead and filed an issue 
> for it.
> 
> 
> David
> 
> 
> 
> On Mon, Apr 28, 2014 at 3:40 PM, Jack Schaedler  wrote:
> 
> 0.6.2 seems to work great! I did have one issue with the tx-listen mechanism. 
> I have a bunch of root components, and had to move the registration of the 
> tx-listen function to the first call to om/root. Otherwise, the tx-listen 
> function would not get called. I noticed that there was a bug-fix commit 
> related to multi-root apps using tx-listen, so this is probably just a case 
> of me misusing the feature in pre 0.6.1 versions. See the commit in the Goya 
> repo here:
> 
> 
> 
> 
> https://github.com/jackschaedler/goya/commit/21e26869e2ceeb44a5fc8e132f4a72e697ca0fc3
> 
> 
> 
> 
> 
> On Thursday, April 24, 2014 7:03:37 PM UTC+2, David Nolen wrote:
> 
> > Om 0.6.1 significantly changes how component local state works - we now 
> > rely on React's forceUpdate to update components that use local state. This 
> > is a significant change so I would like people test this out on their 
> > existing code bases as soon as possible.
> 
> 
> >
> 
> >
> 
> >
> 
> > The immediate benefit is that components now use `=` for the 
> > shouldComponentUpdate logic instead of `identical?`. This means 
> > considerably more flexibility with regards to what a component may receive 
> > without taking a performance hit with respect to rendering. Even more 
> > importantly it's a big step towards independently addressable components.
> 
> 
> >
> 
> >
> 
> >
> 
> > What are independently addressable components? Currently many people 
> > struggle with the fact that parent components must take all the data 
> > associated with their children. This often results in a tight coupling that 
> > is not ideal for real applications. The next few releases of Om will be 
> > focused on providing a sensible solution to this issue without backing away 
> > from the existing efficient time travel capabilities.
> 
> 
> >
> 
> >
> 
> >
> 
> > Feedback welcome!
> 
> >
> 
> >
> 
> > http://github.com/swannodette/om
> 
> >
> 
> >
> 
> >
> 
> > David
> 
> 
> 
> 
> 
> --
> 
> Note that posts from new members are moderated - please be patient with your 
> first post.
> 
> ---
> 
> You received this message because you are subscribed to the Google Groups 
> "ClojureScript" group.
> 
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to clojurescrip...@googlegroups.com.
> 
> To post to this group, send email to clojur...@googlegroups.com.
> 
> Visit this group at http://groups.google.com/group/clojurescript.

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.


[ClojureScript] Re: ANN: Om 0.6.1, moving towards independently addressable components

2014-04-28 Thread Jack Schaedler
0.6.2 seems to work great! I did have one issue with the tx-listen mechanism. I 
have a bunch of root components, and had to move the registration of the 
tx-listen function to the first call to om/root. Otherwise, the tx-listen 
function would not get called. I noticed that there was a bug-fix commit 
related to multi-root apps using tx-listen, so this is probably just a case of 
me misusing the feature in pre 0.6.1 versions. See the commit in the Goya repo 
here:

https://github.com/jackschaedler/goya/commit/21e26869e2ceeb44a5fc8e132f4a72e697ca0fc3

On Thursday, April 24, 2014 7:03:37 PM UTC+2, David Nolen wrote:
> Om 0.6.1 significantly changes how component local state works - we now rely 
> on React's forceUpdate to update components that use local state. This is a 
> significant change so I would like people test this out on their existing 
> code bases as soon as possible.
> 
> 
> 
> The immediate benefit is that components now use `=` for the 
> shouldComponentUpdate logic instead of `identical?`. This means considerably 
> more flexibility with regards to what a component may receive without taking 
> a performance hit with respect to rendering. Even more importantly it's a big 
> step towards independently addressable components.
> 
> 
> 
> What are independently addressable components? Currently many people struggle 
> with the fact that parent components must take all the data associated with 
> their children. This often results in a tight coupling that is not ideal for 
> real applications. The next few releases of Om will be focused on providing a 
> sensible solution to this issue without backing away from the existing 
> efficient time travel capabilities.
> 
> 
> 
> Feedback welcome!
> 
> 
> http://github.com/swannodette/om
> 
> 
> 
> David

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.


Re: [ClojureScript] Pixel Art Editor - Built with Om

2014-04-17 Thread Jack Schaedler
Sounds good, I'll write something up this weekend!

After watching your Functional Final Frontier talk I redid the undo mechanism a 
few times (trying to make components completely ignorant of the global 
undo-strategy), and I think tracking that progression could make for an 
interesting writeup.

Glad to hear that you don't find the multiple roots too nasty. I was tempted to 
switch to a single root which passes cursor(s)  to all of the child components, 
but the multiple roots approach is quite handy!

Best,
-jack


On Thursday, April 17, 2014 5:12:04 PM UTC+2, David Nolen wrote:
> On Thu, Apr 17, 2014 at 9:18 AM, Jack Schaedler  wrote:
> 
> 
> 
> Thanks David!
> 
> 
> 
> I apologize in advance for some of the nasty code in there. I've tried to do 
> everything as idiomatically as possible wrt Om, but have fallen a bit short 
> due to my own misunderstandings. I'm thinking it might be worthwhile to write 
> up a little blog post about my experience so far. As an example, I'm using 
> tx:listen to manage the undo/redo history, but my components still aren't 
> completely agnostic about the outside app's undo strategy since they need to 
> tag transactions with a particular tag to invoke the creation of an 
> undo-step. I also have an embarrassing mess of root components which seems 
> somehow un-Ommy.
> 
> 
> 
> 
> Please do write up a blog post - it would be especially informative to hear 
> more details about the parts of the application that you're unhappy with 
> respect to modularity like you've mentioned here. This is certainly an area 
> in Om that needs work - more discussion and ideas are welcome!
> 
> 
> 
> As far as the multiple root components - that's actually quite a nice use of 
> that feature in Om!
> 
> 
> David

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.


Re: [ClojureScript] Pixel Art Editor - Built with Om

2014-04-17 Thread Jack Schaedler
Thanks David! 

I apologize in advance for some of the nasty code in there. I've tried to do 
everything as idiomatically as possible wrt Om, but have fallen a bit short due 
to my own misunderstandings. I'm thinking it might be worthwhile to write up a 
little blog post about my experience so far. As an example, I'm using tx:listen 
to manage the undo/redo history, but my components still aren't completely 
agnostic about the outside app's undo strategy since they need to tag 
transactions with a particular tag to invoke the creation of an undo-step. I 
also have an embarrassing mess of root components which seems somehow un-Ommy. 

Anyway, thanks so much for Om. I'm really, really enjoying learning more about 
this model of programming. It's absolutely incredible how little time I spend 
debugging the sorts of problems I'm accustomed to after coming from 
imperative/PLOP land. I finally feel like I'm not building a pyramid anymore ;)

Thanks for linking from the Om readme! That's good motivation for me to clean 
up some of my messy code.

Best,
-jack




On Thursday, April 17, 2014 3:07:31 PM UTC+2, David Nolen wrote:
> Wow this is great! I've linked to it from the Om README.
> 
> 
> David
> 
> On Thursday, April 17, 2014, Jack Schaedler  wrote:
> 
> Hey all,
> 
> 
> 
> Thought I'd share a little side project I've been working on for the past few 
> weeks. It's a simple pixel art editor for making 64x64 sprites. It's built on 
> Om.
> 
> 
> 
> App:
> 
> jackschaedler.github.io/goya/
> 
> 
> 
> Repo:
> 
> https://github.com/jackschaedler/goya
> 
> 
> 
> This represents my first dive into Clojure, and of course, my first Om app. I 
> was really excited when my colleague pointed me to David Nolen's Time Travel 
> blog post, and I wanted to see if I could build something similar as an 
> introduction to Clojure/Clojurescript. I thought it might be useful to put 
> the code out there for public critique as the whole thing is meant to be a 
> learning exercise. Any and all advice or criticism is welcomed!
> 
> 
> 
> 
> Best,
> 
> Hopefully the code doesn't make your eyes bleed,
> 
> -jack
> 
> 
> 
> --
> 
> Note that posts from new members are moderated - please be patient with your 
> first post.
> 
> ---
> 
> You received this message because you are subscribed to the Google Groups 
> "ClojureScript" group.
> 
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to clojurescript+unsubscr...@googlegroups.com.
> 
> 
> To post to this group, send email to clojurescript@googlegroups.com.
> 
> Visit this group at http://groups.google.com/group/clojurescript.

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.


[ClojureScript] Pixel Art Editor - Built with Om

2014-04-17 Thread Jack Schaedler
Hey all,

Thought I'd share a little side project I've been working on for the past few 
weeks. It's a simple pixel art editor for making 64x64 sprites. It's built on 
Om.

App:
jackschaedler.github.io/goya/

Repo:
https://github.com/jackschaedler/goya

This represents my first dive into Clojure, and of course, my first Om app. I 
was really excited when my colleague pointed me to David Nolen's Time Travel 
blog post, and I wanted to see if I could build something similar as an 
introduction to Clojure/Clojurescript. I thought it might be useful to put the 
code out there for public critique as the whole thing is meant to be a learning 
exercise. Any and all advice or criticism is welcomed!

Best,
Hopefully the code doesn't make your eyes bleed,
-jack

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.


Re: [ClojureScript] Om: Question about how best to structure app state and use cursors

2014-04-10 Thread Jack Schaedler
Does it make any sense to allow components to reference multiple cursors? 
Instead of specifying a single path into the application state, you would 
specify a collection of paths within the state atom, all of which would trigger 
re-renders and allow for transact! and update!? I often find myself pulling 
component cursor paths 'up' the tree in order to ensure that the cursor is 
broad enough to capture all of the state changes that might cause a re-render.

That being said, I still have the feeling that in the majority of cases, the 
confined scope of the cursor guides me towards a more sensible layout of the 
application state.


On Thursday, April 10, 2014 4:12:31 AM UTC+2, David Nolen wrote:
> Yes it's a problem that you encounter in React if you try to do things in a 
> functional manner. It's not really a "limitation" of React or Om. But at 
> least in the case of Om I consider it a deficiency great enough to build 
> direct support so that users aren't hampered by it or forced to come up with 
> their own ad-hoc solutions.
> 
> 
> 
> David
> 
> 
> 
> On Wed, Apr 9, 2014 at 10:05 PM, Brendan Stromberger  
> wrote:
> 
> I've encountered this issue in vanilla React (js), and couldn't figure out 
> any other way than munging my data together such that I could pass it down in 
> the way OP describes. I guess my question is, is this limitation inherent in 
> React or in the Om abstraction?
> 
> 
> 
> 
> 
> On Wednesday, April 9, 2014 3:52:05 AM UTC-7, David Nolen wrote:
> 
> > You're not missing anything. This is a fundamental issue in Om right now 
> > and I've been designing and working on a fix. Basically in the very near 
> > future a component will be able to access something in the application 
> > state without needing a parent component to pass it in from above.
> 
> 
> >
> 
> >
> 
> >
> 
> > The idea is that a component will be able to get its data directly from the 
> > app state with something like (om/get-shared owner [:app-state :foo]).
> 
> >
> 
> >
> 
> > Still working out the details, but this work is happening in the 
> > `ind-components` branch. When it's finished there'll be an accompanying 
> > nested tab view example - one of the cases that suffers the most under the 
> > current system.
> 
> 
> >
> 
> >
> 
> >
> 
> >
> 
> > David
> 
> >
> 
> >
> 
> >
> 
> 
> > On Wed, Apr 9, 2014 at 6:33 AM, Daniel Kersten  wrote:
> 
> >
> 
> >
> 
> > Hi,
> 
> >
> 
> >
> 
> > I'm trying to figure out the best way of structuring complex applications 
> > in Om and I've hit a bit of a brick wall that I'm hoping someone can help 
> > me with.
> 
> >
> 
> >
> 
> >
> 
> >
> 
> >
> 
> > I like the concept of cursors - narrow down the application state to what 
> > the individual components actually need and allow them to read and modify 
> > only that.
> 
> >
> 
> >
> 
> > The problem I'm having is that I don't know how to structure my state so 
> > that the correct components have access to everything they need. Its easy 
> > if each component only requires a strict subset of its parent, which is 
> > often the case, but not always. I've hit a scenario where a component needs 
> > access to two very different branches of the app state and I'm not sure how 
> > to pass it to the component that needs it.
> 
> 
> >
> 
> >
> 
> >
> 
> >
> 
> >
> 
> > As a (contrived) example, imagine you had an app for displaying orders in 
> > an online store and the application state is something like this:
> 
> >
> 
> >
> 
> > (def app-state (atom {:items  [{:type "book" :price 123} {:type "cd" :price 
> > 200}]
> 
> >
> 
> >
> 
> >
> 
> >                       :orders [{:date xxx :type "book" :count 3} {:date yyy 
> > :type "cd" :count 1}]
> 
> >                       :filter "book"}))
> 
> >
> 
> >
> 
> >
> 
> >
> 
> >
> 
> > You can imagine that in a real application the :items and :orders branches 
> > may be much deeper.
> 
> >
> 
> >
> 
> > Lets say I now have two components, one displaying the items (so it is 
> > passed a cursor with path [:items]) and one displaying the orders (so it is 
> > passed a cursor with path [:orders]). What if I now only want to display 
> > items and orders where the type matches the filter?
> 
> 
> >
> 
> >
> 
> >
> 
> >
> 
> >
> 
> > I have a few options:
> 
> > Restructure the app state in a way that gives each component access to what 
> > it needs. This is not ideal as it means that I'm modelling my state after 
> > how its being rendered rather than how its being processed and makes it 
> > very application specific.
> 
> 
> >
> 
> >
> 
> > I can propagate the additional values down the component tree (eg using the 
> > :state parameter to build), but this means that every other component 
> > before the one that consumes it must now do additional work that it 
> > shouldn't need to know about (couples the parent components too tightly to 
> > the child one)
> 
> 
> >
> 
> >
> 
> > Similarly, passing it in opts is not ideal as it has the same issue as #2, 
> > with the added cave

Re: [ClojureScript] OM: What is the best way of introducing animation/effects during application state transition ?

2014-03-16 Thread Jack Schaedler
Hi David,

Thanks for the quick response! Seems to be working just fine now. I must have 
screwed up something simple when I initially tried it yesterday. 


For posterity:

1) Access the CSSTransitionGroup from cljs:
(def css-trans-group (-> js/React (aget "addons") (aget "CSSTransitionGroup")))

2) Wrap your elements in a css-trans-group just like you would a dom/div or 
dom/ul or whatever:

(om/root
  (fn [app owner]
(apply css-trans-group #js {:className "my-class-name" :transitionName 
"example"}
  (map (fn [text] (dom/li nil text)) (:list app
  app-state
  {:target (. js/document (getElementById "app0"))})

3) Adhere to the naming convention for transition classes in your css (noting 
use of 'example' above):

.example-enter {
  opacity: 0.01;
  transition: opacity .5s ease-in;
}

.example-enter.example-enter-active {
  opacity: 1;
}


.example-leave {
  opacity: 1;
  transition: opacity .5s ease-in;
}

.example-leave.example-leave-active {
  opacity: 0.01;
}


Best,
-jack


On Saturday, March 15, 2014 5:20:07 PM UTC+1, David Nolen wrote:
> Several people have successfully used the CSS transition group add on, 
> hopefully they can chime in.
> 
> On Saturday, March 15, 2014, Jack Schaedler  wrote:
> 
> Hi David,
> 
> 
> 
> Thanks heaps for all of your tutorials and work on Om. I've got a nice little 
> clojurescript app with full undo/redo working with Om thanks to your 
> tutorials and blog posts, and my goal for today is to work on animations.
> 
> 
> 
> 
> As an alternative to the interval within IWillMount, has anyone successfully 
> used the ReactCSSTransitionGroup 
> (http://facebook.github.io/react/docs/animation.html) addon within Om? I'm a 
> newcomer to both cljs and React, and I've unsuccessfully attempted to do 
> something like:
> 
> 
> 
> 
> (def css-trans-group (-> js/React (aget "addons") (aget 
> "CSSTransitionGroup")))
> 
> 
> 
> (defn my-component [app owner]
> 
>   (reify
> 
>     om/IRender
> 
>     (render [this]
> 
>       (css-trans-group #js {:transitionName "example"}
> 
>       (apply dom/div nil
> 
>         (om/build-all palette-entry-component palette))
> 
> 
> 
> Is this sort of approach reasonable within Om? Sorry in advance for the 
> probably silly question!
> 
> 
> 
> -jack
> 
> 
> 
> 
> 
> 
> 
> On Saturday, March 8, 2014 3:08:52 AM UTC+1, David Nolen wrote:
> 
> > I would probably do this by hooking into IWillUpdate. Generally whatever 
> > solution makes sense for React will make sense for Om.
> 
> >
> 
> >
> 
> > David
> 
> >
> 
> >
> 
> >
> 
> >
> 
> > On Fri, Mar 7, 2014 at 8:35 PM,   wrote:
> 
> >
> 
> > Hi Everyone,
> 
> >
> 
> >
> 
> >
> 
> > I have an application state
> 
> >
> 
> >
> 
> >
> 
> > (def app-state (atom {:index 0 :some-list [1 2 3 4]}))
> 
> >
> 
> >
> 
> >
> 
> > When next button is clicked, index is incremented and the corresponding 
> > item from the :some-list is displayed. Now I want to introduce an 
> > animation/effect during the transition from one item to another. How should 
> > I go about it in Om ?
> 
> 
> >
> 
> >
> 
> >
> 
> >
> 
> > regards
> 
> >
> 
> >
> 
> >
> 
> > --
> 
> >
> 
> > Note that posts from new members are moderated - please be patient with 
> > your first post.
> 
> >
> 
> > ---
> 
> >
> 
> > You received this message because you are subscribed to the Google Groups 
> > "ClojureScript" group.
> 
> >
> 
> > To unsubscribe from this group and stop receiving emails from it, send an 
> > email to clojurescrip...@googlegroups.com.
> 
> 
> >
> 
> > To post to this group, send email to clojur...@googlegroups.com.
> 
> >
> 
> > Visit this group at http://groups.google.com/group/clojurescript.
> 
> 
> 
> --
> 
> Note that posts from new members are moderated - please be patient with your 
> first post.
> 
> ---
> 
> You received this message because you are subscribed to the Google Groups 
> "ClojureScript" group.
> 
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to clojurescript+unsubscr...@googlegroups.com.
> 
> 
> To post to this group, send email to clojurescript@googlegroups.com.
> 
> Visit this group at http://groups.google.com/group/clojurescript.

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.


Re: [ClojureScript] OM: What is the best way of introducing animation/effects during application state transition ?

2014-03-15 Thread Jack Schaedler
Hi David,

Thanks heaps for all of your tutorials and work on Om. I've got a nice little 
clojurescript app with full undo/redo working with Om thanks to your tutorials 
and blog posts, and my goal for today is to work on animations. 

As an alternative to the interval within IWillMount, has anyone successfully 
used the ReactCSSTransitionGroup 
(http://facebook.github.io/react/docs/animation.html) addon within Om? I'm a 
newcomer to both cljs and React, and I've unsuccessfully attempted to do 
something like:

(def css-trans-group (-> js/React (aget "addons") (aget "CSSTransitionGroup"))) 

(defn my-component [app owner]
  (reify
om/IRender
(render [this]
  (css-trans-group #js {:transitionName "example"}
  (apply dom/div nil
(om/build-all palette-entry-component palette))

Is this sort of approach reasonable within Om? Sorry in advance for the 
probably silly question!

-jack



On Saturday, March 8, 2014 3:08:52 AM UTC+1, David Nolen wrote:
> I would probably do this by hooking into IWillUpdate. Generally whatever 
> solution makes sense for React will make sense for Om.
> 
> 
> David
> 
> 
> 
> 
> On Fri, Mar 7, 2014 at 8:35 PM,   wrote:
> 
> Hi Everyone,
> 
> 
> 
> I have an application state
> 
> 
> 
> (def app-state (atom {:index 0 :some-list [1 2 3 4]}))
> 
> 
> 
> When next button is clicked, index is incremented and the corresponding item 
> from the :some-list is displayed. Now I want to introduce an animation/effect 
> during the transition from one item to another. How should I go about it in 
> Om ?
> 
> 
> 
> 
> regards
> 
> 
> 
> --
> 
> Note that posts from new members are moderated - please be patient with your 
> first post.
> 
> ---
> 
> You received this message because you are subscribed to the Google Groups 
> "ClojureScript" group.
> 
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to clojurescrip...@googlegroups.com.
> 
> To post to this group, send email to clojur...@googlegroups.com.
> 
> Visit this group at http://groups.google.com/group/clojurescript.

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.