git.iko.soy/rowtype-yoga/psfp
on master help sign in
Finally resize works
commit8e9130c6247c592fe49cae0f8fafbf7aef2e66f2 authorMark Eibes <mark.eibes@gmail.com> dateTue 12 May 2020, 00:28 (6 years ago) parent0d8219a
1 file changed+106−85
components/src/Yoga/Grimoire/Component.purs+106−85
components/src/Yoga/Grimoire/Component.purs+106−85
@@ -1,24 +1,27 @@
11module Yoga.Grimoire.Component where
22
33import Prelude
4−import Data.Array (mapWithIndex, zip, (!!))
4+import Data.Array (length, mapWithIndex, zip, (!!), (..))
55import Data.Array as Array
66import Data.FoldableWithIndex (findWithIndex)
77import Data.Interpolate as Interp
88import Data.Lens (set)
99import Data.Lens.Index (ix)
10−import Data.Maybe (Maybe(..), fromMaybe)
10+import Data.Maybe (Maybe(..), fromMaybe, fromMaybe')
1111import Data.Nullable (Nullable)
1212import Data.Nullable as Nullable
1313import Data.Symbol (SProxy(..))
1414import Data.Traversable (for, sequence)
1515import Data.Tuple.Nested ((/\), type (/\))
16+import Debug.Trace (spy)
1617import Effect (Effect)
18+import Effect.Class.Console (log)
1719import Justifill (justifill)
20+import Partial.Unsafe (unsafeCrashWith)
1821import React.Basic (ReactComponent)
1922import React.Basic.DOM (css)
2023import React.Basic.Helpers (jsx)
21−import React.Basic.Hooks (Ref, component, element, readRef, useLayoutEffect, useRef, writeRef)
24+import React.Basic.Hooks (Ref, component, element, readRef, useLayoutEffect, useRef, useState, writeRef)
2225import React.Basic.Hooks as React
2326import React.Basic.Hooks.Spring (animatedDiv, useSprings)
2427import React.Basic.Hooks.UseGesture (useDrag, withDragProps)
@@ -31,7 +34,6 @@ import Web.HTML.HTMLElement as HTMLElement
3134import Yoga.Grid.Component as Grid
3235import Yoga.Grimoire.Spell.Component as GrimoireSpell
3336import Yoga.Grimoire.Styles (styles)
34−import Yoga.Helpers ((?||))
3537import Yoga.Resize.Hook (useResize)
3638import Yoga.Spell.Types (Spell)
3739import Yoga.Theme.Styles (makeStylesJSS, useTheme)
@@ -69,11 +71,80 @@ translate (x /\ y) { top, right, bottom, left, width, height } =
6971 , height
7072 }
7173
72−swap ∷ ∀ a. Int -> Int -> Array a -> Maybe (Array a)
73−swap i j arr = do
74− valueI <- arr !! i
75− valueJ <- arr !! j
76− pure $ (set (ix i) valueJ <<< set (ix j) valueI) arr
74+orDie msg =
75+ fromMaybe'
76+ (\_ -> unsafeCrashWith msg)
77+
78+idxOrThrow ∷ ∀ a. Array a -> Int -> a
79+idxOrThrow arr i = arr !! i # orDie (Interp.i "Invalid index " i " in array")
80+
81+infixl 8 idxOrThrow as !!!
82+
83+swap ∷ ∀ a. Int -> Int -> Array a -> Array a
84+swap i j arr = swapped # orDie "Couldn't swap"
85+ where
86+ swapped = do
87+ valueI <- arr !! i
88+ valueJ <- arr !! j
89+ pure $ (set (ix i) valueJ <<< set (ix j) valueI) arr
90+
91+springsteen init rectsRef positionsRef arg mx my down springs = do
92+ init
93+ rects <- readRef rectsRef
94+ positionsBefore <- readRef positionsRef
95+ let
96+ rectDragged = rects !!! (positionsBefore !!! arg)
97+ currentPosDragged = rectDragged # translate (mx /\ my)
98+ orderedRectsBefore = positionsBefore <#> (rects !!! _)
99+ overlapsOtherBefore = orderedRectsBefore # findWithIndex \i rect -> i /= arg && overlaps currentPosDragged rect
100+ case down, overlapsOtherBefore of
101+ false, Just { index } -> do
102+ let
103+ newPositions = swap arg index positionsBefore
104+ writeRef positionsRef $ spy "new posis" newPositions
105+ _, _ -> mempty
106+ -- alles gut bis hierher, glaube ich
107+ positions <- readRef positionsRef
108+ springs.set \i -> do
109+ let
110+ j = positions !!! i
111+ isTheDraggedOne = i == arg
112+ originalRect = rects !!! i
113+ currentRect = rects !!! j
114+ leftOffset = currentRect.left - originalRect.left
115+ topOffset = currentRect.top - originalRect.top
116+ case isTheDraggedOne, down, overlapsOtherBefore of
117+ true, true, _ ->
118+ { x: mx + leftOffset
119+ , y: my + topOffset
120+ , zIndex: 1
121+ , transform: "scale3d(1.1, 1.1, 1.1)"
122+ , borderRadius: "var(--s-2)"
123+ , height: "100px"
124+ , shadow: 20
125+ , immediate: \n -> n == "x" || n == "y" || n == "zIndex"
126+ }
127+ false, true, Just { index, value }
128+ | index == i ->
129+ { x: rectDragged.left - currentRect.left + leftOffset
130+ , y: rectDragged.top - currentRect.top + topOffset
131+ , zIndex: 0
132+ , shadow: 2
133+ , height: "100px"
134+ , transform: "scale3d(1.0, 1.0, 1.0)"
135+ , borderRadius: "var(--s-2)"
136+ , immediate: const false
137+ }
138+ _, _, _ ->
139+ { x: leftOffset
140+ , y: topOffset
141+ , shadow: 2
142+ , height: "100px"
143+ , borderRadius: "var(--s-2)"
144+ , zIndex: 0
145+ , transform: "scale3d(1.0, 1.0, 1.0)"
146+ , immediate: const false
147+ }
77148
78149makeComponent ∷ Effect (ReactComponent Props)
79150makeComponent = do
@@ -90,95 +161,45 @@ makeComponent = do
90161 , shadow: 2
91162 , borderRadius: "var(--s-2)"
92163 , zIndex: 0
93− , immediate: const false
164+ , immediate: const true
94165 , transform: "scale3d(1.0,1.0,1.0)"
95166 }
96− springs <-
97− useSprings (Array.length props.spells) defaultSprings
98− nodeRefs <- useRef (props.spells $> Nullable.null)
99− positionsRef <- useRef ([] ∷ _ DOMRect)
100− originalPositionsRef <- useRef ([] ∷ _ DOMRect)
167+ springs <- useSprings (Array.length props.spells) defaultSprings
168+ nodeRefs ∷ Ref (Array (Nullable (_))) <- useRef (props.spells $> Nullable.null)
169+ spells /\ updateSpells <- useState props.spells
170+ positionsRef <- useRef ([] ∷ _ Int)
171+ rectsRef <- useRef ([] ∷ _ DOMRect)
101172 initialisedRef <- useRef false
102173 windowSize <- useResize
103174 let
104175 init = do
105176 initialised <- readRef initialisedRef
106177 unless initialised do
107− rects <- getRects nodeRefs
108− writeRef positionsRef (rects <#> fromMaybe emptyDomRect)
109− writeRef originalPositionsRef (rects <#> fromMaybe emptyDomRect)
178+ log "initialising"
179+ refs <- getRects nodeRefs
180+ positions <- readRef positionsRef
181+ writeRef positionsRef (0 .. (length props.spells - 1))
182+ let
183+ rects = refs <#> fromMaybe emptyDomRect
184+ writeRef rectsRef rects
110185 writeRef initialisedRef true
111186 useLayoutEffect windowSize do
112− springs.stop
113− writeRef initialisedRef false
114187 springs.set defaultSprings
188+ positionsBefore <- readRef positionsRef
189+ when (positionsBefore == []) do
190+ log "resetting positions"
191+ writeRef positionsRef (0 .. (length props.spells - 1))
192+ positions <- readRef positionsRef
193+ updateSpells (const $ positions <#> (spells !!! _))
194+ nodes <- readRef nodeRefs
195+ writeRef nodeRefs (positions <#> (nodes !!! _))
196+ writeRef initialisedRef false
197+ init
115198 mempty
116199 theme ∷ CSSTheme <- useTheme
117200 bindDragProps <-
118− useDrag (justifill { filterTaps: true }) \{ arg, down, movement: mx /\ my } -> do
119− init
120− originalPositions <- readRef originalPositionsRef
121− positionsBefore <- readRef positionsRef
122− let
123− originalPosDraggedBefore = positionsBefore !! arg ?|| emptyDomRect
124−
125− currentPosDraggedBefore = originalPosDraggedBefore # translate (mx /\ my)
126−
127− overlapsOtherBefore = positionsBefore # findWithIndex \i' pos -> i' /= arg && overlaps currentPosDraggedBefore pos
128− case down, overlapsOtherBefore of
129− false, Just { index, value } -> do
130− let
131− swapped = swap arg index positionsBefore ?|| positionsBefore
132− writeRef positionsRef swapped
133− _, _ -> mempty
134− positions <- readRef positionsRef
135− let
136− originalPosDragged = positions !! arg ?|| emptyDomRect
137−
138− currentPosDragged = originalPosDragged # translate (mx /\ my)
139−
140− overlapsOther = positions # findWithIndex \i' pos -> i' /= arg && overlaps currentPosDragged pos
141− springs.set \i -> do
142− let
143− iPos = positions !! i ?|| emptyDomRect
144−
145− origIPos = originalPositions !! i ?|| emptyDomRect
146−
147− leftOffset = if iPos == origIPos then 0.0 else iPos.left - origIPos.left
148−
149− topOffset = if iPos == origIPos then 0.0 else iPos.top - origIPos.top
150− case i == arg, down, overlapsOther of
151− false, true, Just { index, value }
152− | index == i ->
153− { x: originalPosDragged.left - value.left + leftOffset
154− , y: originalPosDragged.top - value.top + topOffset
155− , zIndex: 0
156− , shadow: 2
157− , height: "100px"
158− , transform: "scale3d(1.0, 1.0, 1.0)"
159− , borderRadius: "var(--s-2)"
160− , immediate: const false
161− }
162− true, true, _ ->
163− { x: mx + leftOffset
164− , y: my + topOffset
165− , zIndex: 1
166− , transform: "scale3d(1.1, 1.1, 1.1)"
167− , borderRadius: "var(--s-2)"
168− , height: "100px"
169− , shadow: 20
170− , immediate: \n -> n == "x" || n == "y" || n == "zIndex"
171− }
172− _, _, _ ->
173− { x: leftOffset
174− , y: topOffset
175− , shadow: 2
176− , height: "100px"
177− , borderRadius: "var(--s-2)"
178− , zIndex: 0
179− , transform: "scale3d(1.0, 1.0, 1.0)"
180− , immediate: const false
181− }
201+ useDrag (justifill { filterTaps: true }) \{ arg, down, movement: mx /\ my } ->
202+ springsteen init rectsRef positionsRef arg mx my down springs
182203 let
183204 renderSpells =
184205 mapWithIndex \i (spell /\ style) ->
@@ -196,7 +217,7 @@ makeComponent = do
196217 `withDragProps`
197218 bindDragProps i
198219 pure
199− $ jsx grid {} (renderSpells (props.spells `zip` springs.styles))
220+ $ jsx grid {} (renderSpells (spells `zip` springs.styles))
200221
201222foreign import unsafeArraySetAt ∷ ∀ a. Int -> a -> Array a -> Array a
202223