dominikh/go-js-dom

v2: unable to DrawImage

bergwerf opened this issue · 3 comments

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.

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).

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)

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.