2019-01-08 23:09
浏览 99


I'm using Go and compiling it to web assembly.

I'm trying to render a bunch of rectangles next to eachother with a random colour, but they keep rendering as just gray.

My render function looks something like this:

 for row,_ := range rows {
    for col,_ := range row {
        ctx.Set("fillStyle", fmt.Sprintf("#%06x", rand.Int()))
        ctx.Call("fillRect", 20, 20 + (col * width), maxHeight - (row*height))

With which it renders a big block (all rectangles are next to eachother) but just all in gray, instead of doing them in different colours.

Is this enough code in the example to help further? If not I can post it to a gist, as I'm new to WASM I'm unsure which parts could really be relevant - but those 2 functions are the only ones doing something with rendering as far as I can tell.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • donlih2986
    donlih2986 2019-01-09 09:01

    The problem is that you use this expression to construct the fill style:

    fmt.Sprintf("#%06x", rand.Int())

    rand.Int() returns a non-negative pseudo-random int. Size of int is 64 bits if GOOS=js and GOARCH=wasm. What this means is that the random int number will be random 8 bytes (first bit being always 0 due to being non-negative).

    If you format such a number with the %06x verb, like almost all the time it will be more than just 6 hex digits. The width 6 means to be at least 6, and the flag 0 means to pad with zeros if less. But if it's longer, it is not truncated.

    And if you set an invalid color to canvas.fillStyle, it will disregard it and the last set valid fill style will remain active. And I'm guessing it was a gray color you used before the loop.

    Fix is easy, just make sure the random number has no more than 3 bytes, or in other words, 6 hex digits. Use a simple bitmask:

    ctx.Set("fillStyle", fmt.Sprintf("#%06x", rand.Int()&0xffffff))

    Or use rand.Intn() instead of rand.Int():

    ctx.Set("fillStyle", fmt.Sprintf("#%06x", rand.Int(0x1000000)))

    Also context.fillRect() expects 4 arguments: x, y, width and height, so it should be something like this:

    ctx.Call("fillRect", 20+(col*width), maxHeight-(row*height), width, height)
    点赞 评论