maxence-charriere / go-app

A package to build progressive web apps with Go programming language and WebAssembly.

Home Page:https://go-app.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Load static files to Canvas

riprsa opened this issue · comments

First of all, thank you for this package. It is soo cool that I can write Go code for browsers!

I am writing a simple bullet-hell game. I almost finished basic logic and now want to add textures. However, I do not understand how to add an image to Canvas.

I have a variable of type app.HTMLImg, which is initialised with image := app.Img().Src("/web/assets/rat.png"). I tried to render only the image as a separate component and it works, so issue is not with an empty variable. Also I can locate it by path through address bar.

I cannot figure out how to use this image variable with context2D.Call("drawImage", image, 0, 0). I also tried to use image.JSValue(), but it did not help. I get this error:

panic: JavaScript error: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLCanvasElement or HTMLImageElement or HTMLVideoElement or ImageBitmap or OffscreenCanvas or SVGImageElement or VideoFrame)'.

I have no idea how to correctly get drawImage to work.

	cvEl := app.Window().GetElementByID(c.Id)
	cvCtx := cvEl.Call("getContext", "2d")
	c.done = make(chan struct{})
	img := app.Window().Get("document").Call("createElement", "img")
	img.Set("src", "/web/logo-512.png")
	//app.Window().Get("document").Get("body").Call("appendChild", img)
	img.Call("addEventListener", "load", app.FuncOf(func(app.Value, []app.Value) interface{} {
		dbg.Log("image is loaded")
		ctx.Async(func() {
			var renderFrame app.Func
			c.running = true
			renderFrame = app.FuncOf(func(this app.Value, args []app.Value) interface{} {
				if c.running {
					app.Window().Call("requestAnimationFrame", renderFrame)
				} else {
					close(c.done)
				}
				cvCtx.Call("drawImage", img, 0, 0)
				return nil
			})
			defer renderFrame.Release()
			// start the rendering
			app.Window().Call("requestAnimationFrame", renderFrame)
			// wait till the channel gets closed
			<-c.done
			dbg.Log("closed")
		})
		return nil
	}))

Works like a charm, thank you!