Я использую Elm 0.19 и пакет joakin / elm-canvas .
Все, что я пытаюсь сделать, это нарисовать холст, который охватывает всю ширину и высотуэкран и динамически изменяет размеры при изменении размера окна.Я потратил несколько часов на отладку и исследование, но я просто застрял.Я пробовал несколько реализаций, и я могу заставить его работать, но не при начальной загрузке страницы.Вместо этого он рендерится только после вызова функции update.Я чувствую, что упускаю что-то очевидное, поскольку я все еще очень плохо знаком с Elm.
Вот ссылка на рабочий код / демонстрацию Элли, показывающая проблему: https://ellie -app.com/ 6JZDxnQWPLSa1 Обратите внимание на то, что экран пуст, пока после нажатия клавиши не произойдет обновление, а затем не появится холст.
Редактировать: добавление кода из демонстрации Элли.
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 ]
]
]