the-world-engine
Version:
three.js based, unity like game engine for browser
293 lines (287 loc) • 10.8 kB
JavaScript
import { GlobalConfig } from "../../../GlobalConfig";
import { Transform } from "../../hierarchy_object/Transform";
import { CssRenderer } from "./CssRenderer";
import { ImageRenderingMode } from "./CssSpriteRenderer";
export var CssSpriteAtlasRenderMode;
(function(t) {
t[t["ObjectFit"] = 0] = "ObjectFit";
t[t["ClipPath"] = 1] = "ClipPath";
})(CssSpriteAtlasRenderMode || (CssSpriteAtlasRenderMode = {}));
export class CssSpriteAtlasRenderer extends CssRenderer {
$a=CssSpriteAtlasRenderMode.ObjectFit;
tp=0;
ip=0;
sp=false;
ep=false;
hp=1;
cn=ImageRenderingMode.Pixelated;
xa=1;
Ra=1;
rp=0;
np=0;
ap=0;
wa=null;
renderInitialize() {
if (this.wa) {
this.wa();
} else {
this.asyncSetImageFromPath(GlobalConfig.defaultSpriteSrc, 1, 1);
}
}
updateCenterOffset(t) {
if (!this.css3DObject) return;
if (this.$a === CssSpriteAtlasRenderMode.ObjectFit) {
this.css3DObject.position.set(this.tp * this.centerOffset.x, this.ip * this.centerOffset.y, 0);
if (t) {
Transform.updateRawObject3DWorldMatrixRecursively(this.css3DObject);
this.transform.enqueueRenderAttachedObject3D(this.css3DObject);
}
} else {
const i = this.rp % this.xa;
const s = Math.floor(this.rp / this.xa);
const e = this.sp ? -(this.tp * this.xa / 2 - this.tp / 2) + i * this.tp : this.tp * this.xa / 2 - this.tp / 2 - i * this.tp;
const h = this.ep ? this.ip * this.Ra / 2 - this.ip / 2 - s * this.ip : -(this.ip * this.Ra / 2 - this.ip / 2) + s * this.ip;
this.css3DObject.position.set(this.tp * this.centerOffset.x + e, this.ip * this.centerOffset.y + h, 0);
if (t) {
Transform.updateRawObject3DWorldMatrixRecursively(this.css3DObject);
this.transform.enqueueRenderAttachedObject3D(this.css3DObject);
}
}
}
updateViewScale(t) {
if (!this.css3DObject) return;
if (this.$a === CssSpriteAtlasRenderMode.ObjectFit) {
const i = this.viewScale;
const s = this.sp ? -1 : 1;
const e = this.ep ? -1 : 1;
this.css3DObject.scale.set(this.tp / this.np * i * s, this.ip / this.ap * i * e, 1);
if (t) {
Transform.updateRawObject3DWorldMatrixRecursively(this.css3DObject);
this.transform.enqueueRenderAttachedObject3D(this.css3DObject);
}
} else {
const i = this.viewScale;
const s = this.htmlElement;
s.style.width = this.tp * this.xa / i + "px";
s.style.height = this.ip * this.Ra / i + "px";
const e = this.sp ? -1 : 1;
const h = this.ep ? -1 : 1;
this.css3DObject.scale.set(i * e, i * h, i);
if (t) {
Transform.updateRawObject3DWorldMatrixRecursively(this.css3DObject);
this.transform.enqueueRenderAttachedObject3D(this.css3DObject);
}
}
}
op() {
if (!this.htmlElement) return;
if (this.$a === CssSpriteAtlasRenderMode.ObjectFit) {
const t = -(this.rp % this.xa * this.np);
const i = -Math.floor(this.rp / this.xa) * this.ap;
this.htmlElement.style.objectPosition = t + "px " + i + "px";
} else {
const t = Math.floor(this.rp / this.xa);
const i = this.xa - this.rp % this.xa - 1;
this.htmlElement.style.clipPath = "inset(" + 100 / this.Ra * t + "% " + 100 / this.xa * i + "% " + (100 - (100 / this.Ra * t + 100 / this.Ra)) + "% " + (100 - (100 / this.xa * i + 100 / this.xa)) + "%)";
}
}
get image() {
return this.htmlElement;
}
asyncSetImageFromPath(t, i, s, e) {
if (!this.readyToDraw) {
this.wa = () => this.asyncSetImageFromPath(t, i, s, e);
return;
}
const h = this.htmlElement ?? new Image;
h.src = t;
const onLoad = t => {
if (!this.exists) return;
h.removeEventListener("load", onLoad);
this.setImage(h, i, s);
e?.();
};
h.addEventListener("load", onLoad);
}
setImage(t, i, s) {
if (!t.complete) throw new Error(`Image {${t.src}} is not loaded.`);
this.xa = i;
this.Ra = s;
this.htmlElement = t;
t.alt = this.gameObject.name + "_sprite_atlas";
t.style.imageRendering = this.cn;
t.style.opacity = this.hp.toString();
if (this.$a === CssSpriteAtlasRenderMode.ObjectFit) {
if (this.viewScale !== 1) {
console.warn("CssSpriteAtlas.viewScale is not supported in CssSpriteAtlasRenderMode.ObjectFit, for supressing this warning set viewScale to 1.");
}
this.np = t.naturalWidth / this.xa;
this.ap = t.naturalHeight / this.Ra;
if (this.tp === 0) this.tp = this.np * .1;
if (this.ip === 0) this.ip = this.ap * .1;
t.style.width = this.np + "px";
t.style.height = this.ap + "px";
t.style.objectFit = "none";
} else {
if (this.tp === 0) this.tp = t.naturalWidth / this.xa * .1;
if (this.ip === 0) this.ip = t.naturalHeight / this.Ra * .1;
t.style.width = this.tp * this.xa / this.viewScale + "px";
t.style.height = this.ip * this.Ra / this.viewScale + "px";
}
const e = this.initializeBaseComponents(false);
this.op();
Transform.updateRawObject3DWorldMatrixRecursively(e);
this.transform.enqueueRenderAttachedObject3D(e);
}
get renderMode() {
return this.$a;
}
set renderMode(t) {
if (this.$a === t) return;
this.$a = t;
if (this.htmlElement) {
const t = this.htmlElement;
if (this.$a === CssSpriteAtlasRenderMode.ObjectFit) {
if (this.viewScale !== 1) {
console.warn("CssSpriteAtlas.viewScale is not supported in CssSpriteAtlasRenderMode.ObjectFit");
}
t.style.clipPath = "";
this.np = t.naturalWidth / this.xa;
this.ap = t.naturalHeight / this.Ra;
if (this.tp === 0) this.tp = this.np;
if (this.ip === 0) this.ip = this.ap;
t.style.width = this.np + "px";
t.style.height = this.ap + "px";
t.style.objectFit = "none";
} else {
t.style.objectFit = "";
t.style.objectPosition = "";
if (this.tp === 0) this.tp = t.naturalWidth / this.xa;
if (this.ip === 0) this.ip = t.naturalHeight / this.Ra;
t.style.width = this.tp * this.xa / this.viewScale + "px";
t.style.height = this.ip * this.Ra / this.viewScale + "px";
}
this.updateViewScale(false);
this.updateCenterOffset(false);
this.op();
Transform.updateRawObject3DWorldMatrixRecursively(this.css3DObject);
this.transform.enqueueRenderAttachedObject3D(this.css3DObject);
}
}
get imageIndex() {
return this.rp;
}
set imageIndex(t) {
this.rp = t;
this.op();
if (this.$a === CssSpriteAtlasRenderMode.ClipPath) {
this.updateCenterOffset(true);
}
}
get columnCount() {
return this.xa;
}
get rowCount() {
return this.Ra;
}
get imageWidth() {
return this.tp;
}
set imageWidth(t) {
this.tp = t;
if (this.$a === CssSpriteAtlasRenderMode.ObjectFit) {
if (this.css3DObject) {
this.css3DObject.scale.x = this.tp / this.np * this.viewScale;
this.css3DObject.scale.x *= this.sp ? -1 : 1;
}
} else {
if (this.htmlElement) {
this.htmlElement.style.width = t * this.xa / this.viewScale + "px";
}
}
this.updateCenterOffset(true);
}
get imageHeight() {
return this.ip;
}
set imageHeight(t) {
this.ip = t;
if (this.$a === CssSpriteAtlasRenderMode.ObjectFit) {
if (this.css3DObject) {
this.css3DObject.scale.y = this.ip / this.ap * this.viewScale;
this.css3DObject.scale.y *= this.ep ? -1 : 1;
}
} else {
if (this.htmlElement) {
this.htmlElement.style.height = t * this.Ra / this.viewScale + "px";
}
}
this.updateCenterOffset(true);
}
get imageFlipX() {
return this.sp;
}
set imageFlipX(t) {
this.sp = t;
if (this.css3DObject) {
if (this.sp) {
if (0 < this.css3DObject.scale.x) {
this.css3DObject.scale.x *= -1;
}
} else {
if (this.css3DObject.scale.x < 0) {
this.css3DObject.scale.x *= -1;
}
}
if (this.$a === CssSpriteAtlasRenderMode.ObjectFit) {
Transform.updateRawObject3DWorldMatrixRecursively(this.css3DObject);
this.transform.enqueueRenderAttachedObject3D(this.css3DObject);
} else {
this.op();
this.updateCenterOffset(true);
}
}
}
get imageFlipY() {
return this.ep;
}
set imageFlipY(t) {
this.ep = t;
if (this.css3DObject) {
if (this.ep) {
if (0 < this.css3DObject.scale.y) {
this.css3DObject.scale.y *= -1;
}
} else {
if (this.css3DObject.scale.y < 0) {
this.css3DObject.scale.y *= -1;
}
}
if (this.$a === CssSpriteAtlasRenderMode.ObjectFit) {
Transform.updateRawObject3DWorldMatrixRecursively(this.css3DObject);
this.transform.enqueueRenderAttachedObject3D(this.css3DObject);
} else {
this.op();
this.updateCenterOffset(true);
}
}
}
get opacity() {
return this.hp;
}
set opacity(t) {
this.hp = t;
if (this.htmlElement) {
this.htmlElement.style.opacity = this.hp.toString();
}
}
get imageRenderingMode() {
return this.cn;
}
set imageRenderingMode(t) {
this.cn = t;
if (this.htmlElement) {
this.htmlElement.style.imageRendering = this.cn;
}
}
}