Skip to content

Commit

Permalink
Implement React Native Reanimated V2
Browse files Browse the repository at this point in the history
  • Loading branch information
Parveshdhull committed Jun 19, 2022
1 parent 62a3ed6 commit 87f6095
Show file tree
Hide file tree
Showing 6 changed files with 355 additions and 32 deletions.
3 changes: 3 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"presets": [
"module:metro-react-native-babel-preset"
],
"plugins": [
"react-native-reanimated/plugin"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
import im.status.ethereum.pushnotifications.PushNotificationPackage;
import im.status.ethereum.StatusOkHttpClientFactory;

import com.facebook.react.bridge.JSIModulePackage;
import com.swmansion.reanimated.ReanimatedJSIModulePackage;

public class MainApplication extends NavigationApplication {

private final ReactNativeHost mReactNativeHost = new NavigationReactNativeHost(this) {
Expand All @@ -48,6 +51,11 @@ protected List<ReactPackage> getPackages() {
protected String getJSMainModuleName() {
return "index";
}

@Override
protected JSIModulePackage getJSIModulePackage() {
return new ReanimatedJSIModulePackage();
}
};

@Override
Expand Down
32 changes: 32 additions & 0 deletions js/worklet_factory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { withTiming, withDelay } from 'react-native-reanimated';

// Worklets

export function applyAnimationsToStyle(animations, style) {
return function() {
'worklet'

var animatedStyle = {}

for (var key in animations) {
if (key == "transform") {
var transforms = animations[key];
var animatedTransforms = []

for (var transform of transforms) {
var transformKey = Object.keys(transform)[0];
animatedTransforms.push({
[transformKey]: transform[transformKey].value
})
}

animatedStyle[key] = animatedTransforms;
} else {
animatedStyle[key] = animations[key].value;
}
}

return Object.assign(animatedStyle, style);
};
};

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"app:android": "react-native run-android"
},
"dependencies": {
"@babel/preset-typescript": "^7.17.12",
"@react-native-community/async-storage": "^1.11.0",
"@react-native-community/audio-toolkit": "git+https://github.com/tbenr/react-native-audio-toolkit.git#refs/tags/v2.0.3-status-v6",
"@react-native-community/blur": "^3.6.0",
Expand Down Expand Up @@ -60,7 +61,7 @@
"react-native-navigation": "^7.27.1",
"react-native-permissions": "^2.1.5",
"react-native-randombytes": "^3.6.1",
"react-native-reanimated": "^2.1.0",
"react-native-reanimated": "2.3.3",
"react-native-redash": "^16.0.11",
"react-native-safe-area-context": "^2.0.0",
"react-native-shake": "^3.3.1",
Expand All @@ -75,12 +76,12 @@
"web3-utils": "^1.2.1"
},
"devDependencies": {
"@mapbox/node-pre-gyp": "^1.0.9",
"@babel/generator": "7.0.0",
"@babel/helper-builder-react-jsx": "7.0.0",
"@babel/plugin-transform-block-scoping": "7.0.0",
"@babel/preset-env": "7.1.0",
"@babel/register": "7.0.0",
"@mapbox/node-pre-gyp": "^1.0.9",
"clj-kondo": "^2020.1.13",
"coveralls": "^3.0.4",
"jest": "^25.1.0",
Expand Down
66 changes: 66 additions & 0 deletions src/quo2/reanimated.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
(ns quo2.reanimated
(:require ["react-native" :as rn]
[reagent.core :as reagent]
[clojure.string :as string]
["react-native-reanimated" :default reanimated
:refer (enableLayoutAnimations useSharedValue useAnimatedStyle withTiming Easing Keyframe)]))

;; We can Remove manually enabling layout animations,
;; once react-native-reanimated is updated to 2.5.0
(defonce enable-layout-animation (enableLayoutAnimations true))

;; Animated Components
(def create-animated-component (comp reagent/adapt-react-class (.-createAnimatedComponent reanimated)))

(def view (reagent/adapt-react-class (.-View reanimated)))
(def image (reagent/adapt-react-class (.-Image reanimated)))
(def touchable-opacity (create-animated-component (.-TouchableOpacity ^js rn)))

;; Hooks
(def use-shared-value useSharedValue)
(def use-animated-style useAnimatedStyle)

;; Animations
(def with-timing withTiming)
(def key-frame Keyframe)

;; Easings
(def bezier (.-bezier ^js Easing))

(def easings {:easing1 (bezier 0.25 0.1 0.25 1) ;; TODO - rename easing functions, (design team input)
:easing2 (bezier 0 0.3 0.6 0.9)})

;; Helper functions
(defn get-shared-value [anim]
(.-value anim))

(defn set-shared-value [anim val]
(set! (.-value anim) val))

(defn kebab-case->camelCase [k]
(let [words (string/split (name k) #"-")]
(->> (map string/capitalize (rest words))
(apply str (first words))
keyword)))

(defn map-keys [f m]
(->> (map (fn [[k v]] [(f k) v]) m)
(into {})))

;; Worklets
(def worklet-factory (js/require "../js/worklet_factory.js"))

;;;; Component Animations

;; kebab-case styles are not working for worklets
;; so first converting kebab case styles into camel case styles
(defn apply-animations-to-style [animations style]
(let [animations (map-keys kebab-case->camelCase animations)
style (apply dissoc (map-keys kebab-case->camelCase style) (keys animations))]
(use-animated-style
(.applyAnimationsToStyle ^js worklet-factory (clj->js animations) (clj->js style)))))

;; Animators
(defn animate-shared-value-with-timing [anim val duration easing]
(set-shared-value anim (with-timing val (clj->js {:duration duration
:easing (get easings easing)}))))
Loading

0 comments on commit 87f6095

Please sign in to comment.