How does one add an animation upon an element entering the dom? like the
ReactCSSTransitionGroup
in react?Why not just use ReactCSSTransitionGroup
then? Or you can simply call setTimeout in some hooks to add a new class to the component node (obtained from useRef) and define transitions rules on the new class
framer motion is easy to use and very powerful
(ns app.motion
(:require
[framer-motion :refer (motion MagicMotion AnimateSharedLayout AnimatePresence useSpring useMotionValue useTransform useViewportScroll) :as motion]
[cljs-bean.core :refer [bean ->clj ->js]]))
(def div
(.-div motion))
(def span
(.-span motion))
(def li
(.-li motion))
(def img
(.-img motion))
(def button
(.-button motion))
(def input
(.-input motion))
(def textarea
(.-textarea motion))
(def label
(.-label motion))
(def transform #(motion/transform (->js %1) (->js %2) (->js %3)))
(def animate-presence AnimatePresence)
(defn my-component
[]
[:> motion/animate-presence
[:> motion/div
{:key :my-component
:class [:my-component (<class styles/my-component)]
:variants {:initial {:opacity 0}
:animate {:opacity 1}
:exit {:opacity 0}}
:initial :initial
:animate :animate
:exit :exit}
"My component"]])
You could do some amazing animations with it
@ouvasam that gives me
--------------------------------------------------------------------------------
12 | [:> motion/animate-presence
13 | [:> motion/div
14 | {:key :my-component
15 | :class [:my-component (<class styles/my-component)]
-------------------------------------^------------------------------------------
Use of undeclared Var vendo.cart/<class
--------------------------------------------------------------------------------
16 | :variants {:initial {:opacity 0}
17 | :animate {:opacity 1}
18 | :exit {:opacity 0}}
19 | :initial :initial
-----------------------------------------------------------------------
Yes you can remove (<class ...)
It is roosta/herb
I have the following now:
[:> motion/animate-presence
[:> motion/div
{:key :my-component
:class [:my-component]
:variants {:initial {:opacity 0}
:animate {:opacity 1}
:exit {:opacity 0}}
:initial :initial
:animate :animate
:exit :exit}
"My component"]]
And that gives in the console:
react-dom.development.js:24037 Uncaught Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of
vendo.cart.cart`.`
at createFiberFromTypeAndProps (<http://localhost:3000/js/cljs-runtime/module$node_modules$react_dom$cjs$react_dom_development.js:504:389>)
at createFiberFromElement (<http://localhost:3000/js/cljs-runtime/module$node_modules$react_dom$cjs$react_dom_development.js:505:255>)
at eval (<http://localhost:3000/js/cljs-runtime/module$node_modules$react_dom$cjs$react_dom_development.js:197:268>)
at reconcileChildren (<http://localhost:3000/js/cljs-runtime/module$node_modules$react_dom$cjs$react_dom_development.js:244:90>)
at finishClassComponent (<http://localhost:3000/js/cljs-runtime/module$node_modules$react_dom$cjs$react_dom_development.js:269:433>)
at updateClassComponent (<http://localhost:3000/js/cljs-runtime/module$node_modules$react_dom$cjs$react_dom_development.js:267:61>)
at beginWork$1 (<http://localhost:3000/js/cljs-runtime/module$node_modules$react_dom$cjs$react_dom_development.js:312:88>)
at HTMLUnknownElement.callCallback (<http://localhost:3000/js/cljs-runtime/module$node_modules$react_dom$cjs$react_dom_development.js:527:204>)
at Object.invokeGuardedCallbackImpl (<http://localhost:3000/js/cljs-runtime/module$node_modules$react_dom$cjs$react_dom_development.js:529:430>)
at invokeGuardedCallback (<http://localhost:3000/js/cljs-runtime/module$node_modules$react_dom$cjs$react_dom_development.js:5:463>)
why would that be?
would you please share a self-contained, working example?
Do you use shadow-cljs ?
This should work with it If you use it i'll send a self-contained example
yeah I do
Yeah, for some reason, the :>div doesn't mount when I click the button, but only when I focus/refocus on the browser or click somewhere on the page.
here's the code:
(def div (.-div motion))
[:> div
{
:initial {:opacity 0}
:animate {:opacity 1}
:exit {:opacity 0}}
[:div "Show Me"]]
also, wrapping the :>div with :>animate-presence (similarly defined), didn't change there result
Hi @pshar10 sorry i was off
Here a sample of code that works and show how to. use animate-presence
(defn my-comp
[]
(r/with-let
[clicked (r/atom false)]
[:<>
[:div {:on-click #(swap! clicked not)}
"click me"]
[:> motion/animate-presence
(if @clicked
[:> motion/div
{:key :my-comp
:class [:my-comp]
:variants {:initial {:opacity 0
:y 100
:x 0
:scale 1}
:animate {:opacity 1
:y 0
:scale 1}
:exit {:opacity 0
:x 100
:scale 0.2}}
:initial :initial
:animate :animate
:exit :exit}
"my-comp"])]]))
The key part is important and should be. different for each componentthat use motion
Here is the same example without if and with a different key based on an atom
(defn my-comp
[]
(r/with-let
[clicked (r/atom false)]
[:<>
[:div {:on-click #(swap! clicked not)}
"click me"]
[:> motion/animate-presence
[:> motion/div
{:key (str :my-comp @clicked)
:class [:my-comp]
:variants {:initial {:opacity 0
:y 100
:x 0
:scale 1}
:animate {:opacity 1
:y 0
:scale 1}
:exit {:opacity 0
:x 100
:scale 0.2}}
:initial :initial
:animate :animate
:exit :exit}
(str "my-comp" @clicked)]]]))
r/with-let is reagent/with-let