Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fullscreen, resizable canvas – not visible on page load #10

Open
toakleaf opened this issue Sep 22, 2019 · 4 comments
Open

Fullscreen, resizable canvas – not visible on page load #10

toakleaf opened this issue Sep 22, 2019 · 4 comments

Comments

@toakleaf
Copy link

I'm trying to draw a canvas that spans the entire width and height of the window and resizes dynamically when the window size changes. However, the canvas isn't getting painted on the initial page load, but only on subsequent updates. I've tried multiple implementations but the same problem keeps recurring.

Here's an Ellie showing the issue. Notice how the screen is blank until after a keypress event fires the update, and then the canvas appears.

As a work-around, I can change the screen record into a Maybe, however that just shifts the problem from occurring on initial screen load to on resize.

And just for the sake of good record-keeping here's the code from the Ellie linked above:

module Main exposing (..)

import Browser
import Browser.Dom exposing (Viewport, getViewport)
import Browser.Events exposing (onKeyDown, onResize)
import Canvas exposing (..)
import Canvas.Settings exposing (..)
import Canvas.Settings.Advanced exposing (..)
import Color
import Html exposing (Html, div)
import Html.Attributes exposing (style)
import Json.Decode as Decode
import Task


main : Program () Model Msg
main =
    Browser.element
        { init = init
        , view = view
        , subscriptions = subscriptions
        , update = update
        }


-- MODEL


type alias Model =
    { screen : { width : Int, height : Int }
    }


init : () -> ( Model, Cmd Msg )
init _ =
    ( { screen = { width = 800, height = 600 }
      }
    , Task.perform (\{ viewport } -> ScreenSize (round viewport.width) (round viewport.height)) getViewport
    )


-- UPDATE


type Msg
    = TurnLeft
    | TurnRight
    | MoveForward
    | Other
    | ScreenSize Int Int


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        TurnLeft ->
            ( model, Cmd.none )

        TurnRight ->
            ( model, Cmd.none )

        MoveForward ->
            ( model, Cmd.none )

        ScreenSize w h ->
            ( { model | screen = { width = w, height = h } }
            , Cmd.none
            )

        Other ->
            ( model, Cmd.none )


-- SUBSCRIPTIONS


subscriptions : Model -> Sub Msg
subscriptions model =
    Sub.batch
        [ onKeyDown keyDecoder
        , onResize ScreenSize
        ]


keyDecoder : Decode.Decoder Msg
keyDecoder =
    Decode.map toDirection (Decode.field "key" Decode.string)


toDirection : String -> Msg
toDirection string =
    case string of
        "ArrowLeft" ->
            TurnLeft

        "ArrowRight" ->
            TurnRight

        "ArrowUp" ->
            MoveForward

        _ ->
            Other


-- VIEW


clearScreen : Float -> Float -> Renderable
clearScreen width height =
    shapes [ fill Color.black ] [ rect ( 0, 0 ) width height ]


view : Model -> Html Msg
view { screen } =
    div
        [ style "display" "flex"
        , style "justify-content" "center"
        , style "align-items" "center"
        ]
        [ Canvas.toHtml
            ( screen.width, screen.height )
            []
            [ clearScreen (toFloat screen.width) (toFloat screen.height)
              , shapes [ fill Color.red ] [ rect ( 30, 30 ) 200 200 ]
            ]
        ]

@joakin
Copy link
Owner

joakin commented Sep 23, 2019

Very strange!

This would be a great feature to add to the Fullscreen.elm example once we figure it out.

I’m in the move and checked the Ellie on the phone, and what I see is multiple resize events being triggered with the size increasing each time. I see the canvas flicker black and red to white to finally nothing.

Do you see multiple resize events too? If you do it may be that changing the canvas dimensions is re-triggering a resize event for some reason.

@joakin
Copy link
Owner

joakin commented Sep 23, 2019

I have a game example that does full screen and resizes and doesn’t seem to have a problem: https://github.com/joakin/elm-basic-platformer-game/blob/master/src/Main.elm

The setup seems very similar, so I’m not sure what may be going wrong.

@toakleaf
Copy link
Author

In the Ellie debugger, I only see singular updates to the Model when resizing screen by a single pixel. However, you're correct that it does seem like the canvas gets drawn every time and then erased, as it flashes on screen before going white. I have a pretty busy day, but if I can find the time I'll try making a copy of your game and pairing it back to just a blank canvas to see if I can spot the problem.

@toakleaf
Copy link
Author

Also, I feel like maybe the animation in the game example, much like firing off keypresses in mine, is somehow masking the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants