我一直在寻找如何在Om中创建动画,我尝试创建一个成功的RaphaelJs组件。我得到了我想要的动画,但由于某种原因,Om渲染了SVG元素的多个实例。
查看animation example in the Om github folder使用setInterval
来更改要设置动画的值,这不太理想。
我知道CSSTransitionGroup插件,但看起来你只能在CSS中定义的预设动画之间切换,你不能决定做一些像渲染路径和跟随随机时序的形状。如果您可以使用它动态定义动画,请随时纠正我。
有没有人有任何表现简单动画的好例子?只需翻译或旋转简单的形状,我就可以了解如何从那里开始处理它。
答案 0 :(得分:12)
您可以使用CSSTransitionGroup为位置/移动,方向和其他视觉属性(如不透明度,颜色,边框或阴影(可能使用keyframes)或更多complex hacks设置动画。这种方法的主要限制是它只允许您设置组件的安装和卸载动画,然后只允许通过CSS中定义的动画。
如果您需要在装载生命周期内为组件制作动画,或者您希望对可以制作动画的内容进行更精细的控制,则可能需要采用另一种方法like what I do in this code。
这就是你如何使用Om的CSSTransitionGroup。
为此,您需要使用with-addons
版本的React(例如react-with-addons-0.12.1.js
或react-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。如果孩子和过渡组同时安装,那么它们将不会被动画化。有时这可能有点尴尬。例如,如果没有切换,上面的代码片段将不会在没有(when visible? ...)
的情况下进行动画处理,子项将与转换组同时挂载。此外,如果build-all
未预先填充,而是在安装后填充,则下面的list-of-data
示例效果最佳。因此,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)))))
或者,如果使用子组件列表(例如通过map
或build-all
):
(apply
css-trans-group
#js {:transitionName "example"}
(om/build-all my-component list-of-data))))
我还没有使用low-level TransitionGroup API。可以在React CSSTransitionGroup page上找到更多信息。
答案 1 :(得分:2)
注意查看https://github.com/chenglou/react-tween-state或https://github.com/chenglou/react-state-stream的ClojureScript端口?
TransitionGroup只提供帮助程序来挂钩一些生命周期事件。它理论上与动画无关。如果你想要一个真正的动画API,看看我上面做的两件事。自述文件应该为其余部分提供足够的信息。