UNPKG

skin3d

Version:

Skin3d is a lightweight JS library that renders any Minecraft skin as a smooth, interactive 3D model you can drop straight into a webpage.

163 lines 6.14 kB
/** * @file Nametag.ts * @description This file defines the NameTagObject class for creating Minecraft-style name tags. * @author Cosmic-fi * @license MIT */ 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(); } } /** * Set the text of the name tag. * @param newText The new text. */ async loadAndPaint() { await document.fonts.load(this.font, this.text); this.paint(); } /** * Paint the name tag. * This method creates a canvas, draws the text and background, * and applies it as a texture to the sprite. * @private */ paint() { const canvas = document.createElement("canvas"); /** * Measure the text size * * @remarks * We need to create the canvas and get the context first, * because some browsers (e.g., Safari) require a canvas to measure text. * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Advanced_text_metrics} */ let ctx = canvas.getContext("2d"); ctx.font = this.font; const metrics = ctx.measureText(this.text); /** * Resize the canvas to fit the text with margins */ canvas.width = this.margin[3] + metrics.actualBoundingBoxLeft + metrics.actualBoundingBoxRight + this.margin[1]; canvas.height = this.margin[0] + metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent + this.margin[2]; /** * Draw the background and text * @remarks * We need to get the context again after resizing the canvas, * because resizing clears the canvas and resets the context. * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas#resizing_the_canvas */ ctx = canvas.getContext("2d"); ctx.font = this.font; /** * Draw the background */ ctx.fillStyle = this.backgroundStyle; ctx.fillRect(0, 0, canvas.width, canvas.height); /** * Draw the text */ ctx.fillStyle = this.textStyle; ctx.fillText(this.text, this.margin[3] + metrics.actualBoundingBoxLeft, this.margin[0] + metrics.actualBoundingBoxAscent); /** * Create the texture and apply it to the sprite */ const texture = new CanvasTexture(canvas); texture.magFilter = NearestFilter; texture.minFilter = NearestFilter; this.textMaterial.map = texture; this.textMaterial.needsUpdate = true; /** * Adjust the scale of the sprite to maintain aspect ratio */ this.scale.x = (canvas.width / canvas.height) * this.height; this.scale.y = this.height; } } //# sourceMappingURL=Nametag.js.map