我正在使用GoLang和WASM,实际上我想通过在HTML画布上绘制一个棋盘来编写类似“ Hello,World”的示例。
我将fillStyle
和strokeStyle
设置为'red'
,并将lineWidth
设置为5
。直到我调整窗口大小并重置我的值之前,它都会起作用。
我通过反复试验发现,如果在调用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
}
每次都明确设置这些值并不是一件大事,但是我的问题是为什么会这样?这是应该发生的事情吗(例如:这些副作用是否在我尚未见过的地方得到了记录),或者我正在做的事情组合 会导致这些意想不到的副作用(如果那么,我该如何纠正自己,以免出现更多怪异的副作用?