feat: dom text

This commit is contained in:
cha0s 2021-02-12 13:41:02 -06:00
parent 3769b259ab
commit 9fbaf90a14
2 changed files with 136 additions and 0 deletions

View File

@ -0,0 +1,96 @@
import {Vector} from '@avocado/math';
import {StateProperty, Trait} from '@avocado/traits';
import {compose} from '@latus/core';
const decorate = compose(
StateProperty('parentNode', {
track: true,
}),
);
// TODO...
const FACTOR = 5;
export default () => class DomNode extends decorate(Trait) {
#scheduledRuleApplication = true;
static defaultState() {
return {
parentNode: null,
};
}
static dependencies() {
return [
'Visible',
];
}
destroy() {
super.parentNode?.removeChild(this.entity.node);
}
listeners() {
return {
opacityChanged: () => {
this.#scheduledRuleApplication = true;
},
positionChanged: () => {
this.#scheduledRuleApplication = true;
},
rotationChanged: () => {
this.#scheduledRuleApplication = true;
},
textChanged: () => {
this.#scheduledRuleApplication = true;
},
visibleScaleChanged: () => {
this.#scheduledRuleApplication = true;
},
parentNodeChanged: (oldParentNode, newParentNode) => {
oldParentNode?.removeChild(this.entity.node);
newParentNode?.appendChild(this.entity.node);
},
};
}
applyStyleRules() {
const {
opacity,
position,
rotation,
visibleScale,
} = this.entity;
const [x, y] = Vector.scale(position, FACTOR);
this.entity.node.style.transform = [
`translate(${x}px, ${y}px)`,
`rotate(${360 * (rotation / (Math.PI * 2))}deg)`,
`scale(${visibleScale[0]}, ${visibleScale[1]})`,
].join(' ');
this.entity.node.style.opacity = opacity;
}
async load(json) {
await super.load(json);
if ('client' === process.env.SIDE) {
this.entity.node = window.document.createElement('entity');
this.entity.node.style.position = 'absolute';
}
}
tick() {
if ('client' === process.env.SIDE && this.#scheduledRuleApplication) {
this.#scheduledRuleApplication = false;
this.applyStyleRules();
}
}
};

View File

@ -0,0 +1,40 @@
import {Trait} from '@avocado/traits';
export default () => class DomText extends Trait {
#text;
constructor() {
super();
this.#text = window.document.createElement('span');
}
static defaultParams() {
return {
textStyle: {},
};
}
static dependencies() {
return [
'Textual',
'DomNode',
];
}
async load(json) {
await super.load(json);
const {text} = this.entity;
this.#text.innerText = text;
Object.entries(this.params.textStyle).forEach(([key, value]) => {
this.#text.style[key] = value;
});
const {fontSize: fontSizeInPx = '16px'} = this.params.textStyle;
const fontSize = parseInt(fontSizeInPx, 10);
this.#text.style.position = 'relative';
this.#text.style.left = `-${(fontSize / 2) * text.length}px`;
this.#text.style.top = `-${(fontSize / 2)}px`;
this.entity.node.appendChild(this.#text);
}
};