Создание анимации с Clojurescript Om
Я искал, как создавать анимации в Om, я пытался создать компонент RaphaelJs с умеренным успехом. Я получаю нужную анимацию, но по какой-то причине Om отображает несколько экземпляров элемента SVG.
Глядя на пример анимации в папке Om Github использует setInterval
изменить значения, которые вы хотите анимировать, что не идеально.
Мне известно о надстройке CSSTransitionGroup, но похоже, что вы можете переключаться только между предустановленными анимациями, определенными в CSS, вы не можете решить сделать что-то вроде рендеринга пути и следования по нему фигуре со случайными временными интервалами. Пожалуйста, не стесняйтесь исправлять меня, если вы можете динамически определять анимацию, используя ее.
У кого-нибудь есть хорошие примеры выполнения простых анимаций? Просто перевод или вращение простых фигур дало бы мне представление о том, как начать решать это оттуда.
2 ответа
Вы можете использовать CSSTransitionGroup для анимации положения / движения, ориентации и других визуальных свойств, таких как непрозрачность, цвет, границы или тени (возможно, с использованием ключевых кадров) или более сложных хаков. Основным ограничением этого подхода является то, что он позволяет анимировать только монтирование и демонтирование компонентов, а затем только с помощью анимации, определенной в CSS.
Если вам нужно анимировать компоненты во время их монтируемого времени жизни или вы хотите более детально контролировать то, что вы можете анимировать, вы можете использовать другой подход, подобный тому, что я делаю в этом коде.
Вот как бы вы использовали CSSTransitionGroup от Om.
Чтобы это работало, вам нужно использовать 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.
Еще один момент, о котором следует помнить: это будет анимировать дочерние компоненты, только если группа перехода смонтирована раньше дочерних. Если дочерние элементы и переходная группа смонтированы одновременно, они не будут анимированы. Это может быть немного неловко иногда. Например, приведенные выше фрагменты кода не будут анимированы без (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))))
Я еще не использовал API TransitionGroup низкого уровня. Дополнительную информацию можно найти на странице React CSSTransitionGroup.
Хотите заглянуть в порт ClojureScript по https://github.com/chenglou/react-tween-state или https://github.com/chenglou/react-state-stream?
TransitionGroup предоставляет только помощников для подключения к некоторым событиям жизненного цикла. Это теоретически не имеет ничего общего с анимацией. Если вам нужен настоящий API анимации, взгляните на две вещи, которые я сделал выше. Readmes должен предоставить достаточно информации для отдыха.