This approach absolutely works, and is very straightforward. A "synchronous" animation script like this is often the easiest.
I can offer a few tips that could make such a script shorter and easier to maintain:
- If your script is on the same card as the widgets it references, it isn't necessary to use a fully-qualified name like card.widgets.canvas1; canvas1 will do just as well.
- If you want to modify a large group of widgets at the same time, as in the beginning and ending of your script where you hide all your animation frames, you could make a list of the widgets and then take advantage of the ".." syntax. For example:
on click do parts:(canvas1,canvas2,canvas3,canvas4,canvas5,canvas6,field1,field2,field3,field4,field5,field6) parts..show:"none" # ...the rest of the animation goes here... parts..show:"none" end
- It's possible to introduce "helper" functions to factor out repeated patterns. We could, for example, make a function that sleeps for a few frames and then displays a widget- inverted if it's a field, and otherwise solid:
on reveal delay target do sleep[delay] target.show:if target.type~"field" "invert" else "solid" end end
Which would then turn the main script into:
on click do parts:(canvas1,canvas2,canvas3,canvas4,canvas5,canvas6,field1,field2,field3,field4,field5,field6) parts..show:"none" play["witch3"] reveal[120 canvas1] reveal[120 field1 ] sleep["play"] play["witch4"] reveal[120 canvas2] reveal[120 field2 ] reveal[100 canvas3] reveal[100 field3 ] sleep["play"] play["witch5"] reveal[120 canvas4] reveal[120 field4 ] reveal[120 canvas5] reveal[120 field5 ] sleep["play"] play["witch6"] reveal[120 canvas6] reveal[120 field6 ] reveal[120 canvas7] reveal[120 field7 ] sleep["play"] play["witch7"] sleep["play"] play["TapeOut"] parts..show:"none" end
Perhaps you could go even further, making a function that played a music segment, revealed several items in sequence, and then waited for the segment to complete:
on phrase audio parts do play[audio] each row in parts sleep[row.delay] row.part.show:if row.part.type~"field" "invert" else "solid" end end sleep["play"] end on click do parts:(canvas1,canvas2,canvas3,canvas4,canvas5,canvas6,field1,field2,field3,field4,field5,field6) parts..show:"none" phrase["witch3" insert delay part with 120 canvas1 120 field1 end] phrase["witch4" insert delay part with 120 canvas2 120 field2 100 canvas3 100 field3 end] phrase["witch5" insert delay part with 120 canvas4 120 field4 120 canvas5 120 field5 end] phrase["witch6" insert delay part with 120 canvas6 120 field6 120 canvas7 120 field7 end] phrase["witch7" insert delay part with end] play["TapeOut"] parts..show:"none" end
Of course, abstraction adds some complexity, and might make it harder to introduce new exceptions to the rule if you continue to modify the script. Always choose the approach that feels the simplest to you!