调整大小后,为什么我的HTML Canvas绘图样式会被重置?

时间:2019-10-07 21:19:15

标签: go canvas html5-canvas webassembly

我正在使用GoLang和WASM,实际上我想通过在HTML画布上绘制一个棋盘来编写类似“ Hello,World”的示例。

我将fillStylestrokeStyle设置为'red',并将lineWidth设置为5。直到我调整窗口大小并重置我的值之前,它都会起作用。

Correctly drawing to canvas No longer drawing to canvas

我通过反复试验发现,如果在调用clearRect之后设置样式,它将按预期运行。从我读过的from MDN来看,您只需要担心使用路径。我只是在绘制填充和描边矩形,所以这不应该成为问题。

这没有意义,但这可以通过在每次迭代中设置样式来实现(请注意canvasCtx.Set调用在循环内的位置):

func main() {
    runForever := make(chan bool)
    window := js.Global()
    canvas := window.Get("document").Call("getElementById", "canvas")
    window.Call("addEventListener", "resize", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        width, height := updateCanvasSize(window, canvas)
        fmt.Printf("resize triggered: %f x %f\n", width, height)
        return nil
    }))
    _, _ = updateCanvasSize(window, canvas)

    canvasCtx := canvas.Call("getContext", "2d")

    var renderer js.Func
    renderer = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        width, height := getWindowInnerSize(window)
        canvasCtx.Call("clearRect", 0, 0, width, height)
        fmt.Printf("Rendering with: Canvas Size %fx%f  fillStyle=%s strokeStyle%s lineWidth=%f\n",
            width, height,
            canvasCtx.Get("fillStyle").String(),
            canvasCtx.Get("strokeStyle").String(),
            canvasCtx.Get("lineWidth").Float(),
        )
        canvasCtx.Set("fillStyle", "red")
        canvasCtx.Set("strokeStyle", "red")
        canvasCtx.Set("lineWidth", 5)

        squareWidth := width / 8
        squareHeight := height / 8
        offsetWidth := squareWidth * 0.15
        offsetHeight := squareHeight * 0.15
        for i := 0; i < 8; i++ {
            for j := 0; j < 8; j++ {
                if (i+j)%2 == 0 {
                    canvasCtx.Call("strokeRect", float64(i)*squareWidth+offsetWidth, float64(j)*squareHeight+offsetHeight,
                        squareWidth-(2*offsetWidth), squareHeight-(2*offsetHeight))
                } else {
                    canvasCtx.Call("fillRect", float64(i)*squareWidth, float64(j)*squareHeight, squareWidth, squareHeight)
                }
            }
        }
        window.Call("requestAnimationFrame", renderer)
        return nil
    })
    window.Call("requestAnimationFrame", renderer)

    <-runForever
}

但是将画布值设置为预先设置而不是每次迭代都无效:

package main

import (
    "fmt"
    "syscall/js"
)

func main() {
    runForever := make(chan bool)
    window := js.Global()
    canvas := window.Get("document").Call("getElementById", "canvas")
    window.Call("addEventListener", "resize", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        width, height := updateCanvasSize(window, canvas)
        fmt.Printf("resize triggered: %f x %f\n", width, height)
        return nil
    }))
    _, _ = updateCanvasSize(window, canvas)

    canvasCtx := canvas.Call("getContext", "2d")
    canvasCtx.Set("fillStyle", "red")
    canvasCtx.Set("strokeStyle", "red")
    canvasCtx.Set("lineWidth", 5)

    var renderer js.Func
    renderer = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        width, height := getWindowInnerSize(window)
        canvasCtx.Call("clearRect", 0, 0, width, height)
        fmt.Printf("Rendering with: Canvas Size %fx%f  fillStyle=%s strokeStyle%s lineWidth=%f\n",
            width, height,
            canvasCtx.Get("fillStyle").String(),
            canvasCtx.Get("strokeStyle").String(),
            canvasCtx.Get("lineWidth").Float(),
        )
        squareWidth := width / 8
        squareHeight := height / 8
        offsetWidth := squareWidth * 0.15
        offsetHeight := squareHeight * 0.15
        for i := 0; i < 8; i++ {
            for j := 0; j < 8; j++ {
                if (i+j)%2 == 0 {
                    canvasCtx.Call("strokeRect", float64(i)*squareWidth+offsetWidth, float64(j)*squareHeight+offsetHeight,
                        squareWidth-(2*offsetWidth), squareHeight-(2*offsetHeight))
                } else {
                    canvasCtx.Call("fillRect", float64(i)*squareWidth, float64(j)*squareHeight, squareWidth, squareHeight)
                }
            }
        }
        window.Call("requestAnimationFrame", renderer)
        return nil
    })
    window.Call("requestAnimationFrame", renderer)

    <-runForever
}

func getWindowInnerSize(window js.Value) (float64, float64) {
    width := window.Get("innerWidth").Float()
    height := window.Get("innerHeight").Float()
    return width, height
}

func updateCanvasSize(window js.Value, canvas js.Value) (float64, float64) {
    width, height := getWindowInnerSize(window)
    canvas.Set("width", width)
    canvas.Set("height", height)
    return width, height
}

每次都明确设置这些值并不是一件大事,但是我的问题是为什么会这样?这是应该发生的事情吗(例如:这些副作用是否在我尚未见过的地方得到了记录),或者我正在做的事情组合 会导致这些意想不到的副作用(如果那么,我该如何纠正自己,以免出现更多怪异的副作用?

0 个答案:

没有答案