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

133 lines
3.4 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) {
2019-04-21 14:58:11 -05:00
this.parent = null;
const wrapper = window.document.createElement('div');
this.wrapper = wrapper;
wrapper.style.position = 'absolute';
2019-04-19 00:50:15 -05:00
const div = window.document.createElement('div');
2019-04-21 14:58:11 -05:00
wrapper.appendChild(div);
2019-04-19 00:50:15 -05:00
div.className = 'particle';
const span = window.document.createElement('span');
span.className = 'text';
span.textContent = text;
this.span = span;
div.appendChild(span);
this.div = div;
}
2019-04-21 14:58:11 -05:00
copyFrom(other) {
this.span.textContent = other.span.textContent;
2019-04-19 00:50:15 -05:00
}
update(particle, stage) {
const {div, span} = this;
2019-04-21 14:58:11 -05:00
if (particle.useAlpha) {
const alpha = particle.alpha;
div.style.opacity = alpha;
}
if (particle.useColor) {
const color = particle.color;
div.style.color = `rgb(
${color.r * 255},
${color.g * 255},
${color.b * 255}
)`;
}
2019-04-19 00:50:15 -05:00
const {rotation, scale} = particle;
const camera = stage.camera;
2019-04-20 02:15:04 -05:00
const position = [particle.p.x, particle.p.y];
2019-04-19 00:50:15 -05:00
if (camera) {
2019-04-20 02:15:04 -05:00
const realOffset = camera.realOffset;
2019-04-19 00:50:15 -05:00
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 {
2019-04-21 14:58:11 -05:00
static get freeList() {
if (!this._freeList) {
this._freeList = [];
}
return this._freeList;
}
2019-04-19 00:50:15 -05:00
constructor(selector, stage) {
super();
2019-04-19 23:11:57 -05:00
this._body = new TextNode('');
2019-04-21 14:58:11 -05:00
this.freeList = [];
2019-04-19 00:50:15 -05:00
this.name = 'NodeRenderer';
this.queued = [];
this.stage = stage;
2019-04-20 21:35:07 -05:00
const promise = stage.findUiElement(selector);
promise.then((element) => {
this.parent = element;
2019-04-19 00:50:15 -05:00
});
}
onParticleCreated(particle) {
2019-04-21 14:58:11 -05:00
const freeList = this.constructor.freeList;
if (freeList.length > 0) {
particle.target = freeList.pop();
// ...
if (particle.body) {
particle.target.copyFrom(particle.body);
}
}
else {
if (!particle.body) {
particle.body = this._body.clone();
}
particle.target = particle.body;
particle.target.wrapper.style.opacity = 0;
2019-04-19 00:50:15 -05:00
}
if (!this.parent) {
2019-04-21 14:58:11 -05:00
this.queued.push(particle.target);
2019-04-19 00:50:15 -05:00
}
else {
for (let i = 0; i < this.queued.length; ++i) {
2019-04-21 14:58:11 -05:00
this.parent.appendChild(this.queued[i].wrapper);
this.queued[i].parent = this.parent;
this.queued[i].wrapper.style.opacity = 1;
}
this.queued = [];
if (!particle.target.parent) {
this.parent.appendChild(particle.target.wrapper);
particle.target.parent = this.parent;
2019-04-19 00:50:15 -05:00
}
2019-04-21 14:58:11 -05:00
particle.target.wrapper.style.opacity = 1;
2019-04-19 00:50:15 -05:00
}
}
onParticleUpdate(particle) {
if (!particle.target) {
return;
}
particle.target.update(particle, this.stage);
}
onParticleDead(particle) {
2019-04-21 14:58:11 -05:00
particle.target.wrapper.style.opacity = 0;
const freeList = this.constructor.freeList;
freeList.push(particle.target);
2019-04-19 00:50:15 -05:00
particle.target = undefined;
}
}