Skip to content

Commit

Permalink
Implement onboarding slide animation
Browse files Browse the repository at this point in the history
  • Loading branch information
Parveshdhull committed Mar 27, 2023
1 parent ac27314 commit dad52ad
Show file tree
Hide file tree
Showing 29 changed files with 355 additions and 162 deletions.
Binary file removed resources/images/ui2/[email protected]
Binary file not shown.
Binary file removed resources/images/ui2/[email protected]
Binary file not shown.
Binary file removed resources/images/ui2/[email protected]
Binary file not shown.
Binary file removed resources/images/ui2/[email protected]
Binary file not shown.
Binary file removed resources/images/ui2/[email protected]
Binary file not shown.
Binary file removed resources/images/ui2/[email protected]
Binary file not shown.
Binary file removed resources/images/ui2/[email protected]
Binary file not shown.
Binary file removed resources/images/ui2/[email protected]
Binary file not shown.
Binary file removed resources/images/ui2/[email protected]
Binary file not shown.
Binary file removed resources/images/ui2/[email protected]
Binary file not shown.
Binary file removed resources/images/ui2/[email protected]
Binary file not shown.
Binary file added resources/images/ui2/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
60 changes: 60 additions & 0 deletions src/js/worklets/onboarding_carousel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { useDerivedValue, withTiming, Easing } from 'react-native-reanimated';

const slideAnimationDuration = 300;

const easeOut = {
duration: slideAnimationDuration,
easing: Easing.bezier(0, 0, 0.58, 1),
}

// Derived Values
export function dynamicProgressBarWidth (staticProgressBarWidth, progress) {
return useDerivedValue(
function () {
'worklet'
var progressValue = progress.value;
// Without this check, ios debug build is crashing
progressValue = isNaN(progressValue) ? 0 : progressValue;

return staticProgressBarWidth * progress.value / 100;
}
);
}

export function carouselLeftPosition (windowWidth, progress) {
return useDerivedValue(
function () {
'worklet'
var progressValue = progress.value;
switch (true) {
case (progressValue < 25):
return 0;
break;
case (progressValue == 25):
return withTiming(-windowWidth, easeOut);
break;
case (progressValue < 50):
return -windowWidth;
break;
case (progressValue == 50):
return withTiming(-2 * windowWidth, easeOut);
break;
case (progressValue < 75):
return -2 * windowWidth;
break;
case (progressValue == 75):
return withTiming(-3 * windowWidth, easeOut);
break;
case (progressValue < 100):
return -3 * windowWidth;
break;
case (progressValue == 100):
return withTiming(-4 * windowWidth, easeOut);
break;
default:
return 0;
break;
}
});
}

5 changes: 4 additions & 1 deletion src/react_native/reanimated.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
withDelay
withSpring
withRepeat
withSequence
withDecay
Easing
Keyframe
Expand All @@ -17,8 +18,8 @@
SlideOutUp
LinearTransition)]
[reagent.core :as reagent]
["react-native-redash" :refer (withPause)]
[react-native.flat-list :as rn-flat-list]
[utils.collection]
[utils.worklets.core :as worklets.core]))

(def ^:const default-duration 300)
Expand Down Expand Up @@ -59,6 +60,8 @@
(def with-decay withDecay)
(def key-frame Keyframe)
(def with-repeat withRepeat)
(def with-sequence withSequence)
(def with-pause withPause)
(def cancel-animation cancelAnimation)

;; Easings
Expand Down
23 changes: 9 additions & 14 deletions src/status_im2/common/resources.cljs
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
(ns status-im2.common.resources)

(def ui
{:add-new-contact (js/require "../resources/images/ui2/add-contact.png")
:intro-1 (js/require "../resources/images/ui2/intro-1.png")
:intro-2 (js/require "../resources/images/ui2/intro-2.png")
:intro-3 (js/require "../resources/images/ui2/intro-3.png")
:intro-4 (js/require "../resources/images/ui2/intro-4.png")
:lifestyle (js/require "../resources/images/ui2/lifestyle.png")
:music (js/require "../resources/images/ui2/music.png")
:podcasts (js/require "../resources/images/ui2/podcasts.png")
:sync-device (js/require "../resources/images/ui2/sync-new-device-cover-background.png")
:onboarding-bg-1 (js/require "../resources/images/ui2/onboarding-bg-1.png")
:onboarding-blur-bg (js/require "../resources/images/ui2/onboarding_blur_bg.png")
:generate-keys (js/require "../resources/images/ui2/generate_keys.png")
:ethereum-address (js/require "../resources/images/ui2/ethereum_address.png")
:use-keycard (js/require "../resources/images/ui2/keycard.png")})
{:add-new-contact (js/require "../resources/images/ui2/add-contact.png")
:lifestyle (js/require "../resources/images/ui2/lifestyle.png")
:music (js/require "../resources/images/ui2/music.png")
:podcasts (js/require "../resources/images/ui2/podcasts.png")
:sync-device (js/require "../resources/images/ui2/sync-new-device-cover-background.png")
:generate-keys (js/require "../resources/images/ui2/generate_keys.png")
:ethereum-address (js/require "../resources/images/ui2/ethereum_address.png")
:use-keycard (js/require "../resources/images/ui2/keycard.png")
:onboarding-illustration (js/require "../resources/images/ui2/onboarding_illustration.png")})

(def mock-images
{:coinbase (js/require "../resources/images/mock2/coinbase.png")
Expand Down
10 changes: 1 addition & 9 deletions src/status_im2/contexts/onboarding/common/background/style.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,12 @@
{:background-color colors/neutral-95
:flex-direction :row
:position :absolute
:overflow :hidden
:top 0
:bottom 0
:left 0
:right 0})

(defn background-gradient-overlay
[dark-overlay?]
{:position :absolute
:height (if dark-overlay? 240 136)
:top 0
:left 0
:right 0
:bottom 0})

(def background-blur-overlay
{:position :absolute
:left 0
Expand Down
36 changes: 16 additions & 20 deletions src/status_im2/contexts/onboarding/common/background/view.cljs
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
(ns status-im2.contexts.onboarding.common.background.view
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[status-im2.common.resources :as resources]
[react-native.linear-gradient :as linear-gradient]
[status-im2.contexts.onboarding.common.background.style :as style]))
[react-native.blur :as blur]
[status-im2.contexts.onboarding.common.carousel.view :as carousel]
[status-im2.contexts.onboarding.common.background.style :as style]
[status-im2.contexts.onboarding.common.carousel.animation :as carousel.animation]))

(defn view
[dark-overlay?]
[rn/view
{:style style/background-container}
[rn/image
{:blur-radius (if dark-overlay? 13 0)
:style {:height "100%"
:width "100%"}
;; Todo - get background image from sub using carousel index on landing page
:source (resources/get-image :onboarding-bg-1)}]
[linear-gradient/linear-gradient
{:colors [(if dark-overlay? (colors/custom-color :yin 50) "#000716")
(if dark-overlay? (colors/custom-color :yin 50 0) "#000716")]
:start {:x 0 :y 0}
:end {:x 0 :y 1}
:style (style/background-gradient-overlay dark-overlay?)}]
(when dark-overlay?
[:f>
(fn []
(carousel.animation/initialize-animation)
[rn/view
{:style style/background-blur-overlay}])])
{:style style/background-container}
[carousel/view dark-overlay?]
(when dark-overlay?
[blur/view
{:style style/background-blur-overlay
:blur-amount 30
:blur-radius 25
:blur-type :transparent
:overlay-color :transparent}])])])
47 changes: 47 additions & 0 deletions src/status_im2/contexts/onboarding/common/carousel/animation.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
(ns status-im2.contexts.onboarding.common.carousel.animation
(:require
[react-native.reanimated :as reanimated]
[utils.worklets.onboarding-carousel :as worklets.onboarding-carousel]))

(def progress (atom nil))
(def paused (atom nil))

(defn slide-animation
[value & [delay duration]]
(reanimated/with-delay
(or delay 300)
(reanimated/with-timing
value
(js-obj "duration" (or duration 4000)
"easing" (:linear reanimated/easings)))))

(defn animate-progress
[progress paused]
(reanimated/set-shared-value
progress
(reanimated/with-pause
(reanimated/with-repeat
(reanimated/with-sequence
(slide-animation 25)
(slide-animation 50)
(slide-animation 75)
(slide-animation 100)
(slide-animation 0 300 0))
-1)
paused)))

(defn initialize-animation
[]
(when-not @progress
(reset! progress (reanimated/use-shared-value 0))
(reset! paused (reanimated/use-shared-value false))
(animate-progress @progress @paused)))

;; Derived Values
(defn carousel-left-position
[window-width]
(worklets.onboarding-carousel/carousel-left-position window-width @progress))

(defn dynamic-progress-bar-width
[progress-bar-width]
(worklets.onboarding-carousel/dynamic-progress-bar-width progress-bar-width @progress))
59 changes: 59 additions & 0 deletions src/status_im2/contexts/onboarding/common/carousel/style.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
(ns status-im2.contexts.onboarding.common.carousel.style
(:require
[quo2.foundations.colors :as colors]))

(defn header-container
[status-bar-height content-width index]
{:position :absolute
:top 0
:left (* content-width index)
:padding-top (+ 30 status-bar-height)
:width content-width
:height (+ 96 status-bar-height)
:flex-direction :row
:background-color "#000716"})

(defn header-text-view
[window-width]
{:flex-direction :column
:width window-width
:padding-left 20})

(def carousel-text
{:color colors/white})

(def carousel-sub-text
{:color colors/white
:margin-top 2})

(defn background-image
[content-width]
{:resize-mode :stretch
:width content-width})

(defn progress-bar-item
[static? end?]
{:height 2
:flex 1
:background-color (if static? colors/white-opa-10 colors/white)
:margin-right (if end? 0 8)
:border-radius 4})

(def dynamic-progress-bar
{:height 2
:border-radius 4
:overflow :hidden})

(defn progress-bar-container
[progress-bar-width status-bar-height]
{:position :absolute
:width progress-bar-width
:margin-left 20
:top (+ 12 status-bar-height)})

(def carousel-container
{:position :absolute
:right 0
:top 0
:bottom 0
:flex-direction :row})
96 changes: 96 additions & 0 deletions src/status_im2/contexts/onboarding/common/carousel/view.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
(ns status-im2.contexts.onboarding.common.carousel.view
(:require [quo2.core :as quo]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[react-native.core :as rn]
[react-native.navigation :as navigation]
[react-native.reanimated :as reanimated]
[status-im2.common.resources :as resources]
[status-im2.contexts.onboarding.common.carousel.style :as style]
[status-im2.contexts.onboarding.common.carousel.animation :as animation]))

(def header-text
[{:text (i18n/label :t/join-decentralised-communities)
:sub-text (i18n/label :t/participate-in-the-metaverse)}
{:text (i18n/label :t/chat-with-friends)
:sub-text (i18n/label :t/with-full-encryption)}
{:text (i18n/label :t/own-your-crypto)
:sub-text (i18n/label :t/use-the-multichain-wallet)}
{:text (i18n/label :t/discover-web3)
:sub-text (i18n/label :t/explore-the-decentralized-web)}])

(defn header-text-view
[index window-width]
[rn/view {:style (style/header-text-view window-width)}
[quo/text
{:style style/carousel-text
:weight :semi-bold
:size :heading-2}
(get-in header-text [index :text])]
[quo/text
{:style style/carousel-sub-text
:size :paragraph-1}
(get-in header-text [index :sub-text])]])

(defn content-view
[window-width status-bar-height index]
(let [content-width (* 4 window-width)]
[:<>
[rn/image
{:style (style/background-image (* 4 window-width))
:source (resources/get-image :onboarding-illustration)}]
[rn/view {:style (style/header-container status-bar-height content-width index)}
[header-text-view 0 window-width]
[header-text-view 1 window-width]
[header-text-view 2 window-width]
[header-text-view 3 window-width]]]))

(defn progress-bar
[static? progress-bar-width]
[rn/view
{:style {:position :absolute
:top 0
:width progress-bar-width
:flex-direction :row}}
[rn/view {:style (style/progress-bar-item static? false)}]
[rn/view {:style (style/progress-bar-item static? false)}]
[rn/view {:style (style/progress-bar-item static? false)}]
[rn/view {:style (style/progress-bar-item static? true)}]])

(defn dynamic-progress-bar
[progress-bar-width]
[:f>
(fn []
(let [width (animation/dynamic-progress-bar-width progress-bar-width)
original-style style/dynamic-progress-bar
animated-style (reanimated/apply-animations-to-style
{:width width}
original-style)]
[reanimated/view {:style animated-style}
[progress-bar false progress-bar-width]]))])

(defn view
[]
[:f>
(fn []
(let [window-width (rf/sub [:dimensions/window-width])
view-id (rf/sub [:view-id])
status-bar-height (:status-bar-height @navigation/constants)
progress-bar-width (- window-width 40)
carousel-left (animation/carousel-left-position window-width)
original-style style/carousel-container
animated-style (reanimated/apply-animations-to-style
{:left carousel-left}
original-style)]
(reanimated/set-shared-value @animation/paused (not= view-id :intro))
[:<>
[reanimated/view {:style animated-style}
[content-view window-width status-bar-height 0]
[content-view window-width status-bar-height 1]]
[rn/view
{:style (style/progress-bar-container
progress-bar-width
status-bar-height)}
[progress-bar true progress-bar-width]
[dynamic-progress-bar progress-bar-width]]]))])

Loading

0 comments on commit dad52ad

Please sign in to comment.