This is an API design issue.
The fillStyle
property of CanvasRenderingContext2D
interface can be assigned any of 3 different types, according to https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle:
However, CanvasRenderingContext2D.FillStyle
field is defined as a string
:
|
FillStyle string `js:"fillStyle"` |
So the following code will fail to compile:
gradient := ctx.CreateRadialGradient(0, 0, 8*1.75, 0, 0, 0)
gradient.AddColorStop(0, "rgba(0, 0, 0, 0)")
gradient.AddColorStop(1, "rgba(0, 0, 0, 0.3)")
ctx.FillStyle = gradient
cannot use gradient (variable of type *honnef.co/go/js/dom.CanvasGradient) as string value in assignment
I can think of some solutions, but I'm not sure which one we should pick. They all have trade-offs.
Possible solution 1
Don't do anything special. Let users do use *js.Object
API:
ctx.Set("fillStyle", gradient)
This works, but perhaps it's not as nice as one could wish for.
(I'm using this as my current workaround.)
Possible solution 2
One potential solution is to change FillStyle
type to interface{}
:
FillStyle interface{} `js:"fillStyle"` // Can be assigned one of string, *CanvasGradient, *CanvasPattern.
Then all these are possible:
ctx.FillStyle = "rgb(255, 0, 0)"
ctx.FillStyle = gradient
ctx.FillStyle = pattern
This works, but interface{}
isn't great for APIs. Any other type can be assigned too, and when querying the value of FillStyle
, you get an interface{}
which isn't nice either.
Possible solution 3
Define 3 fields of 3 different types, all mapping to JS property fillStyle
:
FillStyle string `js:"fillStyle"`
FillStyleGradient *CanvasGradient `js:"fillStyle"`
FillStylePattern *CanvasPattern `js:"fillStyle"`
Then all these are possible:
ctx.FillStyle = "rgb(255, 0, 0)"
ctx.FillStyleGradient = gradient
ctx.FillStylePattern = pattern
This works, but now there are 3 fields for one field... Which may be confusing and creates bloat.
/cc @luckcolors FYI, in case you have ideas on this.