cljsrn

https://github.com/drapanjanas/re-natal | https://github.com/drapanjanas/re-natal/wiki/FAQ | https://github.com/condense/mercury-app/wiki | https://github.com/seantempesta/expo-cljs-template/ https://www.npmjs.com/package/create-expo-cljs-app
raspasov 2021-01-04T18:39:55.265500Z

Has anybody been able to successfully use Reanimated V2 from ClojureScript?

raspasov 2021-01-04T18:41:05.266700Z

I managed to use it, but via a workaround: create a local NPM module and write the code in JavaScript… (so not really using it from Cljs, but :require-ing JS files that use it from Cljs works)

lepistane 2021-01-04T21:29:20.267500Z

no sorry but i am interested in what u did cause i will need to get my hands dirty in reanimated soon

ferossgp 2021-01-05T12:10:19.268800Z

The problem is that the plugin matches by function name https://github.com/software-mansion/react-native-reanimated/blob/master/plugin.js#L492 and in cljs the function is assigned to a different var and the plugin does not match it.

var a = useAnimatedStyle;
a(function () {})
This is the first problem. It could be fixed if all closures are explicitly marked as worklets with directive. The second one, is that most of the cljs->rn building tools does not make use of metro which uses babel for code transformations, but pass the code over a websocket connection. Because of that during the live reload the code is not transformed. Just for fun I've tried monky patch the clojurescript emit function, to go through babel so shadow could pick already transformed code, but this approach is not usable as I was using babel-cli via shell, babel is js and cljs compiler is java. Maybe a hybrid approach for live reloading could be used to just write js files and let metro pick them. While leverage the ws for repl

ferossgp 2021-01-05T14:30:05.269200Z

Btw, if you are interested in a simple example, this works, so theoretically one could write a macro to handle all all cases:

(:require ["react-native-reanimated" :refer [useSharedValue Easings withTiming useAnimatedStyle] :default animated])

(defn hooks []
  (let [width      ^js (useSharedValue 10)
        anim-style (fn anim-style []
                     #js {:width           (withTiming (.-value width) #js {:duration 500})
                          :height          80
                          :backgroundColor "black"
                          :margin          30})
        _          (gobj/set anim-style "_closure" #js {:width width})
        style      (useAnimatedStyle anim-style)]
    (r/as-element
     [:> (.-View animated) {:style style}
      [:> rn/TouchableOpacity {:style    {:flex 1}
                               :on-press (fn []
                                           (gobj/set width "value" (* (.random js/Math) 350)))}]])))

raspasov 2021-01-06T01:25:25.269600Z

@ferossgp very cool; so you made it work with this example? What’s the key here that makes it work? Is it this line here?

(gobj/set anim-style "_closure" #js {:width width})

raspasov 2021-01-06T04:59:01.269800Z

Hmm, I still get this error; the view renders (I can close the screen, but the animation does not run when I tap the view): Tried to synchronously call function from a different thread.

raspasov 2021-01-06T04:59:48.270200Z

I have this macro:

(defmacro js-directive
  [directive]
  (list 'js* (str "'" directive "'")))

raspasov 2021-01-06T05:00:07.270400Z

So I can emit ‘worklet’;

raspasov 2021-01-06T05:00:10.270600Z

(macro/js-directive "worklet")

raspasov 2021-01-06T05:01:04.270800Z

But still doesn’t work; it’s definitely something weird with the way this library works with those transforms; it’s not super critical, since I made it work from JavaScript but it would be nice to work from CLJS as well 🙂 .

ferossgp 2021-01-11T08:08:37.273100Z

Oh right, sorry for the delusion, I was using react-native-web and seems like on web it uses the same thread always

raspasov 2021-01-12T04:53:53.273300Z

@ferossgp no problem, thank you for the clarification

raspasov 2021-01-04T21:56:18.267600Z

1. I created a new local npm library via “yarn init” https://classic.yarnpkg.com/en/docs/cli/init/ 2. Included the library in package.json like this: “box”: “./npm-local/box”, 3. Write a basic React view that uses Reanimated v2 https://gist.github.com/raspasov/bc7e717adccee0ba5ad60cdea41d66d6 4. Use the local library called “box” from ClojureScript (:require [box :as box])

raspasov 2021-01-04T21:58:17.268Z

I’m guessing the problem that Cljs has with Reanimated V2 is the fact Reanimated V2 relies on this line in babel.config.js … plugins: [‘react-native-reanimated/plugin’],…

raspasov 2021-01-04T22:00:14.268200Z

My guess is that this plugin somehow preprocesses the JS code to make it work with the hooks like “useAnimatedStyle” which make reanimated v2 really easy to use; My guess is that the transpiled JS code coming out of ClojureScript is not subject to that transformation, and that’s why it doesn’t work