Add a ghost held tile
This commit is contained in:
parent
373f6eeddc
commit
5c9a98df73
80
src/Main.elm
80
src/Main.elm
|
@ -8,10 +8,11 @@ import Array.Extra as Array
|
|||
import Browser
|
||||
import Browser.Dom exposing (focus, getViewport, Viewport)
|
||||
import Browser.Navigation exposing (Key)
|
||||
import Browser.Events exposing (onResize)
|
||||
import Browser.Events exposing (onMouseMove, onResize)
|
||||
import Html exposing (Attribute, button, div, h3, input, Html, section, text)
|
||||
import Html.Attributes exposing (class, id, style, value)
|
||||
import Html.Attributes.Extra as Attributes exposing (attributeIf)
|
||||
import Html.Extra exposing (viewMaybe)
|
||||
import Html.Events exposing (onBlur, onClick, onInput, onMouseEnter)
|
||||
import Json.Decode as D
|
||||
import List exposing (map, singleton)
|
||||
|
@ -30,7 +31,7 @@ main = Browser.application
|
|||
, update = update
|
||||
, onUrlChange = constant Noop
|
||||
, onUrlRequest = constant Noop
|
||||
, subscriptions = constant <| onResize WindowSize
|
||||
, subscriptions = subscriptions
|
||||
}
|
||||
|
||||
type Msg
|
||||
|
@ -41,12 +42,14 @@ type Msg
|
|||
| AddTile Int
|
||||
| TileDeselected Int
|
||||
| HeldOverNewTile Int Int
|
||||
| NewMousePos Int Int
|
||||
|
||||
type alias Model =
|
||||
{ windowW: Int
|
||||
, windowH: Int
|
||||
, columns: Array Column
|
||||
, cardDrop: Maybe (Int, Int)
|
||||
, heldTile: Maybe HeldTile
|
||||
, mousePos: (Int, Int)
|
||||
}
|
||||
|
||||
type alias Column =
|
||||
|
@ -59,6 +62,12 @@ type alias Tile =
|
|||
, stickers: List Sticker
|
||||
}
|
||||
|
||||
type alias HeldTile =
|
||||
{ hoveredColumnIndex: Int
|
||||
, hoveredTileIndex: Int
|
||||
, tile: Tile
|
||||
}
|
||||
|
||||
blankTile = { text = "", stickers = [] }
|
||||
|
||||
viewportToWindowSize : Viewport -> Msg
|
||||
|
@ -84,37 +93,64 @@ init flags url browserKey =
|
|||
}
|
||||
]
|
||||
|> Array.fromList
|
||||
, cardDrop = Just (0, 0)
|
||||
, mousePos = (200, 200)
|
||||
, heldTile = Just
|
||||
{ hoveredColumnIndex = 0
|
||||
, hoveredTileIndex = 0
|
||||
, tile = Tile "hello!" []
|
||||
}
|
||||
}
|
||||
|> withCmd (
|
||||
getViewport
|
||||
|> Task.perform viewportToWindowSize
|
||||
)
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions model = Sub.batch
|
||||
[ onResize WindowSize
|
||||
, if (isJust model.heldTile)
|
||||
then onMouseMove <|
|
||||
D.map2 NewMousePos
|
||||
(D.field "pageX" D.int)
|
||||
(D.field "pageY" D.int)
|
||||
else Sub.none
|
||||
]
|
||||
|
||||
view : Model -> Browser.Document Msg
|
||||
view {windowW, windowH, columns, cardDrop} =
|
||||
section
|
||||
view {windowW, windowH, columns, heldTile, mousePos} =
|
||||
[ section
|
||||
[ class "columns"
|
||||
]
|
||||
( Array.indexedMap (viewColumn cardDrop) columns
|
||||
( Array.indexedMap (viewColumn heldTile) columns
|
||||
|> Array.toList
|
||||
)
|
||||
|> singleton
|
||||
, viewMaybe (viewFloatyTile mousePos) heldTile
|
||||
]
|
||||
|> Browser.Document "meow!"
|
||||
|
||||
viewFloatyTile : (Int, Int) -> HeldTile -> Html Msg
|
||||
viewFloatyTile (mouseX, mouseY) { tile } =
|
||||
div
|
||||
[ style "top" (mouseY |> String.fromInt |> flip (++) "px")
|
||||
, style "left" (mouseX |> String.fromInt |> flip (++) "px")
|
||||
, id "floaty-tile"
|
||||
]
|
||||
[ viewTile False -1 -1 tile ]
|
||||
|
||||
|
||||
viewHoverTile = div [id "hover-tile"] []
|
||||
|
||||
viewColumn : Maybe (Int, Int) -> Int -> Column -> Html Msg
|
||||
viewColumn : Maybe HeldTile -> Int -> Column -> Html Msg
|
||||
viewColumn heldOverTile columnIndex {name, tiles} =
|
||||
let
|
||||
onlyTrueActivityTiles = Array.indexedMap (viewTile (isJust heldOverTile) columnIndex) tiles
|
||||
trueActivityTilesPlusHoverTile = case heldOverTile of
|
||||
Nothing -> onlyTrueActivityTiles
|
||||
Just (heldOverColumnIndx, heldOverTileIndx) ->
|
||||
if heldOverColumnIndx == columnIndex
|
||||
Just {hoveredColumnIndex, hoveredTileIndex} ->
|
||||
if hoveredColumnIndex == columnIndex
|
||||
then
|
||||
Array.insertAt
|
||||
heldOverTileIndx
|
||||
hoveredTileIndex
|
||||
viewHoverTile
|
||||
onlyTrueActivityTiles
|
||||
else onlyTrueActivityTiles
|
||||
|
@ -229,14 +265,24 @@ update msg model = case Debug.log "UPDATE" msg of
|
|||
pruneTiles
|
||||
model
|
||||
|> withoutCmd
|
||||
HeldOverNewTile columnIndex tileIndex -> case model.cardDrop of
|
||||
HeldOverNewTile columnIndex tileIndex -> case model.heldTile of
|
||||
Nothing -> model |> withoutCmd
|
||||
Just (oldColumnIndex, oldTileIndex) ->
|
||||
Just oldHeldTileInfo ->
|
||||
let
|
||||
newTileIndex =
|
||||
if oldTileIndex == tileIndex
|
||||
if oldHeldTileInfo.hoveredTileIndex == tileIndex
|
||||
then tileIndex + 1
|
||||
else tileIndex
|
||||
in
|
||||
{ model | cardDrop = Debug.log "newModel" <| Just (columnIndex, newTileIndex) }
|
||||
|> withoutCmd
|
||||
{ model
|
||||
| heldTile =
|
||||
Just
|
||||
{ oldHeldTileInfo
|
||||
| hoveredColumnIndex = columnIndex
|
||||
, hoveredTileIndex = newTileIndex
|
||||
}
|
||||
}
|
||||
|> withoutCmd
|
||||
NewMousePos x y ->
|
||||
{ model | mousePos = (x, y) }
|
||||
|> withoutCmd
|
75
style.sass
75
style.sass
|
@ -47,38 +47,55 @@ input
|
|||
height: 110px
|
||||
margin-top: -15px
|
||||
|
||||
.tile
|
||||
position: relative
|
||||
height: 80px
|
||||
width: 400px
|
||||
.tile
|
||||
position: relative
|
||||
height: 80px
|
||||
width: 400px
|
||||
|
||||
display: grid
|
||||
align-items: center
|
||||
margin-bottom: 15px
|
||||
display: grid
|
||||
align-items: center
|
||||
margin-bottom: 15px
|
||||
border: none
|
||||
|
||||
input
|
||||
padding: 20px
|
||||
margin: 0
|
||||
height: 40px
|
||||
background: none
|
||||
border: none
|
||||
text-align: center
|
||||
font-size: 2.6em
|
||||
width: 360px
|
||||
|
||||
&:focus-visible
|
||||
border: none
|
||||
|
||||
input
|
||||
padding: 20px
|
||||
margin: 0
|
||||
height: 40px
|
||||
background: none
|
||||
border: none
|
||||
text-align: center
|
||||
font-size: 2.6em
|
||||
width: 360px
|
||||
.tile-stickers
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
pointer-events: none // Allow clicking the input box below this
|
||||
|
||||
&:focus-visible
|
||||
border: none
|
||||
&.add-tile
|
||||
text-align: center
|
||||
font-weight: bold
|
||||
font-size: 80px
|
||||
color: white
|
||||
line-height: 0
|
||||
|
||||
.tile-stickers
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
pointer-events: none // Allow clicking the input box below this
|
||||
#mouse-detector
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
&.add-tile
|
||||
text-align: center
|
||||
font-weight: bold
|
||||
font-size: 80px
|
||||
color: white
|
||||
line-height: 0
|
||||
#floaty-tile
|
||||
position: absolute
|
||||
|
||||
& > .tile
|
||||
background-color: grey
|
||||
position: relative
|
||||
top: -40px
|
||||
left: -40px
|
||||
pointer-events: none
|
Loading…
Reference in New Issue