Anvil.js.import_from - three.js - OrbitControls - FontLoader

  1. Why do I need that ['default'] when I get OrbitControls and FontLoader?

This is a very similar question to Why do I need datetime?

import datetime
datetime.datetime.now()

datetime is the module and datetime.datetime is the class.

Similarly:

OrbitControlsMod = anvil.js.import_from("https://cdn.skypack.dev/three-orbit-controls")
OrbitContorls = OrbitControlsMod.default

You’re importing a module and then you’re getting attributes from the module.

JavaScript has different semantics for modules compared to Python.
Every attribute must be exported explicitly and there is also a semantic for providing a default export.

I guess you can think of it as being a semantic similar to Python using the __all__ attribute when doing from x import *


  1. Why the font_loaded and the font_load_error are not called?

I think you are using the API wrong - it should be:


        font_loader = FontLoader(['Trebuchet MS:n4', 'Arial:n4'], {
            "fontLoaded": font_loaded, 
            "complete": font_complete
        })

  1. Why removing the time.sleep(0.001) the font is not loaded (well, it’s loaded later)?

Javascript is single threaded.
When you use sleep in skulpt it doesn’t block the thread.
Whereas just doing a while True with a print statement blocks the thread and then there’s no opportunity for JavasScript to do other work.

Some details in this talk from @meredydd


  1. Threejs either uses the canvas provided as argument if one is provided

I’m pretty sure it’s because the anvil canvas element is setup as a 2D context, whereas Three wants it to have a different context.

  1. Is the workaround on the line with the comment about question # 5 a reliable one?

Is that code from somewhere in particular?
I’d probably want to play around with a clone.