Actually, I found the problem. I was looking a the portion of generated js code that might be helpful, and it made me think of something. The answer (I believe) is very specific to Scala JS, but I'll post it here in case someone else runs into this.
My original help function built a gsap options structure inside another gsap options structure. Because of the way the javascript code was generated, that became a function call within a function call, which looked weird to gsap (for reasons that are above my pay grade). When I restructured it to get rid of the nested function calls, it worked fine. Here's the revised version of the Scala JS help function:
def physics(dur: Double, vel: Double, ang: Double) = {
val po = new GSAPPhysicsOptions {
override val velocity = vel
override val angle = ang
}
new GSAPOptions {
override val duration = dur
override val physics2D = po
}
}
And if anyone is curious, here is the generated javascript that made gsap unhappy (before refactoring it as shown above):
$c_Lanim_AnimHelpers$.prototype.physics__D__D__D__Lanim_Facades$GSAPOptions = (function(dur, vel, ang) {
var po = (function(arg$1, arg$2) {
var prep0 = $uD(arg$1);
var prep1 = $uD(arg$2);
var vel$1 = prep0;
var ang$1 = prep1;
var $this = {};
$this.velocity = null;
$this.angle = null;
$this.velocity = $m_sjs_js_UndefOr$().any2undefOrA__O__sjs_js_UndefOr(vel$1);
$this.angle = $m_sjs_js_UndefOr$().any2undefOrA__O__sjs_js_UndefOr(ang$1);
return $this
})(vel, ang);
return (function(arg$1, arg$2) {
var prep0 = $uD(arg$1);
var prep1 = arg$2;
var dur$4 = prep0;
var po$1 = prep1;
var this$2 = {};
this$2.duration = null;
this$2.physics2D = null;
this$2.duration = $m_sjs_js_UndefOr$().any2undefOrA__O__sjs_js_UndefOr(dur$4);
this$2.physics2D = $m_sjs_js_UndefOr$().any2undefOrA__O__sjs_js_UndefOr(po$1);
return this$2
})(dur, po)
});
$c_Lanim_AnimHelpers$.prototype.init___ = (function() {
$c_O.prototype.init___.call(this);
$n_Lanim_AnimHelpers$ = this;
return this
});