UNPKG

skin3d

Version:

A fast, customizable Minecraft skin viewer powered by Three.js. Easily render and preview Minecraft skins in 3D for your projects.

126 lines 5.03 kB
import { CanvasTexture, NearestFilter, Sprite, SpriteMaterial } from "three"; /** * A Minecraft name tag, i.e. a text label with background. */ export class NameTagObject extends Sprite { constructor(text = "", options = {}) { const material = new SpriteMaterial({ transparent: true, alphaTest: 1e-5, }); super(material); /** * A promise that is resolved after the name tag is fully painted. * * This will be a resolved promise, if * {@link NameTagOptions.repaintAfterLoaded} is `false`, or * the desired font is available when the `NameTagObject` is created. * * If {@link NameTagOptions.repaintAfterLoaded} is `true`, and * the desired font hasn't been loaded when the `NameTagObject` is created, * the name tag will be painted with the fallback font first, and then * repainted with the desired font after it's loaded. This promise is * resolved after repainting is done. */ Object.defineProperty(this, "painted", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "text", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "font", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "margin", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "textStyle", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "backgroundStyle", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "height", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "textMaterial", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.textMaterial = material; this.text = text; this.font = options.font === undefined ? "48px Minecraft" : options.font; this.margin = options.margin === undefined ? [5, 10, 5, 10] : options.margin; this.textStyle = options.textStyle === undefined ? "white" : options.textStyle; this.backgroundStyle = options.backgroundStyle === undefined ? "rgba(0,0,0,.25)" : options.backgroundStyle; this.height = options.height === undefined ? 4.0 : options.height; const repaintAfterLoaded = options.repaintAfterLoaded === undefined ? true : options.repaintAfterLoaded; if (repaintAfterLoaded && !document.fonts.check(this.font, this.text)) { this.paint(); this.painted = this.loadAndPaint(); } else { this.paint(); this.painted = Promise.resolve(); } } async loadAndPaint() { await document.fonts.load(this.font, this.text); this.paint(); } paint() { const canvas = document.createElement("canvas"); // Measure the text size // eslint-disable-next-line @typescript-eslint/no-non-null-assertion let ctx = canvas.getContext("2d"); ctx.font = this.font; const metrics = ctx.measureText(this.text); // Compute canvas size canvas.width = this.margin[3] + metrics.actualBoundingBoxLeft + metrics.actualBoundingBoxRight + this.margin[1]; canvas.height = this.margin[0] + metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent + this.margin[2]; // After change canvas size, the context needs to be re-created // eslint-disable-next-line @typescript-eslint/no-non-null-assertion ctx = canvas.getContext("2d"); ctx.font = this.font; // Fill background ctx.fillStyle = this.backgroundStyle; ctx.fillRect(0, 0, canvas.width, canvas.height); // Draw text ctx.fillStyle = this.textStyle; ctx.fillText(this.text, this.margin[3] + metrics.actualBoundingBoxLeft, this.margin[0] + metrics.actualBoundingBoxAscent); // Apply texture const texture = new CanvasTexture(canvas); texture.magFilter = NearestFilter; texture.minFilter = NearestFilter; this.textMaterial.map = texture; this.textMaterial.needsUpdate = true; // Update size this.scale.x = (canvas.width / canvas.height) * this.height; this.scale.y = this.height; } } //# sourceMappingURL=nametag.js.map