dominikh / go-js-dom

MIT License
252 stars 42 forks source link

v2: unable to DrawImage #78

Closed bergwerf closed 1 year ago

bergwerf commented 4 years ago

This is my code:

// +build js

package main

import (
    "time"

    dom "honnef.co/go/js/dom/v2"
)

var window = dom.GetWindow()
var qs = window.Document().QuerySelector
var canvas *dom.HTMLCanvasElement
var ctx *dom.CanvasRenderingContext2D
var lock = false
var currentPuzzle *Puzzle

// Puzzle contains all information about one puzzle and its state
type Puzzle struct {
    image *dom.HTMLImageElement
}

func main() {
    canvas = qs("#screen").(*dom.HTMLCanvasElement)
    ctx = canvas.GetContext2d()

    loadImage("assets/puzzles/niagara.jpg", func(img *dom.HTMLImageElement) {
        currentPuzzle = &Puzzle{img}
        redraw()
    })

    window.AddEventListener("resize", false, func(e dom.Event) { resize() })
    resize()
}

func resize() {
    rect := qs("#container").GetBoundingClientRect()
    canvas.SetWidth(int(rect.Width()))
    canvas.SetHeight(int(rect.Height()))
    redraw()
}

func draw(t time.Duration, puzzle *Puzzle) {
    ctx.SetFillStyle("#f00")
    ctx.FillRect(0, 0, 100, 100)
    if puzzle != nil {
        ctx.DrawImage(puzzle.image, 0, 0)
    }
}

func redraw() {
    if !lock {
        lock = true
        window.RequestAnimationFrame(func(d time.Duration) {
            lock = false
            draw(d, currentPuzzle)
        })
    }
}

func loadImage(src string, callback func(img *dom.HTMLImageElement)) {
    img := window.Document().CreateElement("img").(*dom.HTMLImageElement)
    img.AddEventListener("load", false, func(e dom.Event) { callback(img) })
    img.SetSrc(src)
}

On Firefox it gives me: Error: invalid arg: *dom.HTMLImageElement with the stack trace pointing to convertArgs js.go:174.

bergwerf commented 4 years ago

There was #48, but did anyone produce a test afterwards? If there is an example of DrawImage somehow working, I would be happy to use it to make mine work (as far as I understand what I am doing is legitimate).

bergwerf commented 4 years ago

It turns out that ValueOf in js.go doesn't manage to extract the underlying js.Value. Confusingly the stack trace points to different method names and line numbers than are actually in the syscall/js/js.go in my GOROOT (this contains a makeArgs while the stack trace is talking about a convertArgs, something gets mixed up but I couldn't find out what).

Anyway, we can help js.go a bit:

ctx.Call("drawImage", image.Underlying(), dx, dy)
dmitshur commented 4 years ago

Thanks for reporting.

There was #48, but did anyone produce a test afterwards?

That was the v1 API, which used the GopherJS js package. I suspect this issue affects the v2 API only, which uses syscall/js and is more strict.

Also see #71. I think we need to apply the same fix in more places, including DrawImage.