使用Clojurescript创建动画Om

问题描述:

我一直在寻找如何在Om中创建动画,我尝试了创建一个RaphaelJs组件,并取得了中等成功。我得到了我想要的动画,但由于某些原因,Om渲染了SVG元素的多个实例。使用Clojurescript创建动画Om

enter image description here

望着animation example in the Om github folder使用setInterval改变要进行动画处理,这是不太理想的值。

我知道CSSTransitionGroup插件,但它看起来像只能在CSS中定义的预设动画之间进行切换,您不能决定做一些事情,比如渲染一条路径,并随随随机时序。请随时纠正我,如果你可以使用它动态定义动画。

有没有人有任何执行简单动画的好例子?只需翻译或旋转简单的形状就能让我知道如何从那里开始解决问题。

+1

我刚刚发布了一个用于创建动画Om组件的库,但我使用setTimeout来更改这些值。我还没有调查过使用CSSTransitionGroup或其他动画方式。我会在未来几周内做o,看看我可以扩展我的图书馆以包括那些。 https://github.com/danielytics/ominate – Dan

+0

@丹,你想添加它作为答案吗? :)... – toofarsideways

+0

当然 - 我很快就会再看看这个。我已经尝试过使用CSSTransitionGroups,虽然他们的动画对我来说非常不好。我没有时间真正研究它,并在一个大的代码库中测试它,所以我想它的东西很容易修复。当我查看它时,我会发布一个答案。我打算把它作为一个dom/transition-group元素提交给om-tools,不管怎样, – Dan

您可以使用CSSTransitionGroup为位置/移动,方向和其他视觉属性(如不透明度,颜色,边框或阴影)(可能使用keyframes)或更多complex hacks设置动画。这种方法的主要限制是它只允许你动画组件的挂载和卸载,然后只能通过CSS中定义的动画。

如果您需要在组件使用寿命期间为组件生成动画,或者您希望对可以动画的内容进行更细致的控制,则可能需要采取另一种方法like what I do in this code

这就是你如何使用Om的CSSTransitionGroup。

要使用此功能,您需要使用React的with-addons版本(例如react-with-addons-0.12.1.jsreact-with-addons-0.12.1.min.js)。

(def css-trans-group (-> js/React (aget "addons") (aget "CSSTransitionGroup"))) 
(defn transition-group 
    [opts component] 
    (let [[group-name enter? leave?] (if (map? opts) 
            [(:name opts) (:enter opts) (:leave opts)] 
            [opts true true])] 
    (apply 
     css-trans-group 
     #js {:transitionName group-name 
      :transitionEnter enter? 
      :transitionLeave leave?} 
     component))) 

然后使用它,你可以这样做:

(transition-group "example" (when visible? (om/build my-component data))) 

现在切换visible?动画my-component安装和卸载。如果要禁用无论是进入或离开动画:

(transition-group 
    {:name "example" 
    :enter false} ; Only animate when component gets unmounted, not when mounted 
    (when visible? (om/build my-component data))) 

您也可以动画添加或移除/项的列表:

(transition-group "example" (om/build-all my-component list-of-data)) 

或者使用的地图,也许是这样的:

(transition-group "example" (map #(dom/li %) list-of-data)) 

您还需要添加正确的CSS:

.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; 
} 

请注意,除非您禁用其中一个动画,否则您需要将两者都包含在CSS中。例如,如果您忽略了leave动画,则您的组件可能无法卸载,因为React将挂起等待动画完成。简单的解决方法是使用{:leave false}将其禁用,或者将离开动画包含在CSS中。

另一个需要注意的问题:这个will only animate child components if the transition group is mounted before the children。如果孩子和过渡小组同时安装,那么他们将不会动画。有时这可能有点尴尬。例如,如果没有切换,上述代码片段不会生成动画,则该子代将与转换组同时安装。另外,如果list-of-data未预先填充,而是在安装后填充,则下面的build-all示例效果最佳。因此,CSSTransitionGroups最适用于在用户修改的视图/组件或数据列表之间切换的代码,但不适用于在页面加载时动画化组件的初始显示。

也许是这样的:

(transition-group "view-selection" 
    (condp = current-view 
    "home" (om/build home-page data) 
    "blog" (om/build blog-page data) 
    "about" (om/build about-page data) 
    :else (om/build error-404-page data))) 

-

最后,如果你不希望使用一个辅助功能,可以直接使用css-trans-group

(css-trans-group 
     #js {:transitionName "example"} 
     (when visible? (om/build my-component data))))) 

或者,如果使用子组件列表(例如,通过mapbuild-all):

(apply 
     css-trans-group 
     #js {:transitionName "example"} 
     (om/build-all my-component list-of-data)))) 

我还没有使用low-level TransitionGroup API。有关更多信息,请参见React CSSTransitionGroup page

小心查看https://github.com/chenglou/react-tween-statehttps://github.com/chenglou/react-state-stream的ClojureScript端口?

TransitionGroup只提供了一些帮助器来挂钩某些生命周期事件。它理论上与动画无关。如果你想要一个实际的动画API,看看我上面做的两件事情。自述文件应为其余部分提供足够的信息。