One possible refinement to this which would produce smaller deck sizes would be to mark the internal canvas as "volatile"; instead of saving the rendered bitmap of text, Decker would then regenerate the image at load time or the first view[] event. (This would also require you to save the pattern selection in a separate internal field.)
Thanks, I have yet to get my head around "volatile" but I will experiment. I was hesitant to try because I wasn't sure whether it would play nice with transition functions, e.g. would it only call the "view" at the end of the transition?
I will experiment and see if I can get it working, since not having images saved in the deck files is probably nicer
So I whipped up a version that uses volatiles, but it does indeed have the problem of, if you're transitioning between cards on a freshly opened deck, it doesn't draw the text in until the end of the transition, so it kind of "pops in". I've uploaded a quick example to show what I mean https://zine.milliesquilly.com/surprises/colourtextpopindemo.html
If there's something I'm missing here please let me know
Here's the new version of the contraption - I'm hestitant to replace the original since it's not a strict improvement, but if you're not using transitions or if you don't mind manually calling "view" on the contraption before the transition it does save on deck size
Edit: slightly updated version, did some experimenting and wasn't able to get manually calling "view" to work so I've exposed the redraw[] function itself. So if you want to use this version and need to refresh the contents before a transition (or whatever other fun things you're doing) you can call redraw[] on the widget to refresh it before your transition.
%%WGT0{"w":[{"name":"colourtext1","type":"contraption","size":[134,65],"pos":[145,125],"show":"transparent","def":"colourtext","widgets":{"canvas1":{"size":[134,65],"pattern":35},"field1":{"pos":[-186,154],"value":{"text":["Look at all this text, it comes in ","different fonts"," and it's red and transparent"],"font":["","menu",""],"arg":["","",""]}},"slider1":{"size":[116,25],"pos":[-52,149],"value":35}}}],"d":{"colourtext":{"name":"colourtext","size":[100,100],"resizable":1,"margin":[0,0,0,0],"description":"Like a text box, but with colour! With volatiles now. Exposes a redraw[] function if you need to refresh it manually for whatever reason.","version":1.2,"script":"on get_colour do\n slider1.value\nend\n\non set_colour x do\n slider1.value:x\n redraw[]\nend\n\non get_value do\n field1.value\nend\n\non set_value x do\n field1.value:x\n redraw[]\nend\n\non redraw do\n canvas1.clear[]\n canvas1.pattern:slider1.value\n size:canvas1.textsize[field1.value canvas1.size[0]-4]\n canvas1.text[field1.value 2,2,size]\nend\n\non view do\n redraw[]\nend\n\non get_redraw do\n redraw\nend","attributes":{"name":["value","colour"],"label":["Text","Colour (palette index)"],"type":["rich","number"]},"widgets":{"canvas1":{"type":"canvas","size":[100,100],"pos":[0,0],"locked":1,"volatile":1,"show":"transparent","border":0,"scale":1},"field1":{"type":"field","size":[100,20],"pos":[-186,189]},"slider1":{"type":"slider","size":[100,25],"pos":[-52,184],"interval":[0,47],"value":1,"style":"compact"}}}}}
I have come up with a... sort of solution for drawing all the colour text at deck launch so that I don't have the "pop in after transition" issue
Essentially I've just put this function in my deck-level scripts to just cycle through all the cards and make them all draw on launch. Then I just call it from the "on view" of my starting card.
(removed, see below for better version)
This is kinda hacky (I didn't see an obvious way to check that the contraptions belong to the right prototype so I'm running it on any contraption) so if you have other contraptions with a redraw[] method that does something else this may not be good but it is working for my purposes!
(Apologies if there IS an obvious way to check which prototype a contraption belongs to and I'm just too eepy to figure it out right now)
Edit: better version, thanks IJ for the tip on picking the prototype name
on refreshcolourtext do each c in deck.cards each w in c.widgets if w.def.name="colourtext" w.redraw[] end end end end