diff --git a/packages/lume/src/components/CameraRig.ts b/packages/lume/src/components/CameraRig.ts index 2a03ee615..dcb574a10 100644 --- a/packages/lume/src/components/CameraRig.ts +++ b/packages/lume/src/components/CameraRig.ts @@ -66,7 +66,7 @@ export class CameraRig extends Node { this.scrollFling!.y untrack(() => { - this.cam!.position.z = this.scrollFling!.y + this.cam!.getPosition().z = this.scrollFling!.y }) }) } diff --git a/packages/lume/src/components/Cube.ts b/packages/lume/src/components/Cube.ts index 4efd697e8..9c3a9fcaf 100644 --- a/packages/lume/src/components/Cube.ts +++ b/packages/lume/src/components/Cube.ts @@ -61,11 +61,11 @@ export default class Cube extends Node { // rotate and place each side. if (index < 4) // 4 sides - rotator.rotation.y = 90 * index + rotator.getRotation().y = 90 * index // top/bottom - else rotator.rotation.x = 90 * (index % 2 ? -1 : 1) + else rotator.getRotation().x = 90 * (index % 2 ? -1 : 1) - side.position.z = this.size.x / 2 + side.getPosition().z = this.getSize().x / 2 this.add(rotator) } diff --git a/packages/lume/src/core/ImperativeBase.ts b/packages/lume/src/core/ImperativeBase.ts index 5b95b1503..fb6b960f8 100644 --- a/packages/lume/src/core/ImperativeBase.ts +++ b/packages/lume/src/core/ImperativeBase.ts @@ -233,12 +233,12 @@ function ImperativeBaseMixin(Base: T) { untrack(() => { if ( - this.sizeMode.x === 'proportional' || - this.sizeMode.y === 'proportional' || - this.sizeMode.z === 'proportional' || - this.align.x !== 0 || - this.align.y !== 0 || - this.align.z !== 0 + this.getSizeMode().x === 'proportional' || + this.getSizeMode().y === 'proportional' || + this.getSizeMode().z === 'proportional' || + this.getAlign().x !== 0 || + this.getAlign().y !== 0 || + this.getAlign().z !== 0 ) { this._calcSize() this.needsUpdate() @@ -703,8 +703,10 @@ function ImperativeBaseMixin(Base: T) { * move _calcSize to a render task. */ protected _calculateMatrix(): void { - // const {__align: align, __mountPoint: mountPoint, __position: position, __origin: origin} = this - const {align, mountPoint, position, origin} = this + const align = this.getAlign() + const mountPoint = this.getMountPoint() + const position = this.getPosition() + const origin = this.getOrigin() const size = this.calculatedSize @@ -815,6 +817,8 @@ function ImperativeBaseMixin(Base: T) { } protected _updateRotation(): void { + const {x, y, z} = this.getRotation() + // Currently rotation is left-handed as far as values inputted into // the LUME APIs. This method converts them to Three's right-handed // system. @@ -831,34 +835,26 @@ function ImperativeBaseMixin(Base: T) { // TODO Make the handedness configurable (f.e. left handed or right // handed rotation) - this.three.rotation.set( - -toRadians(this.rotation.x), - // We don't negate Y rotation here, but we negate Y translation - // in _calculateMatrix so that it has the same effect. - toRadians(this.rotation.y), - -toRadians(this.rotation.z), - ) + // We don't negate Y rotation here, but we negate Y translation + // in _calculateMatrix so that it has the same effect. + this.three.rotation.set(-toRadians(x), toRadians(y), -toRadians(z)) - // TODO Besides that Transformable shouldn't know about Three.js - // objects, it should also not know about Scene. The isScene check - // prevents us from having to import Scene (avoiding a circular - // dependency). - const childOfScene = (this.parent as any)?.isScene + const childOfScene = this.parent?.isScene // TODO write a comment as to why we needed the childOfScne check to // alternate rotation directions here. It's been a while, I forgot // why. I should've left a comment when I wrote this! this.threeCSS.rotation.set( - (childOfScene ? -1 : 1) * toRadians(this.rotation.x), - toRadians(this.rotation.y), - (childOfScene ? -1 : 1) * toRadians(this.rotation.z), + (childOfScene ? -1 : 1) * toRadians(x), + toRadians(y), + (childOfScene ? -1 : 1) * toRadians(z), ) } protected _updateScale(): void { - this.three.scale.set(this.scale.x, this.scale.y, this.scale.z) - - this.threeCSS.scale.set(this.scale.x, this.scale.y, this.scale.z) + const {x, y, z} = this.getScale() + this.three.scale.set(x, y, z) + this.threeCSS.scale.set(x, y, z) } protected _calculateWorldMatricesInSubtree(): void { diff --git a/packages/lume/src/core/Node.test.ts b/packages/lume/src/core/Node.test.ts index 50d38481f..559a0b881 100644 --- a/packages/lume/src/core/Node.test.ts +++ b/packages/lume/src/core/Node.test.ts @@ -18,35 +18,35 @@ describe('Node', () => { it('default values', async () => { const n = new Node() - expect(n.position.x).toEqual(0) - expect(n.position.y).toEqual(0) - expect(n.position.z).toEqual(0) + expect(n.getPosition().x).toEqual(0) + expect(n.getPosition().y).toEqual(0) + expect(n.getPosition().z).toEqual(0) - expect(n.rotation.x).toEqual(0) - expect(n.rotation.y).toEqual(0) - expect(n.rotation.z).toEqual(0) + expect(n.getRotation().x).toEqual(0) + expect(n.getRotation().y).toEqual(0) + expect(n.getRotation().z).toEqual(0) - expect(n.scale.x).toEqual(1) - expect(n.scale.y).toEqual(1) - expect(n.scale.z).toEqual(1) + expect(n.getScale().x).toEqual(1) + expect(n.getScale().y).toEqual(1) + expect(n.getScale().z).toEqual(1) - expect(n.align.x).toEqual(0) - expect(n.align.y).toEqual(0) - expect(n.align.z).toEqual(0) + expect(n.getAlign().x).toEqual(0) + expect(n.getAlign().y).toEqual(0) + expect(n.getAlign().z).toEqual(0) - expect(n.mountPoint.x).toEqual(0) - expect(n.mountPoint.y).toEqual(0) - expect(n.mountPoint.z).toEqual(0) + expect(n.getMountPoint().x).toEqual(0) + expect(n.getMountPoint().y).toEqual(0) + expect(n.getMountPoint().z).toEqual(0) - expect(n.opacity).toEqual(1) + expect(n.getOpacity()).toEqual(1) - expect(n.size.x).toEqual(0, 'default size value not as expected') - expect(n.size.y).toEqual(0, 'default size value not as expected') - expect(n.size.z).toEqual(0, 'default size value not as expected') + expect(n.getSize().x).toEqual(0, 'default size value not as expected') + expect(n.getSize().y).toEqual(0, 'default size value not as expected') + expect(n.getSize().z).toEqual(0, 'default size value not as expected') - expect(n.sizeMode.x).toEqual('literal') - expect(n.sizeMode.y).toEqual('literal') - expect(n.sizeMode.z).toEqual('literal') + expect(n.getSizeMode().x).toEqual('literal') + expect(n.getSizeMode().y).toEqual('literal') + expect(n.getSizeMode().z).toEqual('literal') }) it('element is an instance of Node, created with `new`', async () => { diff --git a/packages/lume/src/core/Node.ts b/packages/lume/src/core/Node.ts index bb58bae01..5e3b1ef48 100644 --- a/packages/lume/src/core/Node.ts +++ b/packages/lume/src/core/Node.ts @@ -7,6 +7,7 @@ import {default as HTMLInterface} from '../html/HTMLNode.js' // register behaviors that can be used on this element import '../html/behaviors/ObjModelBehavior.js' import '../html/behaviors/GltfModelBehavior.js' +import '../html/behaviors/ColladaModelBehavior.js' import type {BaseAttributes} from './ImperativeBase.js' diff --git a/packages/lume/src/core/Scene.ts b/packages/lume/src/core/Scene.ts index b7b686aae..4fa51a3fe 100644 --- a/packages/lume/src/core/Scene.ts +++ b/packages/lume/src/core/Scene.ts @@ -192,7 +192,7 @@ function SceneMixin(Base: T) { * [`Sizeable.sizeMode`](TODO) property to make the default values for the X and * Y axes both "proportional". */ - this.sizeMode.set('proportional', 'proportional', 'literal') + this.getSizeMode().set('proportional', 'proportional', 'literal') /** * @override @@ -201,7 +201,7 @@ function SceneMixin(Base: T) { * [`Sizeable.size`](TODO) property to make the default values for the * X and Y axes both `1`. */ - this.size.set(1, 1, 0) + this.getSize().set(1, 1, 0) // The scene should always render CSS properties (it needs to always // be rendered or resized, for example, because it contains the @@ -654,7 +654,7 @@ function SceneMixin(Base: T) { // If we will be rendering something... (this.enableCss || this.webgl) && // ...and if one size dimension is proportional... - (this.sizeMode.x == 'proportional' || this.sizeMode.y == 'proportional') + (this.getSizeMode().x == 'proportional' || this.getSizeMode().y == 'proportional') // Note, we don't care about the Z dimension, because Scenes are flat surfaces. ) { // ...then observe the parent element size (it may not be a LUME diff --git a/packages/lume/src/core/Sizeable.ts b/packages/lume/src/core/Sizeable.ts index 655ee4f4f..1004250a9 100644 --- a/packages/lume/src/core/Sizeable.ts +++ b/packages/lume/src/core/Sizeable.ts @@ -8,19 +8,10 @@ import Motor from './Motor.js' import type {MixinResult} from 'lowclass' import type {StopFunction} from '@lume/element' -import type {XYZValuesObject, XYZValuesArray, XYZPartialValuesArray, XYZPartialValuesObject} from './XYZValues.js' +import type {XYZValues, XYZValuesObject, XYZPartialValuesArray, XYZPartialValuesObject} from './XYZValues.js' import type {SizeModeValue} from './XYZSizeModeValues.js' import type {RenderTask} from './Motor.js' - -// Property functions are used for animating properties of type XYZNumberValues or XYZNonNegativeValues -type XYZPropertyFunction = ( - x: number, - y: number, - z: number, - time: number, -) => XYZValuesObject | XYZValuesArray | false - -type SinglePropertyFunction = (value: number, time: number) => number | false +import type {XYZNumberValues} from './XYZNumberValues.js' // Cache variables to avoid making new variables in repeatedly-called methods. const previousSize: Partial> = {} @@ -40,8 +31,12 @@ function SizeableMixin>(Base: T) { constructor(...args: any[]) { super(...args) - this.sizeMode.on('valuechanged', () => !this._isSettingProperty && (this.sizeMode = this.sizeMode)) - this.size.on('valuechanged', () => !this._isSettingProperty && (this.size = this.size)) + // TODO: Once TS lands the upcoming feature to have getters with + // different types than setters, we can fix the ugly type casting + // in the following constructor lines. + // Tracking issues: https://github.com/microsoft/TypeScript/issues/2521 and https://github.com/microsoft/TypeScript/pull/42425 + this.getSizeMode().on('valuechanged', () => !this._isSettingProperty && (this.sizeMode = this.sizeMode)) + this.getSize().on('valuechanged', () => !this._isSettingProperty && (this.size = this.size)) } /** @@ -58,18 +53,21 @@ function SizeableMixin>(Base: T) { */ @attribute @emits('propertychange') - set sizeMode(newValue) { + set sizeMode(newValue: XYZSizeModeValuesProperty) { if (typeof newValue === 'function') throw new TypeError('property functions are not allowed for sizeMode') if (!this.__sizeMode) this.__sizeMode = new XYZSizeModeValues('literal', 'literal', 'literal') this._setPropertyXYZ('sizeMode', newValue) } - get sizeMode() { + get sizeMode(): XYZSizeModeValuesProperty { if (!this.__sizeMode) this.__sizeMode = new XYZSizeModeValues('literal', 'literal', 'literal') return this.__sizeMode } private declare __sizeMode?: XYZSizeModeValues + // prettier-ignore + getSizeMode(): XYZSizeModeValues { return this.sizeMode as XYZSizeModeValues } + // TODO: A "differential" size would be cool. Good for padding, // borders, etc. Inspired from Famous' differential sizing. // @@ -100,17 +98,20 @@ function SizeableMixin>(Base: T) { */ @attribute @emits('propertychange') - set size(newValue) { + set size(newValue: XYZNonNegativeNumberValuesProperty | XYZNonNegativeNumberValuesPropertyFunction) { if (!this.__size) this.__size = new XYZNonNegativeValues(0, 0, 0) this._setPropertyXYZ('size', newValue) } - get size() { + get size(): XYZNonNegativeNumberValuesProperty | XYZNonNegativeNumberValuesPropertyFunction { if (!this.__size) this.__size = new XYZNonNegativeValues(0, 0, 0) return this.__size } private declare __size?: XYZNonNegativeValues + // prettier-ignore + getSize(): XYZNonNegativeValues { return this.size as XYZNonNegativeValues } + /** * Get the actual size of the Node. This can be useful when size is * proportional, as the actual size of the Node depends on the size of @@ -194,7 +195,8 @@ function SizeableMixin>(Base: T) { Object.assign(previousSize, calculatedSize) - const {sizeMode, size} = this + const size = this.getSize() + const sizeMode = this.getSizeMode() const parentSize = this._getParentSize() if (sizeMode.x == 'literal') { @@ -282,7 +284,7 @@ function SizeableMixin>(Base: T) { private __propertyFunctions: Map | null = null private __settingValueFromPropFunction = false - private __handleXYZPropertyFunction(fn: XYZPropertyFunction, name: keyof this) { + private __handleXYZPropertyFunction(fn: XYZNumberValuesPropertyFunction, name: keyof this) { if (!this.__propertyFunctions) this.__propertyFunctions = new Map() const propFunction = this.__propertyFunctions.get(name as string) @@ -361,11 +363,15 @@ function SizeableMixin>(Base: T) { return Sizeable as MixinResult } +export const Sizeable = Mixin(SizeableMixin) +export interface Sizeable extends InstanceType {} +export default Sizeable + // the following type guards are used above just to satisfy the type system, // though the actual runtime check does not guarantee that the functions are of // the expected shape. -function isXYZPropertyFunction(f: any): f is XYZPropertyFunction { +function isXYZPropertyFunction(f: any): f is XYZNumberValuesPropertyFunction { return typeof f === 'function' } @@ -373,21 +379,31 @@ function isSinglePropertyFunction(f: any): f is SinglePropertyFunction { return typeof f === 'function' } -export const Sizeable = Mixin(SizeableMixin) -export interface Sizeable extends InstanceType {} -export default Sizeable - -export type Size = XYZNonNegativeValues | XYZPartialValuesArray | XYZPartialValuesObject | string -export type SizeMode = - | XYZSizeModeValues - | XYZPartialValuesArray - | XYZPartialValuesObject +// This type represents the types of values that can be set via attributes or +// properties (attributes pass strings to properties and properties all handle +// string values for example, hence why it includes `| string`) +export type XYZValuesProperty = + | XYZValuesType + | XYZPartialValuesArray + | XYZPartialValuesObject | string -export function size(val: Size) { - return val as XYZNonNegativeValues -} +export type XYZNumberValuesProperty = XYZValuesProperty +export type XYZNonNegativeNumberValuesProperty = XYZValuesProperty +export type XYZSizeModeValuesProperty = XYZValuesProperty -export function sizeMode(val: SizeMode) { - return val as XYZSizeModeValues -} +// Property functions are used for animating properties of type XYZNumberValues +export type XYZValuesPropertyFunction = ( + x: DataType, + y: DataType, + z: DataType, + time: number, +) => XYZValuesPropertyType | false + +export type XYZNumberValuesPropertyFunction = XYZValuesPropertyFunction +export type XYZNonNegativeNumberValuesPropertyFunction = XYZValuesPropertyFunction< + XYZNonNegativeNumberValuesProperty, + number +> + +export type SinglePropertyFunction = (value: number, time: number) => number | false diff --git a/packages/lume/src/core/Transformable.ts b/packages/lume/src/core/Transformable.ts index 447163fcf..bd132142c 100644 --- a/packages/lume/src/core/Transformable.ts +++ b/packages/lume/src/core/Transformable.ts @@ -2,9 +2,8 @@ import {Mixin, MixinResult, Constructor} from 'lowclass' import {attribute, element} from '@lume/element' import {emits} from '@lume/eventful' import XYZNumberValues from './XYZNumberValues.js' -import {Sizeable} from './Sizeable.js' +import {SinglePropertyFunction, Sizeable, XYZNumberValuesProperty, XYZNumberValuesPropertyFunction} from './Sizeable.js' -import type {XYZPartialValuesArray, XYZPartialValuesObject} from './XYZValues.js' import type {SizeableAttributes} from './Sizeable.js' export type TransformableAttributes = @@ -28,12 +27,22 @@ function TransformableMixin>(Base: T) { constructor(...args: any[]) { super(...args) - this.position.on('valuechanged', () => !this._isSettingProperty && (this.position = this.position)) - this.rotation.on('valuechanged', () => !this._isSettingProperty && (this.rotation = this.rotation)) - this.scale.on('valuechanged', () => !this._isSettingProperty && (this.scale = this.scale)) - this.origin.on('valuechanged', () => !this._isSettingProperty && (this.origin = this.origin)) - this.align.on('valuechanged', () => !this._isSettingProperty && (this.align = this.align)) - this.mountPoint.on('valuechanged', () => !this._isSettingProperty && (this.mountPoint = this.mountPoint)) + // TODO: Once TS lands the upcoming feature to have getters with + // different types than setters, we can fix the ugly type casting + // in the following constructor lines. + // Tracking issues: https://github.com/microsoft/TypeScript/issues/2521 and https://github.com/microsoft/TypeScript/pull/42425 + // The get*() methods (f.e. getPosition()) are temporary for + // us TypeScript users until the above issues are fixed soon, at which + // point we can use the getters like a JavaScript user would. + this.getPosition().on('valuechanged', () => !this._isSettingProperty && (this.position = this.position)) + this.getRotation().on('valuechanged', () => !this._isSettingProperty && (this.rotation = this.rotation)) + this.getScale().on('valuechanged', () => !this._isSettingProperty && (this.scale = this.scale)) + this.getOrigin().on('valuechanged', () => !this._isSettingProperty && (this.origin = this.origin)) + this.getAlign().on('valuechanged', () => !this._isSettingProperty && (this.align = this.align)) + this.getMountPoint().on( + 'valuechanged', + () => !this._isSettingProperty && (this.mountPoint = this.mountPoint), + ) } /** @@ -46,17 +55,20 @@ function TransformableMixin>(Base: T) { */ @attribute @emits('propertychange') - set position(newValue) { + set position(newValue: XYZNumberValuesProperty | XYZNumberValuesPropertyFunction) { if (!this.__position) this.__position = new XYZNumberValues(0, 0, 0) this._setPropertyXYZ('position', newValue) } - get position() { + get position(): XYZNumberValuesProperty | XYZNumberValuesPropertyFunction { if (!this.__position) this.__position = new XYZNumberValues(0, 0, 0) return this.__position } private declare __position?: XYZNumberValues + // prettier-ignore + getPosition(): XYZNumberValues { return this.position as XYZNumberValues } + /** * @param {Object} newValue * @param {number} [newValue.x] The x-axis rotation to apply. @@ -65,17 +77,20 @@ function TransformableMixin>(Base: T) { */ @attribute @emits('propertychange') - set rotation(newValue) { + set rotation(newValue: XYZNumberValuesProperty | XYZNumberValuesPropertyFunction) { if (!this.__rotation) this.__rotation = new XYZNumberValues(0, 0, 0) this._setPropertyXYZ('rotation', newValue) } - get rotation() { + get rotation(): XYZNumberValuesProperty | XYZNumberValuesPropertyFunction { if (!this.__rotation) this.__rotation = new XYZNumberValues(0, 0, 0) return this.__rotation } private declare __rotation?: XYZNumberValues + // prettier-ignore + getRotation(): XYZNumberValues { return this.rotation as XYZNumberValues } + /** * @param {Object} newValue * @param {number} [newValue.x] The x-axis scale to apply. @@ -84,17 +99,20 @@ function TransformableMixin>(Base: T) { */ @attribute @emits('propertychange') - set scale(newValue) { + set scale(newValue: XYZNumberValuesProperty | XYZNumberValuesPropertyFunction) { if (!this.__scale) this.__scale = new XYZNumberValues(1, 1, 1) this._setPropertyXYZ('scale', newValue) } - get scale() { + get scale(): XYZNumberValuesProperty | XYZNumberValuesPropertyFunction { if (!this.__scale) this.__scale = new XYZNumberValues(1, 1, 1) return this.__scale } private declare __scale?: XYZNumberValues + // prettier-ignore + getScale(): XYZNumberValues { return this.scale as XYZNumberValues } + /** * @param {Object} newValue * @param {number} [newValue.x] The x-axis origin to apply. @@ -103,17 +121,20 @@ function TransformableMixin>(Base: T) { */ @attribute @emits('propertychange') - set origin(newValue) { + set origin(newValue: XYZNumberValuesProperty | XYZNumberValuesPropertyFunction) { if (!this.__origin) this.__origin = new XYZNumberValues(0.5, 0.5, 0.5) this._setPropertyXYZ('origin', newValue) } - get origin() { + get origin(): XYZNumberValuesProperty | XYZNumberValuesPropertyFunction { if (!this.__origin) this.__origin = new XYZNumberValues(0.5, 0.5, 0.5) return this.__origin } private declare __origin?: XYZNumberValues + // prettier-ignore + getOrigin(): XYZNumberValues { return this.origin as XYZNumberValues } + /** * Set the alignment of the Node. This determines at which point in this * Node's parent that this Node is mounted. @@ -125,17 +146,20 @@ function TransformableMixin>(Base: T) { */ @attribute @emits('propertychange') - set align(newValue) { + set align(newValue: XYZNumberValuesProperty | XYZNumberValuesPropertyFunction) { if (!this.__align) this.__align = new XYZNumberValues(0, 0, 0) this._setPropertyXYZ('align', newValue) } - get align() { + get align(): XYZNumberValuesProperty | XYZNumberValuesPropertyFunction { if (!this.__align) this.__align = new XYZNumberValues(0, 0, 0) return this.__align } private declare __align?: XYZNumberValues + // prettier-ignore + getAlign(): XYZNumberValues { return this.align as XYZNumberValues } + /** * Set the mount point of the Node. * @@ -146,17 +170,20 @@ function TransformableMixin>(Base: T) { */ @attribute @emits('propertychange') - set mountPoint(newValue) { + set mountPoint(newValue: XYZNumberValuesProperty | XYZNumberValuesPropertyFunction) { if (!this.__mountPoint) this.__mountPoint = new XYZNumberValues(0, 0, 0) this._setPropertyXYZ('mountPoint', newValue) } - get mountPoint() { + get mountPoint(): XYZNumberValuesProperty | XYZNumberValuesPropertyFunction { if (!this.__mountPoint) this.__mountPoint = new XYZNumberValues(0, 0, 0) return this.__mountPoint } private declare __mountPoint?: XYZNumberValues + // prettier-ignore + getMountPoint(): XYZNumberValues { return this.mountPoint as XYZNumberValues } + /** * Set this Node's opacity. * @@ -166,16 +193,19 @@ function TransformableMixin>(Base: T) { // TODO opacity doesn't belong in Transformable @attribute @emits('propertychange') - set opacity(newValue) { + set opacity(newValue: number | SinglePropertyFunction) { if (this.__opacity == null) this.__opacity = 1 this._setPropertySingle('opacity', newValue) } - get opacity() { + get opacity(): number | SinglePropertyFunction { if (this.__opacity == null) this.__opacity = 1 return this.__opacity } private declare __opacity?: number + + // prettier-ignore + getOpacity(): number { return this.opacity as number } } return Transformable as MixinResult @@ -184,48 +214,3 @@ function TransformableMixin>(Base: T) { export const Transformable = Mixin(TransformableMixin) export interface Transformable extends InstanceType {} export default Transformable - -// position -// rotation -// scale -// origin -// align -// mountPoint - -export type NumberValues = - | XYZNumberValues - | XYZPartialValuesArray - | XYZPartialValuesObject - | string - | ((x: number, y: number, z: number, time: number) => NumberValues | false) - -export type Position = NumberValues -export type Rotation = NumberValues -export type Scale = NumberValues -export type Origin = NumberValues -export type Align = NumberValues -export type MountPoint = NumberValues - -export function position(val: Position) { - return val as XYZNumberValues -} - -export function rotation(val: Rotation) { - return val as XYZNumberValues -} - -export function scale(val: Origin) { - return val as XYZNumberValues -} - -export function origin(val: Origin) { - return val as XYZNumberValues -} - -export function align(val: Align) { - return val as XYZNumberValues -} - -export function mountPoint(val: MountPoint) { - return val as XYZNumberValues -} diff --git a/packages/lume/src/examples/FlickeringOrb.ts b/packages/lume/src/examples/FlickeringOrb.ts index 79592c248..fb2e972d4 100644 --- a/packages/lume/src/examples/FlickeringOrb.ts +++ b/packages/lume/src/examples/FlickeringOrb.ts @@ -43,7 +43,7 @@ export class FlickeringOrb extends Node { super.connectedCallback() const initialIntensity = this.intensity - const initialOpacity = this.opacity + const initialOpacity = this.getOpacity() // Prior art: https://www.instructables.com/Realistic-Fire-Effect-with-Arduino-and-LEDs/ const flickerFunction = () => { diff --git a/packages/lume/src/interaction/flingRotation.ts b/packages/lume/src/interaction/flingRotation.ts index 1f98ec848..4b2c5cfab 100644 --- a/packages/lume/src/interaction/flingRotation.ts +++ b/packages/lume/src/interaction/flingRotation.ts @@ -1,5 +1,4 @@ import {clamp} from '../math/clamp.js' -import {rotation} from '../core/index.js' import type {Node} from '../core/Node.js' @@ -34,20 +33,20 @@ export function flingRotation({ }: FlingRotationOptions) { interactionInitiator.addEventListener('pointerdown', () => { // Stop rotation if any. - rotationYTarget.rotation = rotation(() => false) + rotationYTarget.rotation = () => false let deltaX = 0 let deltaY = 0 const onMove = (event: PointerEvent) => { deltaX = event.movementY * 0.2 - rotationXTarget.rotation.x = clamp( - rotationXTarget.rotation.x + deltaX, + rotationXTarget.getRotation().x = clamp( + rotationXTarget.getRotation().x + deltaX, minFlingRotationX, maxFlingRotationX, ) deltaY = -event.movementX * 0.2 - rotationYTarget.rotation.y += deltaY + rotationYTarget.getRotation().y += deltaY } // @ts-ignore, whyyyy TypeScript @@ -63,7 +62,7 @@ export function flingRotation({ if (deltaX === 0 && deltaY === 0) return // slow the rotation down based on former drag speed - rotationXTarget.rotation = rotation((x, y, z) => { + rotationXTarget.rotation = (x, y, z) => { deltaX = deltaX * 0.95 // stop rotation once the delta is small enough that we @@ -71,9 +70,9 @@ export function flingRotation({ if (Math.abs(deltaX) < 0.01) return false return [clamp(x + deltaX, minFlingRotationX, maxFlingRotationX), y, z] - }) + } - rotationYTarget.rotation = rotation((x, y, z) => { + rotationYTarget.rotation = (x, y, z) => { deltaY = deltaY * 0.95 // stop rotation once the delta is small enough that we @@ -81,7 +80,7 @@ export function flingRotation({ if (Math.abs(deltaY) < 0.01) return false return [x, y + deltaY, z] - }) + } }, {once: true}, ) diff --git a/packages/lume/src/layout/AutoLayoutNode.ts b/packages/lume/src/layout/AutoLayoutNode.ts index 8b2b1dd54..fbc16f566 100644 --- a/packages/lume/src/layout/AutoLayoutNode.ts +++ b/packages/lume/src/layout/AutoLayoutNode.ts @@ -24,7 +24,6 @@ import {attribute, autorun, element} from '@lume/element' import {emits} from '@lume/eventful' import Node, {NodeAttributes} from '../core/Node.js' import Motor from '../core/Motor.js' -import {sizeMode, size, position} from '../core/index.js' import type {XYZPartialValuesArray} from '../core/XYZValues.js' @@ -284,7 +283,7 @@ export default class AutoLayoutNode extends Node { } var x var y - var size = this.size.toArray() + var size = this.getSize().toArray() if (this._layoutOptions.spacing || this._metaInfo.spacing) { this._autoLayoutView.setSpacing(this._layoutOptions.spacing || this._metaInfo.spacing) } @@ -324,26 +323,26 @@ export default class AutoLayoutNode extends Node { // they only perform type casting for use in TypeScript code. Without // them there will be type errors. - node.sizeMode = sizeMode([ + node.sizeMode = [ // PORTED // @ts-ignore: TODO, key is not defined from anywhere, but it was working??? widths && widths[key] === true ? 'proportional' : 'literal', // @ts-ignore: TODO, key is not defined from anywhere, but it was working??? heights && heights[key] === true ? 'proportional' : 'literal', - ]) - node.size = size([ + ] + node.size = [ // PORTED // @ts-ignore: TODO, key is not defined from anywhere, but it was working??? widths && widths[key] === true ? 1 : subView.width, // @ts-ignore: TODO, key is not defined from anywhere, but it was working??? heights && heights[key] === true ? 1 : subView.height, - ]) - node.position = position([ + ] + node.position = [ // PORTED x + subView.left, y + subView.top, subView.zIndex * 5, - ]) + ] } private _checkNodes() {