Update animation for onboarding carousel. (#16294)
* Update animation for onboarding carousel. * Fixed issues with long press while swipe. * Fixed issues after generating keys.
This commit is contained in:
parent
e0e693791f
commit
6b0a51720e
|
@ -1,6 +1,8 @@
|
|||
import { useDerivedValue, withTiming, Easing } from 'react-native-reanimated';
|
||||
|
||||
const slideAnimationDuration = 300;
|
||||
const totalPages = 4;
|
||||
const pageSize = 100 / totalPages;
|
||||
|
||||
const easeOut = {
|
||||
duration: slideAnimationDuration,
|
||||
|
@ -15,29 +17,15 @@ export function dynamicProgressBarWidth(staticProgressBarWidth, progress) {
|
|||
});
|
||||
}
|
||||
|
||||
export function carouselLeftPosition(windowWidth, progress) {
|
||||
export function carouselLeftPosition(windowWidth, progress, isDragging, dragAmount) {
|
||||
return useDerivedValue(function () {
|
||||
'worklet';
|
||||
const progressValue = progress.value;
|
||||
switch (true) {
|
||||
case progressValue < 25:
|
||||
return 0;
|
||||
case progressValue === 25:
|
||||
return withTiming(-windowWidth, easeOut);
|
||||
case progressValue < 50:
|
||||
return -windowWidth;
|
||||
case progressValue === 50:
|
||||
return withTiming(-2 * windowWidth, easeOut);
|
||||
case progressValue < 75:
|
||||
return -2 * windowWidth;
|
||||
case progressValue === 75:
|
||||
return withTiming(-3 * windowWidth, easeOut);
|
||||
case progressValue < 100:
|
||||
return -3 * windowWidth;
|
||||
case progressValue === 100:
|
||||
return withTiming(-4 * windowWidth, easeOut);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
const dragAmountValue = dragAmount.value;
|
||||
|
||||
const baseOffset = (Math.floor(progressValue / pageSize) % totalPages) * windowWidth;
|
||||
const adjustedOffset = baseOffset === 0 && dragAmountValue > 0 ? baseOffset : -baseOffset + dragAmountValue;
|
||||
|
||||
return isDragging.value ? withTiming(adjustedOffset, easeOut) : withTiming(-baseOffset, easeOut);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
(defn gesture-pan [] (.Pan ^js Gesture))
|
||||
|
||||
(defn gesture-long-press [] (.LongPress ^js Gesture))
|
||||
|
||||
(defn gesture-pinch [] (.Pinch ^js Gesture))
|
||||
|
||||
(defn on-begin [gesture handler] (.onBegin ^js gesture handler))
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
(defonce progress (atom nil))
|
||||
(defonce paused? (atom nil))
|
||||
(defonce is-dragging? (atom nil))
|
||||
(defonce drag-amount (atom nil))
|
||||
|
||||
(defn store-screen-height
|
||||
[evt]
|
||||
|
@ -60,7 +62,7 @@
|
|||
animate? (not dark-overlay?)
|
||||
window-width (rf/sub [:dimensions/window-width])]
|
||||
(when animate?
|
||||
(carousel.animation/use-initialize-animation progress paused? animate?))
|
||||
(carousel.animation/use-initialize-animation progress paused? animate? is-dragging? drag-amount))
|
||||
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
|
@ -78,6 +80,8 @@
|
|||
:progress progress
|
||||
:paused? paused?
|
||||
:header-text header-text
|
||||
:is-dragging? is-dragging?
|
||||
:drag-amount drag-amount
|
||||
:header-background true
|
||||
:gesture :swipeable
|
||||
:background [background-image (* 4 window-width)]}]
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
(if (zero? value) (slide-animation value 0) (slide-animation value)))
|
||||
|
||||
(defn animate-progress
|
||||
[progress paused next-progress]
|
||||
[progress paused? next-progress]
|
||||
(let [q (quot next-progress 25)]
|
||||
(reanimated/set-shared-value
|
||||
progress
|
||||
|
@ -53,7 +53,7 @@
|
|||
(animate-progress-value (animation-value q 4))
|
||||
(animate-progress-value (calculate-remainder next-progress drag-limit)))
|
||||
-1)
|
||||
paused))))
|
||||
paused?))))
|
||||
|
||||
(defn get-next-progress
|
||||
[progress]
|
||||
|
@ -74,37 +74,74 @@
|
|||
(* progress-threshold)))))
|
||||
|
||||
(defn use-initialize-animation
|
||||
[progress paused animate?]
|
||||
[progress paused? animate? is-dragging? drag-amount]
|
||||
(reset! progress (reanimated/use-shared-value 0))
|
||||
(reset! paused (reanimated/use-shared-value false))
|
||||
(reset! paused? (reanimated/use-shared-value false))
|
||||
(reset! is-dragging? (reanimated/use-shared-value false))
|
||||
(reset! drag-amount (reanimated/use-shared-value 0))
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(animate-progress @progress @paused 0))
|
||||
(animate-progress @progress @paused? 0))
|
||||
[animate?]))
|
||||
|
||||
(defn cleanup-animation
|
||||
[progress paused]
|
||||
[progress paused?]
|
||||
(fn []
|
||||
(reanimated/cancel-animation @progress)
|
||||
(reanimated/cancel-animation @paused)))
|
||||
(reanimated/cancel-animation @paused?)))
|
||||
|
||||
(defn update-progress
|
||||
[progress paused new-progress]
|
||||
[progress paused? new-progress]
|
||||
(reanimated/set-shared-value @progress new-progress)
|
||||
(animate-progress @progress @paused new-progress))
|
||||
(animate-progress @progress @paused? new-progress))
|
||||
|
||||
(defn handle-drag
|
||||
[event paused? is-dragging? drag-amount]
|
||||
(let [translation-x (oops/oget event "translationX")]
|
||||
(reanimated/set-shared-value @paused? true)
|
||||
(reanimated/set-shared-value @is-dragging? true)
|
||||
(reanimated/set-shared-value @drag-amount translation-x)))
|
||||
|
||||
(defn drag-gesture
|
||||
[progress paused]
|
||||
[progress paused? is-dragging? drag-amount]
|
||||
(-> (gesture/gesture-pan)
|
||||
(gesture/max-pointers 1)
|
||||
(gesture/on-start
|
||||
(fn [event]
|
||||
(handle-drag event paused? is-dragging? drag-amount)))
|
||||
(gesture/on-update
|
||||
(fn [event]
|
||||
(handle-drag event paused? is-dragging? drag-amount)))
|
||||
(gesture/on-end
|
||||
(fn []
|
||||
(reanimated/set-shared-value @is-dragging? false)
|
||||
(reanimated/set-shared-value @paused? false)))
|
||||
(gesture/on-finalize
|
||||
(fn [event]
|
||||
(let [next? (< (oops/oget event "translationX") (- drag-limit))
|
||||
previous? (> (oops/oget event "translationX") drag-limit)]
|
||||
(when next?
|
||||
(update-progress progress paused (get-next-progress progress)))
|
||||
(update-progress progress paused? (get-next-progress progress)))
|
||||
(when previous?
|
||||
(update-progress progress paused (get-previous-progress progress))))))))
|
||||
(update-progress progress paused? (get-previous-progress progress))))))))
|
||||
|
||||
(defn long-press-gesture
|
||||
[paused?]
|
||||
(->
|
||||
(gesture/gesture-long-press)
|
||||
(gesture/enabled true)
|
||||
(gesture/on-start
|
||||
(fn []
|
||||
(reanimated/set-shared-value @paused? true)))
|
||||
(gesture/on-finalize
|
||||
(fn []
|
||||
(reanimated/set-shared-value @paused? false)))))
|
||||
|
||||
(defn composed-gestures
|
||||
[progress paused? is-dragging? drag-amount]
|
||||
(let [long-press (long-press-gesture paused?)
|
||||
drag (drag-gesture progress paused? is-dragging? drag-amount)]
|
||||
(gesture/simultaneous long-press drag)))
|
||||
|
||||
(defn tap-gesture
|
||||
[progress paused]
|
||||
|
@ -112,9 +149,12 @@
|
|||
(gesture/on-end #(update-progress progress paused (get-next-progress progress)))))
|
||||
|
||||
(defn carousel-left-position
|
||||
[window-width animate? progress]
|
||||
[window-width animate? progress is-dragging? drag-amount]
|
||||
(if animate?
|
||||
(worklets.onboarding-carousel/carousel-left-position window-width @progress)
|
||||
(worklets.onboarding-carousel/carousel-left-position window-width
|
||||
@progress
|
||||
@is-dragging?
|
||||
@drag-amount)
|
||||
(-> (or (reanimated/get-shared-value @progress) 0)
|
||||
(quot -25)
|
||||
(* window-width))))
|
||||
|
|
|
@ -50,16 +50,19 @@
|
|||
:progress-bar-width progress-bar-width}]]))
|
||||
|
||||
(defn f-view
|
||||
[{:keys [animate? progress paused? header-text background header-background gesture]}]
|
||||
(let [window-width (rf/sub [:dimensions/window-width])
|
||||
status-bar-height (:status-bar-height @navigation/constants)
|
||||
[{:keys [animate? progress paused? header-text background header-background gesture is-dragging?
|
||||
drag-amount]}]
|
||||
(let [window-width (rf/sub [:dimensions/window-width])
|
||||
status-bar-height (:status-bar-height @navigation/constants)
|
||||
progress-bar-width (- window-width 40)
|
||||
carousel-left (animation/carousel-left-position window-width animate? progress)
|
||||
container-view (if animate? reanimated/view rn/view)
|
||||
identified-gesture (case gesture
|
||||
:swipeable (animation/drag-gesture progress paused?)
|
||||
:tappable (animation/tap-gesture progress paused?)
|
||||
nil)]
|
||||
carousel-left
|
||||
(animation/carousel-left-position window-width animate? progress is-dragging? drag-amount)
|
||||
container-view (if animate? reanimated/view rn/view)
|
||||
identified-gesture
|
||||
(case gesture
|
||||
:swipeable (animation/composed-gestures progress paused? is-dragging? drag-amount)
|
||||
:tappable (animation/tap-gesture progress paused?)
|
||||
nil)]
|
||||
[:<>
|
||||
[gesture/gesture-detector {:gesture identified-gesture}
|
||||
[container-view {:style (style/carousel-container carousel-left animate?)}
|
||||
|
|
|
@ -25,12 +25,14 @@
|
|||
[]
|
||||
(let [progress (atom nil)
|
||||
paused? (atom nil)
|
||||
is-dragging? (atom nil)
|
||||
drag-amount (atom nil)
|
||||
{:keys [emoji-hash display-name compressed-key
|
||||
public-key]} (rf/sub [:multiaccount])
|
||||
{:keys [color]} (rf/sub [:onboarding-2/profile])
|
||||
photo-path (rf/sub [:chats/photo-path public-key])
|
||||
emoji-string (string/join emoji-hash)]
|
||||
(carousel.animation/use-initialize-animation progress paused? true)
|
||||
(carousel.animation/use-initialize-animation progress paused? true is-dragging? drag-amount)
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(carousel.animation/cleanup-animation progress paused?))
|
||||
|
@ -39,11 +41,13 @@
|
|||
[background/view true]
|
||||
[rn/view {:style style/page-container}
|
||||
[carousel/view
|
||||
{:animate? true
|
||||
:progress progress
|
||||
:paused? paused?
|
||||
:gesture :tappable
|
||||
:header-text header-text}]
|
||||
{:animate? true
|
||||
:progress progress
|
||||
:paused? paused?
|
||||
:gesture :tappable
|
||||
:is-dragging? is-dragging?
|
||||
:drag-amount drag-amount
|
||||
:header-text header-text}]
|
||||
[rn/view {:style style/content-container}
|
||||
[profile-card/profile-card
|
||||
{:profile-picture photo-path
|
||||
|
|
|
@ -7,5 +7,5 @@
|
|||
(.dynamicProgressBarWidth ^js worklets static-progress-bar-width progress))
|
||||
|
||||
(defn carousel-left-position
|
||||
[window-width progress]
|
||||
(.carouselLeftPosition ^js worklets window-width progress))
|
||||
[window-width progress is-dragging? drag-amount]
|
||||
(.carouselLeftPosition ^js worklets window-width progress is-dragging? drag-amount))
|
||||
|
|
Loading…
Reference in New Issue