Skip to content

Canvas

How to draw on a canvas.Canvas from the server with a 2D context: a rectangle with a shadow and an image which follow the pointer.

Canvas

package main

import (
	"context"
	_ "embed"
	"fmt"

	"go.wdy.de/nago/application"
	"go.wdy.de/nago/presentation/core"
	"go.wdy.de/nago/presentation/ui"
	"go.wdy.de/nago/presentation/ui/canvas"
	"go.wdy.de/nago/web/vuejs"
)

//go:embed morty_vanilla.png
var morty application.StaticBytes

func main() {
	application.Configure(func(cfg *application.Configurator) {
		cfg.SetApplicationID("de.worldiety.tutorial_93")
		cfg.Serve(vuejs.Dist())

		mortyUrl := cfg.Resource(morty)

		cfg.RootView(".", func(wnd core.Window) core.View {
			const myCanvas = "."
			const fps = 30

			canvasCtx := canvas.Context2D(wnd, myCanvas)
			var evt core.InputEvent
			wnd.AddInputListener(myCanvas, func(e core.InputEvent) {
				fmt.Println(e)
				evt = e
				canvasCtx.LoadImage(1, mortyUrl)
				redraw(canvasCtx, evt)
			},
				core.InputEventInvalidate,
				core.InputEventPointerDown,
				core.InputEventPointerMove,
				core.InputEventPointerUp,

				// destroy option, reset is default
				core.DestroyOnReset,
			)

			core.OnFrame(wnd, myCanvas, fps, func(ctx context.Context) {
				//redraw(canvasCtx, evt)
			})

			return ui.VStack(
				canvas.Canvas(myCanvas).Frame(ui.Frame{Width: ui.L400, Height: ui.L320}),
			).Frame(ui.Frame{}.MatchScreen())
		})

	}).Run()
}

func redraw(ctx canvas.TContext2D, evt core.InputEvent) {
	ctx.NewList(1)
	ctx.ShadowOffsetX(10)
	ctx.ShadowOffsetY(10)
	ctx.ShadowColor("#0000ff")
	ctx.ShadowBlur(5)

	ctx.FillColor("#ff0000")
	ctx.FillRect(evt.X, evt.Y, 100, 100)
	ctx.DrawImage(1, evt.X, evt.Y)
	ctx.EndList()

	// check nested list calls
	ctx.NewList(2)
	ctx.ClearRect(0, 0, 1000, 1000)
	ctx.CallList(1)
	ctx.EndList()

	// actually call the list to render outside of any list
	ctx.CallList(2)
}

View on GitHub ↗ · run it with go run go.wdy.de/nago/example/cmd/tutorial-93-canvas@latest