【发布时间】:2019-09-22 21:36:41
【问题描述】:
我正在使用 Elm 0.19 和 joakin/elm-canvas 包。
我要做的只是绘制一个横跨屏幕整个宽度和高度的画布,并随着窗口大小的变化动态调整大小。我花了几个小时调试和研究,但我只是卡住了。我已经尝试了多种实现,我可以让它工作,但不是在初始页面加载时。相反,它仅在调用更新函数后呈现。我觉得我遗漏了一些明显的东西,因为我对 Elm 还是很陌生。
这是显示问题的有效 Ellie 代码/演示的链接:https://ellie-app.com/6JZDxnQWPLSa1 注意在按键事件触发更新之前屏幕是空白的,然后画布出现。
编辑:添加来自 Ellie 演示的代码。
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 ]
]
]
【问题讨论】:
-
好点。我附上了我链接的 Ellie 演示中的代码。
-
谢谢。不过有趣的问题。我看起来像 joakin/elm-canvas 中的错误。我建议将
screen设为Maybe,而不是最初使用任意值。这最初解决了这个问题,但是当你调整大小时它会再次清除屏幕。当屏幕调整大小时,它可能会强制重新渲染它,但这会增加一些混乱。我建议改为在 github repo 上打开一个问题。
标签: html5-canvas elm