103 lines
2.7 KiB
JavaScript
103 lines
2.7 KiB
JavaScript
import {Proton} from './proton';
|
|
|
|
import {Vector} from '@avocado/math';
|
|
|
|
export class TextNode {
|
|
|
|
constructor(text) {
|
|
const div = window.document.createElement('div');
|
|
div.className = 'particle';
|
|
div.style.position = 'absolute';
|
|
const span = window.document.createElement('span');
|
|
span.className = 'text';
|
|
span.textContent = text;
|
|
this.span = span;
|
|
div.appendChild(span);
|
|
this.div = div;
|
|
}
|
|
|
|
clone() {
|
|
const clone = new TextNode();
|
|
clone.div = this.div.cloneNode(true);
|
|
clone.span = clone.div.children[0];
|
|
return clone;
|
|
}
|
|
|
|
update(particle, stage) {
|
|
const {div, span} = this;
|
|
const alpha = particle.useAlpha ? particle.alpha : 1;
|
|
const color = particle.useColor ? particle.color : {r: 0, g: 0, b: 0};
|
|
const {rotation, scale} = particle;
|
|
div.style.color = `rgb(
|
|
${color.r * 255},
|
|
${color.g * 255},
|
|
${color.b * 255}
|
|
)`;
|
|
div.style.opacity = alpha;
|
|
const camera = stage.camera;
|
|
const stageScale = stage.scale;
|
|
const position = Vector.mul([particle.p.x, particle.p.y], stageScale);
|
|
if (camera) {
|
|
const realOffset = Vector.mul(camera.realOffset, stageScale);
|
|
position[0] -= realOffset[0];
|
|
position[1] += realOffset[1];
|
|
}
|
|
const angle = rotation.x / (Math.PI * 2);
|
|
div.style.transform = `
|
|
translate(${position[0]}px, ${-position[1]}px)
|
|
rotate(${angle * 360}deg)
|
|
scale(${scale})
|
|
`;
|
|
const spanTranslate = 50 * (1 / scale);
|
|
span.style.transform = `translate(-${spanTranslate}%, -${spanTranslate}%)`;
|
|
}
|
|
|
|
}
|
|
|
|
export class TextNodeRenderer extends Proton.BaseRender {
|
|
|
|
constructor(selector, stage) {
|
|
super();
|
|
this._body = new TextNode(parent);
|
|
this.name = 'NodeRenderer';
|
|
this._nodePool = new Proton.Pool();
|
|
this.queued = [];
|
|
this.stage = stage;
|
|
stage.uiPromise.then(() => {
|
|
const parent = stage.ui.querySelector(selector);
|
|
this.parent = parent;
|
|
});
|
|
}
|
|
|
|
onParticleCreated(particle) {
|
|
if (!particle.body) {
|
|
particle.body = this._body;
|
|
}
|
|
particle.target = this._nodePool.get(particle.body);
|
|
particle.target.div.style.opacity = 0;
|
|
if (!this.parent) {
|
|
this.queued.push(particle.target.div);
|
|
}
|
|
else {
|
|
for (let i = 0; i < this.queued.length; ++i) {
|
|
this.parent.appendChild(this.queued[i]);
|
|
}
|
|
this.parent.appendChild(particle.target.div);
|
|
}
|
|
}
|
|
|
|
onParticleUpdate(particle) {
|
|
if (!particle.target) {
|
|
return;
|
|
}
|
|
particle.target.update(particle, this.stage);
|
|
}
|
|
|
|
onParticleDead(particle) {
|
|
this._nodePool.expire(particle.target);
|
|
this.parent.removeChild(particle.target.div);
|
|
particle.target = undefined;
|
|
}
|
|
|
|
}
|