Today I Learned

A Hashrocket project

Animate ReactNative in ClojureScript with Reagent

Reagent uses ratoms to refresh components. When the state of a ratom is changed, components that deref that state re-render. ReactNative Animation uses a similar technique: changes to an Animated.Value cause a re-render. I was afraid these concepts would collide, and I’d have to bypass Reagent using it’s low-level api to use animations. But much to my joyful surprise, Animated.Value changes trigger a re-render in normal Reagent components.

(ns my-app.animation
  (:require
    ["react-native" :as ReactNative]
    [reagent.core :as r]))

(def animated (.-Animated ReactNative))
(def text (r/adapt-react-class (.-Text ReactNative)))
(def animated-value (.-Value animated))
(def animated-view (r/adapt-react-class (.-View animated)))

(defn testview []
  (let [bounce-value (new animated-value 0)]
    (.setValue bounce-value 1.5)
    (-> bounce-value
        (animated.spring #js {:toValue 0.8 :friction 1})
        (.start))
    (fn [] [animated-view
            {:style {:flex 1
                     :transform [{:scale bounce-value}]
                     :background-color "red"
                     :border-radius 10
                     :shadow-color "#000000"
                     :shadow-opacity 0.7
                     :shadow-radius 2
                     :shadow-offset {:height 1 :width 0}}}
            [text "test"]])))

animation

This may look complex, but compare it to the low level Reagent api used in other examples.