This commit is contained in:
Mark Eibes 2020-05-12 22:56:44 +02:00
parent fd4a42d47f
commit 7e0bbefd01
3 changed files with 57 additions and 21 deletions

View File

@ -21,10 +21,22 @@ import Yoga.Helpers ((?||))
foreign import data UseDrag ∷ Type -> Type -> Type
type DragHandler a
= { arg ∷ a, down ∷ Boolean, movement ∷ Number /\ Number, xy ∷ Number /\ Number } -> Effect Unit
= { arg ∷ a
, down ∷ Boolean
, movement ∷ Number /\ Number
, xy ∷ Number /\ Number
, tap ∷ Boolean
} ->
Effect Unit
type DragHandlerImpl a
= { args ∷ Array a, down ∷ Boolean, movement ∷ Array Number, xy ∷ Array Number } -> Unit
= { args ∷ Array a
, down ∷ Boolean
, movement ∷ Array Number
, xy ∷ Array Number
, tap ∷ Boolean
} ->
Unit
type DragProps
= { onMouseDown ∷ EventHandler, onTouchStart ∷ EventHandler }
@ -52,7 +64,7 @@ useDrag dragOptions dragHandler = unsafeHook (runEffectFn2 useDragImpl dragHandl
dragHandlerImpl ∷ DragHandlerImpl a
dragHandlerImpl x =
(unsafePerformEffect <<< dragHandler)
{ arg, down: x.down, movement: mx /\ my, xy: xyX /\ xyY
{ arg, down: x.down, tap: x.tap, movement: mx /\ my, xy: xyX /\ xyY
}
where
arg = x.args !! 0 # fromMaybe' (\_ -> unsafeCrashWith "Bollox")

View File

@ -12,8 +12,8 @@ import React.Basic.Hooks (Hook, UseLayoutEffect, UseRef, UseState, coerceHook, r
import React.Basic.Hooks as React
import Unsafe.Coerce (unsafeCoerce)
import Web.DOM (Node)
import Web.DOM.Element (clientHeight)
import Web.HTML (HTMLElement, window)
import Web.DOM.Element (clientHeight, clientWidth)
import Web.HTML (window)
import Web.HTML.HTMLDocument as Document
import Web.HTML.HTMLElement (DOMRect, focus, getBoundingClientRect)
import Web.HTML.HTMLElement as HTMLElement
@ -63,6 +63,26 @@ useViewportHeight =
pure (pure unit)
pure viewportHeight
newtype UseViewportWidth hooks
= UseViewportWidth (UseLayoutEffect Unit (UseState (Maybe Number) hooks))
derive instance ntUseViewportWidth ∷ Newtype (UseViewportWidth hooks) _
useViewportWidth ∷ Hook UseViewportWidth (Maybe Number)
useViewportWidth =
coerceHook React.do
viewportWidth /\ modifyViewportWidth <- useState Nothing
useLayoutEffect unit do
doc <- window >>= document
let
maybeElem = Document.toNode doc # HTMLElement.fromNode
case maybeElem of
Nothing -> pure unit
Just elem -> do
ch <- clientWidth (HTMLElement.toElement elem)
modifyViewportWidth (const $ Just ch)
pure (pure unit)
pure viewportWidth
newtype UseFocus hooks
= UseFocus (UseLayoutEffect Unit (UseRef (Nullable Node) (UseState Boolean hooks)))

View File

@ -91,6 +91,8 @@ regularScale = "scale3d(1.0, 1.0, 1.0)"
scaledUp = "scale3d(1.1, 1.1, 1.1)"
scaledCompletely = "scale3d(2.0, 2.0, 2.0)"
defaultSprings =
{ x: 0.0
, y: 0.0
@ -100,7 +102,7 @@ defaultSprings =
, transform: "scale3d(1.0,1.0,1.0)"
}
springsteen init rectsRef positionsRef arg mx my down springs = do
springsteen init windowSize rectsRef positionsRef arg mx my down tap springs = do
init
rects <- readRef rectsRef
positionsBefore <- readRef positionsRef
@ -122,24 +124,25 @@ springsteen init rectsRef positionsRef arg mx my down springs = do
currentRect = rects !!! (positions !!! i)
leftOffset = currentRect.left - originalRect.left
topOffset = currentRect.top - originalRect.top
case i == arg, down, overlapsOther of
true, true, _ ->
defaultSprings
{ x = mx + leftOffset
, y = my + topOffset
, zIndex = 1
, transform = scaledUp
, shadow = 20
, immediate = \n -> n == "x" || n == "y" || n == "zIndex"
}
false, true, Just { index, value }
case down, overlapsOther of
true, _
| i == arg ->
defaultSprings
{ x = mx + leftOffset
, y = my + topOffset
, zIndex = 1
, transform = scaledUp
, shadow = 20
, immediate = \n -> n == "x" || n == "y" || n == "zIndex"
}
true, Just { index, value }
| index == i ->
defaultSprings
{ x = rectDragged.left - currentRect.left + leftOffset
, y = rectDragged.top - currentRect.top + topOffset
, immediate = const false
}
_, _, _ ->
_, _ ->
defaultSprings
{ x = leftOffset
, y = topOffset
@ -187,8 +190,8 @@ makeComponent = do
mempty
theme ∷ CSSTheme <- useTheme
bindDragProps <-
useDrag (justifill { filterTaps: true }) \{ arg, down, movement: mx /\ my } ->
springsteen init rectsRef positionsRef arg mx my down springs
useDrag (justifill { filterTaps: true }) \{ arg, down, movement: mx /\ my, tap } ->
springsteen init windowSize rectsRef positionsRef arg mx my down tap springs
let
renderSpells =
mapWithIndex \i (spell /\ style) ->
@ -205,7 +208,8 @@ makeComponent = do
`withDragProps`
bindDragProps i
pure
$ jsx grid {} (renderSpells (spells `zip` springs.styles))
$ jsx grid {}
$ renderSpells (spells `zip` springs.styles)
foreign import unsafeArraySetAt ∷ ∀ a. Int -> a -> Array a -> Array a