Lightbox opacity swipe animation, and margins (#16510)
* feat: lightbox animations
This commit is contained in:
parent
f5948fa016
commit
7392b9bf50
|
@ -58,7 +58,7 @@
|
||||||
:start {:x 0 :y 1}
|
:start {:x 0 :y 1}
|
||||||
:end {:x 0 :y 0}
|
:end {:x 0 :y 0}
|
||||||
:style (style/gradient-container insets animations derived)}
|
:style (style/gradient-container insets animations derived)}
|
||||||
[text-sheet/view messages animations state]
|
[text-sheet/view messages animations state props]
|
||||||
[rn/flat-list
|
[rn/flat-list
|
||||||
{:ref #(reset! (:small-list-ref props) %)
|
{:ref #(reset! (:small-list-ref props) %)
|
||||||
:key-fn :message-id
|
:key-fn :message-id
|
||||||
|
|
|
@ -40,12 +40,13 @@
|
||||||
|
|
||||||
(defn expand-sheet
|
(defn expand-sheet
|
||||||
[{:keys [derived-value overlay-opacity saved-top]}
|
[{:keys [derived-value overlay-opacity saved-top]}
|
||||||
expanded-height max-height overlay-z-index expanded?]
|
expanded-height max-height overlay-z-index expanded? text-sheet-lock?]
|
||||||
(reanimated/animate derived-value expanded-height)
|
(when-not @text-sheet-lock?
|
||||||
(reanimated/animate overlay-opacity (/ expanded-height max-height))
|
(reanimated/animate derived-value expanded-height)
|
||||||
(reanimated/set-shared-value saved-top (- expanded-height))
|
(reanimated/animate overlay-opacity (/ expanded-height max-height))
|
||||||
(reset! overlay-z-index 1)
|
(reanimated/set-shared-value saved-top (- expanded-height))
|
||||||
(reset! expanded? true))
|
(reset! overlay-z-index 1)
|
||||||
|
(reset! expanded? true)))
|
||||||
|
|
||||||
(defn on-scroll
|
(defn on-scroll
|
||||||
[e expanded? dragging? {:keys [gradient-opacity]}]
|
[e expanded? dragging? {:keys [gradient-opacity]}]
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
[rn/view {:style style/bar}]]))
|
[rn/view {:style style/bar}]]))
|
||||||
|
|
||||||
(defn text-sheet
|
(defn text-sheet
|
||||||
[messages overlay-opacity overlay-z-index]
|
[messages overlay-opacity overlay-z-index text-sheet-lock?]
|
||||||
(let [text-height (reagent/atom 0)
|
(let [text-height (reagent/atom 0)
|
||||||
expanded? (reagent/atom false)
|
expanded? (reagent/atom false)
|
||||||
dragging? (atom false)]
|
dragging? (atom false)]
|
||||||
|
@ -49,7 +49,12 @@
|
||||||
[reanimated/touchable-opacity
|
[reanimated/touchable-opacity
|
||||||
{:active-opacity 1
|
{:active-opacity 1
|
||||||
:on-press
|
:on-press
|
||||||
#(utils/expand-sheet animations expanded-height max-height overlay-z-index expanded?)
|
#(utils/expand-sheet animations
|
||||||
|
expanded-height
|
||||||
|
max-height
|
||||||
|
overlay-z-index
|
||||||
|
expanded?
|
||||||
|
text-sheet-lock?)
|
||||||
:style (style/sheet-container derived)}
|
:style (style/sheet-container derived)}
|
||||||
[bar @text-height]
|
[bar @text-height]
|
||||||
[reanimated/linear-gradient
|
[reanimated/linear-gradient
|
||||||
|
@ -74,5 +79,5 @@
|
||||||
:on-layout #(utils/on-layout % text-height)}]]]]))))
|
:on-layout #(utils/on-layout % text-height)}]]]]))))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[messages {:keys [overlay-opacity]} {:keys [overlay-z-index]}]
|
[messages {:keys [overlay-opacity]} {:keys [overlay-z-index]} {:keys [text-sheet-lock?]}]
|
||||||
[:f> text-sheet messages overlay-opacity overlay-z-index])
|
[:f> text-sheet messages overlay-opacity overlay-z-index text-sheet-lock?])
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im2.contexts.chat.lightbox.utils
|
(ns status-im2.contexts.chat.lightbox.utils
|
||||||
(:require
|
(:require
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
|
[oops.core :as oops]
|
||||||
[quo2.foundations.colors :as colors]
|
[quo2.foundations.colors :as colors]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.gesture :as gesture]
|
[react-native.gesture :as gesture]
|
||||||
|
@ -11,7 +12,6 @@
|
||||||
[status-im2.contexts.chat.lightbox.animations :as anim]
|
[status-im2.contexts.chat.lightbox.animations :as anim]
|
||||||
[status-im2.contexts.chat.lightbox.top-view :as top-view]
|
[status-im2.contexts.chat.lightbox.top-view :as top-view]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[oops.core :refer [oget]]
|
|
||||||
[status-im2.contexts.chat.lightbox.constants :as constants]
|
[status-im2.contexts.chat.lightbox.constants :as constants]
|
||||||
[utils.worklets.lightbox :as worklet]))
|
[utils.worklets.lightbox :as worklet]))
|
||||||
|
|
||||||
|
@ -98,6 +98,20 @@
|
||||||
(when (and enabled? (not= result orientation/landscape-right))
|
(when (and enabled? (not= result orientation/landscape-right))
|
||||||
(handle-orientation result props state animations))))))))
|
(handle-orientation result props state animations))))))))
|
||||||
|
|
||||||
|
(defn on-scroll
|
||||||
|
[e item-width {:keys [images-opacity]} landscape?]
|
||||||
|
(let [total-item-width (+ item-width constants/separator-width)
|
||||||
|
progress (/ (if landscape?
|
||||||
|
(oops/oget e "nativeEvent.contentOffset.y")
|
||||||
|
(oops/oget e "nativeEvent.contentOffset.x"))
|
||||||
|
total-item-width)
|
||||||
|
index-initial (max (Math/floor progress) 0)
|
||||||
|
index-final (inc index-initial)
|
||||||
|
decimal-part (- progress index-initial)]
|
||||||
|
(anim/set-val (nth images-opacity index-initial) (- 1 decimal-part))
|
||||||
|
(when (< index-final (count images-opacity))
|
||||||
|
(anim/set-val (nth images-opacity index-final) decimal-part))))
|
||||||
|
|
||||||
(defn drag-gesture
|
(defn drag-gesture
|
||||||
[{:keys [pan-x pan-y background-color opacity layout]} x? set-full-height?]
|
[{:keys [pan-x pan-y background-color opacity layout]} x? set-full-height?]
|
||||||
(->
|
(->
|
||||||
|
@ -105,14 +119,15 @@
|
||||||
(gesture/enabled true)
|
(gesture/enabled true)
|
||||||
(gesture/max-pointers 1)
|
(gesture/max-pointers 1)
|
||||||
(gesture/on-start #(reset! set-full-height? false))
|
(gesture/on-start #(reset! set-full-height? false))
|
||||||
(gesture/on-update (fn [e]
|
(gesture/on-update
|
||||||
(let [translation (if x? (oget e "translationX") (oget e "translationY"))
|
(fn [e]
|
||||||
progress (Math/abs (/ translation constants/drag-threshold))]
|
(let [translation (if x? (oops/oget e "translationX") (oops/oget e "translationY"))
|
||||||
(anim/set-val (if x? pan-x pan-y) translation)
|
progress (Math/abs (/ translation constants/drag-threshold))]
|
||||||
(anim/set-val opacity (- 1 progress))
|
(anim/set-val (if x? pan-x pan-y) translation)
|
||||||
(anim/set-val layout (* progress -20)))))
|
(anim/set-val opacity (- 1 progress))
|
||||||
|
(anim/set-val layout (* progress -20)))))
|
||||||
(gesture/on-end (fn [e]
|
(gesture/on-end (fn [e]
|
||||||
(if (> (Math/abs (if x? (oget e "translationX") (oget e "translationY")))
|
(if (> (Math/abs (if x? (oops/oget e "translationX") (oops/oget e "translationY")))
|
||||||
constants/drag-threshold)
|
constants/drag-threshold)
|
||||||
(do
|
(do
|
||||||
(anim/animate background-color "rgba(0,0,0,0)")
|
(anim/animate background-color "rgba(0,0,0,0)")
|
||||||
|
@ -129,6 +144,7 @@
|
||||||
{:flat-list-ref (atom nil)
|
{:flat-list-ref (atom nil)
|
||||||
:small-list-ref (atom nil)
|
:small-list-ref (atom nil)
|
||||||
:scroll-index-lock? (atom true)
|
:scroll-index-lock? (atom true)
|
||||||
|
:text-sheet-lock? (atom false)
|
||||||
:timers (atom {})})
|
:timers (atom {})})
|
||||||
|
|
||||||
(defn init-state
|
(defn init-state
|
||||||
|
@ -142,20 +158,29 @@
|
||||||
:set-full-height? (reagent/atom false)
|
:set-full-height? (reagent/atom false)
|
||||||
:overlay-z-index (reagent/atom 0)})
|
:overlay-z-index (reagent/atom 0)})
|
||||||
|
|
||||||
|
(defn initialize-opacity
|
||||||
|
[size selected-index]
|
||||||
|
(mapv #(if (= % selected-index)
|
||||||
|
(anim/use-val 1)
|
||||||
|
(anim/use-val 0))
|
||||||
|
(range size)))
|
||||||
|
|
||||||
(defn init-animations
|
(defn init-animations
|
||||||
[]
|
[size index]
|
||||||
{:background-color (anim/use-val colors/neutral-100-opa-0)
|
{:background-color (anim/use-val colors/neutral-100-opa-0)
|
||||||
:border (anim/use-val (if platform/ios? 0 16))
|
:border (anim/use-val (if platform/ios? 0 16))
|
||||||
:opacity (anim/use-val 0)
|
:full-screen-scale (anim/use-val 1)
|
||||||
:overlay-opacity (anim/use-val 0)
|
:opacity (anim/use-val 0)
|
||||||
:rotate (anim/use-val "0deg")
|
:overlay-opacity (anim/use-val 0)
|
||||||
:layout (anim/use-val -10)
|
:images-opacity (initialize-opacity size index)
|
||||||
:top-view-y (anim/use-val 0)
|
:rotate (anim/use-val "0deg")
|
||||||
:top-view-x (anim/use-val 0)
|
:layout (anim/use-val -10)
|
||||||
:top-view-width (anim/use-val (:width (rn/get-window)))
|
:top-view-y (anim/use-val 0)
|
||||||
:top-view-bg (anim/use-val colors/neutral-100-opa-0)
|
:top-view-x (anim/use-val 0)
|
||||||
:pan-y (anim/use-val 0)
|
:top-view-width (anim/use-val (:width (rn/get-window)))
|
||||||
:pan-x (anim/use-val 0)})
|
:top-view-bg (anim/use-val colors/neutral-100-opa-0)
|
||||||
|
:pan-y (anim/use-val 0)
|
||||||
|
:pan-x (anim/use-val 0)})
|
||||||
|
|
||||||
(defn init-derived-animations
|
(defn init-derived-animations
|
||||||
[{:keys [layout]}]
|
[{:keys [layout]}]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im2.contexts.chat.lightbox.view
|
(ns status-im2.contexts.chat.lightbox.view
|
||||||
(:require
|
(:require
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
|
[oops.core :as oops]
|
||||||
[quo2.foundations.colors :as colors]
|
[quo2.foundations.colors :as colors]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.orientation :as orientation]
|
[react-native.orientation :as orientation]
|
||||||
|
@ -14,7 +15,6 @@
|
||||||
[status-im2.contexts.chat.lightbox.zoomable-image.view :as zoomable-image]
|
[status-im2.contexts.chat.lightbox.zoomable-image.view :as zoomable-image]
|
||||||
[status-im2.contexts.chat.lightbox.top-view :as top-view]
|
[status-im2.contexts.chat.lightbox.top-view :as top-view]
|
||||||
[status-im2.contexts.chat.lightbox.bottom-view :as bottom-view]
|
[status-im2.contexts.chat.lightbox.bottom-view :as bottom-view]
|
||||||
[oops.core :refer [oget]]
|
|
||||||
[status-im2.contexts.chat.lightbox.utils :as utils]
|
[status-im2.contexts.chat.lightbox.utils :as utils]
|
||||||
[status-im2.contexts.chat.lightbox.constants :as constants]))
|
[status-im2.contexts.chat.lightbox.constants :as constants]))
|
||||||
|
|
||||||
|
@ -28,12 +28,12 @@
|
||||||
(defn on-viewable-items-changed
|
(defn on-viewable-items-changed
|
||||||
[e {:keys [scroll-index-lock? small-list-ref]} {:keys [scroll-index]}]
|
[e {:keys [scroll-index-lock? small-list-ref]} {:keys [scroll-index]}]
|
||||||
(when-not @scroll-index-lock?
|
(when-not @scroll-index-lock?
|
||||||
(let [changed (-> e (oget :changed) first)
|
(let [changed (-> e (oops/oget :changed) first)
|
||||||
index (oget changed :index)]
|
index (oops/oget changed :index)]
|
||||||
(reset! scroll-index index)
|
(reset! scroll-index index)
|
||||||
(when @small-list-ref
|
(when @small-list-ref
|
||||||
(.scrollToIndex ^js @small-list-ref #js {:animated true :index index}))
|
(.scrollToIndex ^js @small-list-ref #js {:animated true :index index}))
|
||||||
(rf/dispatch [:chat.ui/update-shared-element-id (:message-id (oget changed :item))]))))
|
(rf/dispatch [:chat.ui/update-shared-element-id (:message-id (oops/oget changed :item))]))))
|
||||||
|
|
||||||
(defn image
|
(defn image
|
||||||
[message index _ {:keys [screen-width screen-height] :as args}]
|
[message index _ {:keys [screen-width screen-height] :as args}]
|
||||||
|
@ -79,19 +79,23 @@
|
||||||
[gesture/flat-list
|
[gesture/flat-list
|
||||||
{:ref #(reset! (:flat-list-ref props) %)
|
{:ref #(reset! (:flat-list-ref props) %)
|
||||||
:key-fn :message-id
|
:key-fn :message-id
|
||||||
|
:on-scroll #(utils/on-scroll % item-width animations landscape?)
|
||||||
|
:scroll-event-throttle 8
|
||||||
:style {:width (+ screen-width constants/separator-width)}
|
:style {:width (+ screen-width constants/separator-width)}
|
||||||
:data @data
|
:data @data
|
||||||
:render-fn image
|
:render-fn image
|
||||||
:render-data {:opacity-value (:opacity animations)
|
:render-data {:opacity-value (:opacity animations)
|
||||||
:border-value (:border animations)
|
:border-value (:border animations)
|
||||||
:transparent? transparent?
|
:full-screen-scale (:full-screen-scale animations)
|
||||||
:set-full-height? set-full-height?
|
:images-opacity (:images-opacity animations)
|
||||||
:screen-height screen-height
|
:transparent? transparent?
|
||||||
:screen-width screen-width
|
:set-full-height? set-full-height?
|
||||||
:window-height window-height
|
:screen-height screen-height
|
||||||
:window-width window-width
|
:screen-width screen-width
|
||||||
:props props
|
:window-height window-height
|
||||||
:curr-orientation curr-orientation}
|
:window-width window-width
|
||||||
|
:props props
|
||||||
|
:curr-orientation curr-orientation}
|
||||||
:horizontal horizontal?
|
:horizontal horizontal?
|
||||||
:inverted inverted?
|
:inverted inverted?
|
||||||
:paging-enabled true
|
:paging-enabled true
|
||||||
|
@ -113,7 +117,7 @@
|
||||||
handle-items-changed (fn [e]
|
handle-items-changed (fn [e]
|
||||||
(on-viewable-items-changed e props state))]
|
(on-viewable-items-changed e props state))]
|
||||||
(fn []
|
(fn []
|
||||||
(let [animations (utils/init-animations)
|
(let [animations (utils/init-animations (count messages) index)
|
||||||
derived (utils/init-derived-animations animations)]
|
derived (utils/init-derived-animations animations)]
|
||||||
(anim/animate (:background-color animations) colors/neutral-100)
|
(anim/animate (:background-color animations) colors/neutral-100)
|
||||||
(reset! (:data state) messages)
|
(reset! (:data state) messages)
|
||||||
|
|
|
@ -15,3 +15,5 @@
|
||||||
(def ^:const default-duration 300)
|
(def ^:const default-duration 300)
|
||||||
|
|
||||||
(def ^:const default-dimension 1000)
|
(def ^:const default-dimension 1000)
|
||||||
|
|
||||||
|
(def ^:const margin 8)
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
(defn container
|
(defn container
|
||||||
[{:keys [width height]}
|
[{:keys [width height]}
|
||||||
{:keys [pan-x pan-y pinch-x pinch-y scale]}
|
{:keys [pan-x pan-y pinch-x pinch-y scale]}
|
||||||
|
full-screen-scale
|
||||||
set-full-height?
|
set-full-height?
|
||||||
portrait?]
|
portrait?]
|
||||||
(reanimated/apply-animations-to-style
|
(reanimated/apply-animations-to-style
|
||||||
|
@ -13,7 +14,8 @@
|
||||||
{:translateY pan-y}
|
{:translateY pan-y}
|
||||||
{:translateX pinch-x}
|
{:translateX pinch-x}
|
||||||
{:translateY pinch-y}
|
{:translateY pinch-y}
|
||||||
{:scale scale}]}
|
{:scale scale}
|
||||||
|
{:scale full-screen-scale}]}
|
||||||
{:justify-content :center
|
{:justify-content :center
|
||||||
:align-items :center
|
:align-items :center
|
||||||
:width (if (or platform/ios? portrait?) width "100%")
|
:width (if (or platform/ios? portrait?) width "100%")
|
||||||
|
@ -22,10 +24,12 @@
|
||||||
(defn image
|
(defn image
|
||||||
[{:keys [image-width image-height]}
|
[{:keys [image-width image-height]}
|
||||||
{:keys [rotate rotate-scale]}
|
{:keys [rotate rotate-scale]}
|
||||||
border-radius]
|
{:keys [border-value images-opacity]}
|
||||||
|
index]
|
||||||
(reanimated/apply-animations-to-style
|
(reanimated/apply-animations-to-style
|
||||||
{:transform [{:rotate rotate}
|
{:transform [{:rotate rotate}
|
||||||
{:scale rotate-scale}]
|
{:scale rotate-scale}]
|
||||||
:border-radius border-radius}
|
:opacity (nth images-opacity index)
|
||||||
|
:border-radius border-value}
|
||||||
{:width image-width
|
{:width image-width
|
||||||
:height image-height}))
|
:height image-height}))
|
||||||
|
|
|
@ -1,31 +1,32 @@
|
||||||
(ns status-im2.contexts.chat.lightbox.zoomable-image.utils
|
(ns status-im2.contexts.chat.lightbox.zoomable-image.utils
|
||||||
(:require
|
(:require
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
|
[react-native.core :as rn]
|
||||||
[react-native.navigation :as navigation]
|
[react-native.navigation :as navigation]
|
||||||
[react-native.orientation :as orientation]
|
[react-native.orientation :as orientation]
|
||||||
[react-native.platform :as platform]
|
[react-native.platform :as platform]
|
||||||
[react-native.reanimated :as reanimated]
|
[react-native.reanimated :as reanimated]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im2.contexts.chat.lightbox.zoomable-image.constants :as c]
|
[status-im2.contexts.chat.lightbox.zoomable-image.constants :as constants]
|
||||||
[status-im2.contexts.chat.lightbox.animations :as anim]
|
[status-im2.contexts.chat.lightbox.animations :as anim]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
;;; Helpers
|
;;; Helpers
|
||||||
(defn center-x
|
(defn center-x
|
||||||
[{:keys [pinch-x pinch-x-start pan-x pan-x-start]} exit?]
|
[{:keys [pinch-x pinch-x-start pan-x pan-x-start]} exit?]
|
||||||
(let [duration (if exit? 100 c/default-duration)]
|
(let [duration (if exit? 100 constants/default-duration)]
|
||||||
(anim/animate pinch-x c/init-offset duration)
|
(anim/animate pinch-x constants/init-offset duration)
|
||||||
(anim/set-val pinch-x-start c/init-offset)
|
(anim/set-val pinch-x-start constants/init-offset)
|
||||||
(anim/animate pan-x c/init-offset duration)
|
(anim/animate pan-x constants/init-offset duration)
|
||||||
(anim/set-val pan-x-start c/init-offset)))
|
(anim/set-val pan-x-start constants/init-offset)))
|
||||||
|
|
||||||
(defn center-y
|
(defn center-y
|
||||||
[{:keys [pinch-y pinch-y-start pan-y pan-y-start]} exit?]
|
[{:keys [pinch-y pinch-y-start pan-y pan-y-start]} exit?]
|
||||||
(let [duration (if exit? 100 c/default-duration)]
|
(let [duration (if exit? 100 constants/default-duration)]
|
||||||
(anim/animate pinch-y c/init-offset duration)
|
(anim/animate pinch-y constants/init-offset duration)
|
||||||
(anim/set-val pinch-y-start c/init-offset)
|
(anim/set-val pinch-y-start constants/init-offset)
|
||||||
(anim/animate pan-y c/init-offset duration)
|
(anim/animate pan-y constants/init-offset duration)
|
||||||
(anim/set-val pan-y-start c/init-offset)))
|
(anim/set-val pan-y-start constants/init-offset)))
|
||||||
|
|
||||||
(defn reset-values
|
(defn reset-values
|
||||||
[exit? animations {:keys [focal-x focal-y]}]
|
[exit? animations {:keys [focal-x focal-y]}]
|
||||||
|
@ -40,9 +41,9 @@
|
||||||
{:keys [x-threshold-scale y-threshold-scale]}
|
{:keys [x-threshold-scale y-threshold-scale]}
|
||||||
{:keys [scale saved-scale] :as animations}
|
{:keys [scale saved-scale] :as animations}
|
||||||
{:keys [pan-x-enabled? pan-y-enabled?] :as state}]
|
{:keys [pan-x-enabled? pan-y-enabled?] :as state}]
|
||||||
(when (= value c/min-scale)
|
(when (= value constants/min-scale)
|
||||||
(reset-values exit? animations state))
|
(reset-values exit? animations state))
|
||||||
(anim/animate scale value (if exit? 100 c/default-duration))
|
(anim/animate scale value (if exit? 100 constants/default-duration))
|
||||||
(anim/set-val saved-scale value)
|
(anim/set-val saved-scale value)
|
||||||
(reset! pan-x-enabled? (> value x-threshold-scale))
|
(reset! pan-x-enabled? (> value x-threshold-scale))
|
||||||
(reset! pan-y-enabled? (> value y-threshold-scale)))
|
(reset! pan-y-enabled? (> value y-threshold-scale)))
|
||||||
|
@ -66,8 +67,8 @@
|
||||||
(anim/animate rotate-scale landscape-scale-val))
|
(anim/animate rotate-scale landscape-scale-val))
|
||||||
(= curr-orientation orientation/portrait)
|
(= curr-orientation orientation/portrait)
|
||||||
(do
|
(do
|
||||||
(anim/animate rotate c/init-rotation)
|
(anim/animate rotate constants/init-rotation)
|
||||||
(anim/animate rotate-scale c/min-scale)))
|
(anim/animate rotate-scale constants/min-scale)))
|
||||||
(cond
|
(cond
|
||||||
(= curr-orientation orientation/landscape-left)
|
(= curr-orientation orientation/landscape-left)
|
||||||
(do
|
(do
|
||||||
|
@ -79,8 +80,8 @@
|
||||||
(anim/set-val rotate-scale landscape-scale-val))
|
(anim/set-val rotate-scale landscape-scale-val))
|
||||||
(= curr-orientation orientation/portrait)
|
(= curr-orientation orientation/portrait)
|
||||||
(do
|
(do
|
||||||
(anim/set-val rotate c/init-rotation)
|
(anim/set-val rotate constants/init-rotation)
|
||||||
(anim/set-val rotate-scale c/min-scale))))
|
(anim/set-val rotate-scale constants/min-scale))))
|
||||||
(center-x animations false)
|
(center-x animations false)
|
||||||
(center-y animations false)
|
(center-y animations false)
|
||||||
(reset! pan-x-enabled? (> (anim/get-val scale) x-threshold-scale))
|
(reset! pan-x-enabled? (> (anim/get-val scale) x-threshold-scale))
|
||||||
|
@ -92,9 +93,9 @@
|
||||||
[exit-lightbox-signal index scale rescale set-full-height?]
|
[exit-lightbox-signal index scale rescale set-full-height?]
|
||||||
(when (= exit-lightbox-signal index)
|
(when (= exit-lightbox-signal index)
|
||||||
(reset! set-full-height? false)
|
(reset! set-full-height? false)
|
||||||
(if (> scale c/min-scale)
|
(if (> scale constants/min-scale)
|
||||||
(do
|
(do
|
||||||
(rescale c/min-scale true)
|
(rescale constants/min-scale true)
|
||||||
(js/setTimeout #(rf/dispatch [:navigate-back]) 70))
|
(js/setTimeout #(rf/dispatch [:navigate-back]) 70))
|
||||||
(rf/dispatch [:navigate-back]))
|
(rf/dispatch [:navigate-back]))
|
||||||
(js/setTimeout #(rf/dispatch [:chat.ui/exit-lightbox-signal nil]) 500)))
|
(js/setTimeout #(rf/dispatch [:chat.ui/exit-lightbox-signal nil]) 500)))
|
||||||
|
@ -102,13 +103,16 @@
|
||||||
(defn handle-zoom-out-signal
|
(defn handle-zoom-out-signal
|
||||||
"Zooms out when pressing on another photo from the small bottom list"
|
"Zooms out when pressing on another photo from the small bottom list"
|
||||||
[zoom-out-signal index scale rescale]
|
[zoom-out-signal index scale rescale]
|
||||||
(when (and (= zoom-out-signal index) (> scale c/min-scale))
|
(when (and (= zoom-out-signal index) (> scale constants/min-scale))
|
||||||
(rescale c/min-scale true)))
|
(rescale constants/min-scale true)))
|
||||||
|
|
||||||
(defn toggle-opacity
|
(defn toggle-opacity
|
||||||
[index {:keys [opacity-value border-value transparent? props]} portrait?]
|
[index {:keys [opacity-value border-value full-screen-scale transparent? props]} portrait?]
|
||||||
(let [{:keys [small-list-ref timers]} props
|
(let [{:keys [small-list-ref timers text-sheet-lock?]} props
|
||||||
opacity (reanimated/get-shared-value opacity-value)]
|
opacity (reanimated/get-shared-value opacity-value)
|
||||||
|
scale-value (+ 1
|
||||||
|
(/ constants/margin
|
||||||
|
(:width (rn/get-window))))]
|
||||||
(if (= opacity 1)
|
(if (= opacity 1)
|
||||||
(do
|
(do
|
||||||
(js/clearTimeout (:show-0 @timers))
|
(js/clearTimeout (:show-0 @timers))
|
||||||
|
@ -119,7 +123,9 @@
|
||||||
(js/setTimeout #(navigation/merge-options "lightbox" {:statusBar {:visible false}})
|
(js/setTimeout #(navigation/merge-options "lightbox" {:statusBar {:visible false}})
|
||||||
(if platform/ios? 75 0)))
|
(if platform/ios? 75 0)))
|
||||||
(anim/animate opacity-value 0)
|
(anim/animate opacity-value 0)
|
||||||
(swap! timers assoc :hide-1 (js/setTimeout #(reset! transparent? (not @transparent?)) 400)))
|
(swap! timers assoc :hide-1 (js/setTimeout #(reset! transparent? (not @transparent?)) 400))
|
||||||
|
(reset! text-sheet-lock? true)
|
||||||
|
(js/setTimeout #(reset! text-sheet-lock? false) 300))
|
||||||
(do
|
(do
|
||||||
(js/clearTimeout (:hide-0 @timers))
|
(js/clearTimeout (:hide-0 @timers))
|
||||||
(js/clearTimeout (:hide-1 @timers))
|
(js/clearTimeout (:hide-1 @timers))
|
||||||
|
@ -135,7 +141,8 @@
|
||||||
:show-2
|
:show-2
|
||||||
(js/setTimeout #(navigation/merge-options "lightbox" {:statusBar {:visible true}})
|
(js/setTimeout #(navigation/merge-options "lightbox" {:statusBar {:visible true}})
|
||||||
(if platform/ios? 150 50))))))
|
(if platform/ios? 150 50))))))
|
||||||
(anim/animate border-value (if (= opacity 1) 0 16))))
|
(anim/animate border-value (if (= opacity 1) 0 16))
|
||||||
|
(anim/animate full-screen-scale (if (= opacity 1) scale-value 1))))
|
||||||
|
|
||||||
;;; Dimensions
|
;;; Dimensions
|
||||||
(defn get-dimensions
|
(defn get-dimensions
|
||||||
|
@ -150,11 +157,12 @@
|
||||||
landscape-image-width (* pixels-width (/ window-width pixels-height))
|
landscape-image-width (* pixels-width (/ window-width pixels-height))
|
||||||
width (if landscape? landscape-image-width portrait-image-width)
|
width (if landscape? landscape-image-width portrait-image-width)
|
||||||
height (if landscape? screen-height portrait-image-height)
|
height (if landscape? screen-height portrait-image-height)
|
||||||
container-width (if platform/ios? window-width width)
|
container-width (- (if platform/ios? window-width width) constants/margin)
|
||||||
container-height (if (and platform/ios? landscape?) landscape-image-width height)]
|
container-height (- (if (and platform/ios? landscape?) landscape-image-width height)
|
||||||
|
constants/margin)]
|
||||||
;; width and height used in style prop
|
;; width and height used in style prop
|
||||||
{:image-width (if platform/ios? portrait-image-width width)
|
{:image-width (- (if platform/ios? portrait-image-width width) constants/margin)
|
||||||
:image-height (if platform/ios? portrait-image-height height)
|
:image-height (- (if platform/ios? portrait-image-height height) constants/margin)
|
||||||
;; container width and height, also used in animations calculations
|
;; container width and height, also used in animations calculations
|
||||||
:width container-width
|
:width container-width
|
||||||
:height container-height
|
:height container-height
|
||||||
|
@ -169,7 +177,7 @@
|
||||||
;;; MATH
|
;;; MATH
|
||||||
(defn get-max-offset
|
(defn get-max-offset
|
||||||
[size screen-size scale]
|
[size screen-size scale]
|
||||||
(/ (- (* size (min scale c/max-scale))
|
(/ (- (* size (min scale constants/max-scale))
|
||||||
screen-size)
|
screen-size)
|
||||||
2))
|
2))
|
||||||
|
|
||||||
|
@ -181,8 +189,8 @@
|
||||||
(defn get-double-tap-offset
|
(defn get-double-tap-offset
|
||||||
[size screen-size focal]
|
[size screen-size focal]
|
||||||
(let [center (/ size 2)
|
(let [center (/ size 2)
|
||||||
target-point (* (- center focal) c/double-tap-scale)
|
target-point (* (- center focal) constants/double-tap-scale)
|
||||||
max-offset (get-max-offset size screen-size c/double-tap-scale)
|
max-offset (get-max-offset size screen-size constants/double-tap-scale)
|
||||||
translate-val (min (Math/abs target-point) max-offset)]
|
translate-val (min (Math/abs target-point) max-offset)]
|
||||||
(if (neg? target-point) (- translate-val) translate-val)))
|
(if (neg? target-point) (- translate-val) translate-val)))
|
||||||
|
|
||||||
|
@ -201,20 +209,20 @@
|
||||||
;;; INITIALIZATIONS
|
;;; INITIALIZATIONS
|
||||||
(defn init-animations
|
(defn init-animations
|
||||||
[]
|
[]
|
||||||
{:scale (anim/use-val c/min-scale)
|
{:scale (anim/use-val constants/min-scale)
|
||||||
:saved-scale (anim/use-val c/min-scale)
|
:saved-scale (anim/use-val constants/min-scale)
|
||||||
:pan-x-start (anim/use-val c/init-offset)
|
:pan-x-start (anim/use-val constants/init-offset)
|
||||||
:pan-x (anim/use-val c/init-offset)
|
:pan-x (anim/use-val constants/init-offset)
|
||||||
:pan-y-start (anim/use-val c/init-offset)
|
:pan-y-start (anim/use-val constants/init-offset)
|
||||||
:pan-y (anim/use-val c/init-offset)
|
:pan-y (anim/use-val constants/init-offset)
|
||||||
:pinch-x-start (anim/use-val c/init-offset)
|
:pinch-x-start (anim/use-val constants/init-offset)
|
||||||
:pinch-x (anim/use-val c/init-offset)
|
:pinch-x (anim/use-val constants/init-offset)
|
||||||
:pinch-y-start (anim/use-val c/init-offset)
|
:pinch-y-start (anim/use-val constants/init-offset)
|
||||||
:pinch-y (anim/use-val c/init-offset)
|
:pinch-y (anim/use-val constants/init-offset)
|
||||||
:pinch-x-max (anim/use-val js/Infinity)
|
:pinch-x-max (anim/use-val js/Infinity)
|
||||||
:pinch-y-max (anim/use-val js/Infinity)
|
:pinch-y-max (anim/use-val js/Infinity)
|
||||||
:rotate (anim/use-val c/init-rotation)
|
:rotate (anim/use-val constants/init-rotation)
|
||||||
:rotate-scale (anim/use-val c/min-scale)})
|
:rotate-scale (anim/use-val constants/min-scale)})
|
||||||
|
|
||||||
(defn init-state
|
(defn init-state
|
||||||
[]
|
[]
|
||||||
|
|
|
@ -221,12 +221,13 @@
|
||||||
[reanimated/view
|
[reanimated/view
|
||||||
{:style (style/container dimensions
|
{:style (style/container dimensions
|
||||||
animations
|
animations
|
||||||
|
(:full-screen-scale render-data)
|
||||||
@set-full-height?
|
@set-full-height?
|
||||||
(= curr-orientation orientation/portrait))}
|
(= curr-orientation orientation/portrait))}
|
||||||
[reanimated/fast-image
|
[reanimated/fast-image
|
||||||
{:source {:uri (http/replace-port (:image content) (rf/sub [:mediaserver/port]))}
|
{:source {:uri (http/replace-port (:image content) (rf/sub [:mediaserver/port]))}
|
||||||
:native-ID (when focused? :shared-element)
|
:native-ID (when focused? :shared-element)
|
||||||
:style (style/image dimensions animations (:border-value render-data))}]]]))
|
:style (style/image dimensions animations render-data index)}]]]))
|
||||||
|
|
||||||
(defn zoomable-image
|
(defn zoomable-image
|
||||||
[]
|
[]
|
||||||
|
|
Loading…
Reference in New Issue