diff --git a/src/components.js b/src/components.js index 8bca5a7..ddefdf9 100644 --- a/src/components.js +++ b/src/components.js @@ -1,5 +1,6 @@ import * as THREE from "three"; import { TagComponent, Component, SystemStateComponent, Types } from "ecsy"; +import { VectorComponent } from "./lib/VectorComponent"; class Object3D extends Component { constructor() { @@ -16,32 +17,18 @@ Object3D.schema = { value: { type: Types.Ref }, }; -class Rotation extends Component { +class Rotation extends VectorComponent { constructor() { super(); - this.rotation = new THREE.Vector3(); } - - reset() {} } -Rotation.schema = { - rotation: { type: Types.Ref }, -}; - -class Position extends Component { +class Position extends VectorComponent { constructor() { super(); - this.position = new THREE.Vector3(); } - - reset() {} } -Position.schema = { - position: { type: Types.Ref }, -}; - class ParentObject3D extends Component { constructor() { super(); @@ -62,7 +49,7 @@ class Text extends Component { super(); this.text = ""; this.textAlign = "left"; // ['left', 'right', 'center'] - this.anchorX = "center"; // ['left', 'right', 'center', 'align'] + this.anchor = "center"; // ['left', 'right', 'center', 'align'] this.baseline = "center"; // ['top', 'center', 'bottom'] this.color = "#FFF"; this.font = "https://code.cdn.mozilla.net/fonts/ttf/ZillaSlab-SemiBold.ttf"; @@ -83,7 +70,7 @@ class Text extends Component { Text.schema = { text: { type: Types.String }, textAlign: { type: Types.String }, - anchorX: { type: Types.String }, + anchor: { type: Types.String }, baseline: { type: Types.String }, color: { type: Types.String }, font: { type: Types.String }, diff --git a/src/lib/VectorComponent.js b/src/lib/VectorComponent.js new file mode 100644 index 0000000..50b1681 --- /dev/null +++ b/src/lib/VectorComponent.js @@ -0,0 +1,95 @@ +import * as THREE from "three"; +import { Types } from "ecsy"; + +class VectorComponent extends THREE.Vector3 { + constructor() { + super(); + this.componentConstructor(); + } + + componentConstructor(props) { + if (props !== false) { + const schema = this.constructor.schema; + + for (const key in schema) { + if (props && props.hasOwnProperty(key)) { + this[key] = props[key]; + } else { + const schemaProp = schema[key]; + if (schemaProp.hasOwnProperty("default")) { + this[key] = schemaProp.type.clone(schemaProp.default); + } else { + const type = schemaProp.type; + this[key] = type.clone(type.default); + } + } + } + + if (process.env.NODE_ENV !== "production" && props !== undefined) { + this.checkUndefinedAttributes(props); + } + } + + this._pool = null; + } + + copy(source) { + const schema = this.constructor.schema; + + for (const key in schema) { + const prop = schema[key]; + + if (source.hasOwnProperty(key)) { + this[key] = prop.type.copy(source[key], this[key]); + } + } + + // @DEBUG + if (process.env.NODE_ENV !== "production") { + this.checkUndefinedAttributes(source); + } + + return this; + } + + clone() { + return new this.constructor().copy(this); + } + + reset() {} + + dispose() { + if (this._pool) { + this._pool.release(this); + } + } + + getName() { + return this.constructor.getName(); + } + + checkUndefinedAttributes(src) { + const schema = this.constructor.schema; + + // Check that the attributes defined in source are also defined in the schema + Object.keys(src).forEach((srcKey) => { + if (!schema.hasOwnProperty(srcKey)) { + console.warn( + `Trying to set attribute '${srcKey}' not defined in the '${this.constructor.name}' schema. Please fix the schema, the attribute value won't be set` + ); + } + }); + } +} + +VectorComponent.schema = { + x: { type: Types.Number }, + y: { type: Types.Number }, + z: { type: Types.Number }, +}; +VectorComponent.isComponent = true; +VectorComponent.getName = function () { + return this.displayName || this.name; +}; + +export { VectorComponent }; diff --git a/src/systems/SDFTextSystem.js b/src/systems/SDFTextSystem.js index f0cf5f2..0c02ab6 100644 --- a/src/systems/SDFTextSystem.js +++ b/src/systems/SDFTextSystem.js @@ -18,8 +18,8 @@ export class SDFTextSystem extends System { updateText(textMesh, textComponent) { textMesh.text = textComponent.text; textMesh.textAlign = textComponent.textAlign; - textMesh.anchor[0] = anchorMapping[textComponent.anchor]; - textMesh.anchor[1] = baselineMapping[textComponent.baseline]; + textMesh.anchorX = anchorMapping[textComponent.anchor]; + textMesh.anchorY = baselineMapping[textComponent.baseline]; textMesh.color = textComponent.color; textMesh.font = textComponent.font; textMesh.fontSize = textComponent.fontSize; @@ -40,7 +40,8 @@ export class SDFTextSystem extends System { const textMesh = new TextMesh(); textMesh.name = "textMesh"; - textMesh.anchor = [0, 0]; + textMesh.anchorX = 0; + textMesh.anchorY = 0; textMesh.renderOrder = 1; //brute-force fix for ugly antialiasing, see issue #67 this.updateText(textMesh, textComponent); e.addComponent(Object3D, { value: textMesh });