avocado-old/packages/graphics/proton/text-node-renderer.js

103 lines
2.7 KiB
JavaScript
Raw Normal View History

2019-04-19 00:50:15 -05:00
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() {
2019-04-19 01:33:01 -05:00
const clone = new TextNode();
2019-04-19 00:50:15 -05:00
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);
2019-04-19 03:12:30 -05:00
const distanceScale = particle.p.z > 0 ? particle.p.z / 70 : 0;
2019-04-19 00:50:15 -05:00
div.style.transform = `
translate(${position[0]}px, ${-position[1]}px)
rotate(${angle * 360}deg)
2019-04-19 03:12:30 -05:00
scale(${scale + distanceScale})
2019-04-19 00:50:15 -05:00
`;
const spanTranslate = 50 * (1 / scale);
span.style.transform = `translate(-${spanTranslate}%, -${spanTranslate}%)`;
}
}
export class TextNodeRenderer extends Proton.BaseRender {
constructor(selector, stage) {
super();
2019-04-19 23:11:57 -05:00
this._body = new TextNode('');
2019-04-19 00:50:15 -05:00
this.name = 'NodeRenderer';
this._nodePool = new Proton.Pool();
this.queued = [];
this.stage = stage;
stage.uiPromise.then(() => {
2019-04-19 23:12:04 -05:00
this.parent = stage.ui.querySelector(selector);
2019-04-19 00:50:15 -05:00
});
}
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;
}
}