Lume `v0.3.0-alpha.44` - The Decorator Future

This release makes improvements to Lume’s foundation, improving the decorator implementation based on the spec that browsers are currently implementing! In the very near future, we will be able to write new 3D HTML elements using native decorators without a build system, making the process of authoring new 3D elements possible without ever touching a command (and still using decorators). There is currently a way to write elements without decorators without a build, but it is less ergonomic.

@keywizzle added two new attributes to <lume-camera-rig>, the dynamic-dolly and dynamic-rotation attributes which will dynamically modify the dolly speed or rotation speed, respectively, of a camera rig depending on how far in or out the camera has dollied. This makes it easier to perform smaller movements when zoomed in. The new camera-rig.html example shows how it works:

https://raw.githack.com/lume/lume/64303f70d55a4f25198b0a3130afc50450eef8c0/examples/camera-rig.html

Before, without the new attributes:

After, with the new attributes:

What’s Changed

  • feat: add missing active prop for cameras in JSX types by @trusktr in add missing active prop for cameras in JSX by trusktr · Pull Request #302 · lume/lume · GitHub
  • feat: Dynamic cam by @keywizzle in Dynamic cam by keywizzle · Pull Request #304 · lume/lume · GitHub
    • Adds a new dynamic-dolly boolean attribute to <lume-camera-rig>. When true, the effective dolly speed will be changed based on the camera’s distance to minDistance. Getting closer to minDistance will lower the effective dolly speed towards zero. This is useful when zoomed into an object and having the dolly movements not be disproportionately huge while viewing fine details of the object.
    • Adds a new dynamic-rotation boolean attribute to <lume-camera-rig>. When true, the effective rotation speed will be changed based on the camera’s distance to minDistance. Getting closer to minDistance will lower the effective rotation speed to allow for finer control. This is useful zoomed in to see fine details of an object and having the rotation not be disproportionately huge, for example when zooming into a 3D globe.
  • feat: Update lowclass, @lume/element, and three versions (@types/three and three were updated in yarn.lock) by @trusktr in Update `lowclass`, `@lume/element`, and `three` versions (`@types/three` and `three` were updated in `yarn.lock`) by trusktr · Pull Request #313 · lume/lume · GitHub
    • This is inherited from the respective changes in @lume/element and in classy-solid, see those release notes in case you’re using those libraries directly (which are re-exported from lume, the exports Element, element, attribute, numberAttribute, booleanAttribute, stringAttribute, reactive, and signal)
    • This enables accessor #private fields and get #private/set #private properties to be decorated with @signal, which allows converting code using conventional underscored “private” properties like this,
      @element('my-el')
      class MyEl extends Element3D {
        @signal __someProperty = 123
        
        @signal
        get __otherProperty() {...}
        set __otherProperty(v) {...}
      }
      
      to code that uses actually-private syntax:
      @element('my-el')
      class MyEl extends Element3D {
        @signal accessor #someProperty = 123
      
        @signal get #otherProperty() {...}
        @signal set #otherProperty(v) {...}
      }
      
    • BREAKING: If you get an error like Uncaught SyntaxError: The requested module 'lowclass' does not provide an export named 'Constructor', it means your app is loading an older version of lume, @lume/element, classy-solid, lowclass or another dependency that depends on @lume/element, classy-solid, or lowclass.
      • Ensure you have lume 0.3.0-alpha.44, @lume/element 0.13.x, classy-solid 0.4.x, lowclass 8.x, and any updated versions of other libraries that use the new versions of lume, @lume/element, classy-solid, or lowclass.
    • BREAKING: If you get an error like Uncaught TypeError: Failed to resolve module specifier "lowclass/dist/getInheritedDescriptor.js". Relative references must start with either "/", "./", or "../"., it means your <script type="impormap"> needs to be updated to include an entry for lowclass/.
      • Before:
        <script type="importmap">{
          "imports": {
            ...
            "lowclass": "/node_modules/lowclass/dist/index.js",
            ...
          }
        }</script>
        
        After
        <script type="importmap">{
          "imports": {
            ...
            "lowclass": "/node_modules/lowclass/dist/index.js",
            "lowclass/": "/node_modules/lowclass/",
            ...
          }
        }</script>
        
        If you are getting dependencies from a CDN, it would be similar:
        <script type="importmap">{
          "imports": {
            ...
            "lowclass": "https://cdn.jsdelivr.net/npm/lowclass@8.0.2/dist/index.js",
            "lowclass/": "https://cdn.jsdelivr.net/npm/lowclass@8.0.2/",
            ...
          }
        }</script>
        
        Another option is to use JSPM Importmap Generator to generate an importmap (tutorial here).
    • BREAKING: If you extended Lume classes to make new classes, or used @lume/element (whose exports are re-exprted from lume) to make new non-3D elements, and you used an attribute decorator (f.e. @attribute, @numberAttribute, etc) or the @signal decorator on any getter/setter class properties, you will need to ensure that you place the decorators on both the getter and the setter. This code,
      @element('my-el')
      class MyEl extends Element3D {
          @numberAttribute
          get someProperty() {...}
          set someProperty(v) {...}
      
          @booleanAttribute
          @noSignal
          get someProperty() {...}
          set someProperty(v) {...}
      
          @signal
          get otherProperty() {...}
          set otherProperty(v) {...}
      }
      
      becomes the following, ensuring that decorators are repeated on both getter and setter (new lines or no new lines are style preference):
      @element('my-el')
      class MyEl extends Element3D {
          @numberAttribute get someProperty() {...}
          @numberAttribute set someProperty(v) {...}
      
          @booleanAttribute @noSignal get someProperty() {...}
          @booleanAttribute @noSignal set someProperty(v) {...}
      
          @signal get otherProperty() {...}
          @signal set otherProperty(v) {...}
      }
      
      or
      @element('my-el')
      class MyEl extends Element3D {
          @numberAttribute
          get someProperty() {...}
          @numberAttribute
          set someProperty(v) {...}
      
          @booleanAttribute
          @noSignal
          get someProperty() {...}
          @booleanAttribute
          @noSignal
          set someProperty(v) {...}
      
          @signal
          get otherProperty() {...}
          @signal
          set otherProperty(v) {...}
      }
      

Insignificant changes to the repo

Full Changelog: Comparing v0.3.0-alpha.43...v0.3.0-alpha.44 · lume/lume · GitHub