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 position = [particle.p.x, particle.p.y]; if (camera) { const realOffset = camera.realOffset; position[0] -= realOffset[0]; position[1] += realOffset[1]; } const angle = rotation.x / (Math.PI * 2); const distanceScale = particle.p.z > 0 ? particle.p.z / 70 : 0; div.style.transform = ` translate(${position[0]}px, ${-position[1]}px) rotate(${angle * 360}deg) scale(${scale + distanceScale}) `; 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(''); this.name = 'NodeRenderer'; this._nodePool = new Proton.Pool(); this.queued = []; this.stage = stage; const promise = stage.findUiElement(selector); promise.then((element) => { this.parent = element; }); } 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; } }