Files
2025-01-04 00:34:03 +01:00

1 line
23 KiB
Plaintext

{"version":3,"file":"HTMLText.mjs","sources":["../src/HTMLText.ts"],"sourcesContent":["import { Rectangle, settings, Texture, utils } from '@pixi/core';\nimport { Sprite } from '@pixi/sprite';\nimport { TextStyle } from '@pixi/text';\nimport { HTMLTextStyle } from './HTMLTextStyle';\n\nimport type { ImageResource, IRenderer, ISize, Renderer } from '@pixi/core';\nimport type { IDestroyOptions } from '@pixi/display';\nimport type { ITextStyle } from '@pixi/text';\n\n/**\n * Alternative to {@link PIXI.Text|Text} but supports multi-style HTML text. There are\n * few key differences between this and {@link PIXI.Text|Text}:\n * <br>&bull; HTMLText not support {@link https://caniuse.com/mdn-svg_elements_foreignobject|Internet Explorer}.\n * <br>&bull; Rendering is text asynchronous. If statically rendering, listen to `update` event on BaseTexture.\n * <br>&bull; Does not support all style options (e.g., `lineJoin`, `leading`, `textBaseline`, `trim`, `miterLimit`,\n * `fillGradientStops`, `fillGradientType`)\n * @example\n * import { HTMLText } from 'pixi.js';\n *\n * const text = new HTMLText(\"Hello <b>World</b>\", { fontSize: 20 });\n *\n * text.texture.baseTexture.on('update', () => {\n * console.log('Text is redrawn!');\n * });\n * @class\n * @memberof PIXI\n * @extends PIXI.Sprite\n * @since 7.2.0\n */\nexport class HTMLText extends Sprite\n{\n /**\n * Default opens when destroying.\n * @type {PIXI.IDestroyOptions}\n * @property {boolean} [texture=true] - Whether to destroy the texture.\n * @property {boolean} [children=false] - Whether to destroy the children.\n * @property {boolean} [baseTexture=true] - Whether to destroy the base texture.\n */\n public static defaultDestroyOptions: IDestroyOptions = {\n texture: true,\n children: false,\n baseTexture: true,\n };\n\n /** Default maxWidth, set at construction */\n public static defaultMaxWidth = 2024;\n\n /** Default maxHeight, set at construction */\n public static defaultMaxHeight = 2024;\n\n /** Default resolution, make sure autoResolution or defaultAutoResolution is `false`. */\n public static defaultResolution: number | undefined;\n\n /** Default autoResolution for all HTMLText objects */\n public static defaultAutoResolution = true;\n\n /** The maximum width in rendered pixels that the content can be, any larger will be hidden */\n public maxWidth: number;\n\n /** The maximum height in rendered pixels that the content can be, any larger will be hidden */\n public maxHeight: number;\n\n private _domElement: HTMLElement;\n private _styleElement: HTMLElement;\n private _svgRoot: SVGSVGElement;\n private _foreignObject: SVGForeignObjectElement;\n private _image: HTMLImageElement;\n private _loadImage: HTMLImageElement;\n private _resolution: number;\n private _text: string | null = null;\n private _style: HTMLTextStyle | null = null;\n private _autoResolution = true;\n private localStyleID = -1;\n private dirty = false;\n private _updateID = 0;\n\n /** The HTMLTextStyle object is owned by this instance */\n private ownsStyle = false;\n\n /**\n * @param {string} [text] - Text contents\n * @param {PIXI.HTMLTextStyle|PIXI.TextStyle|PIXI.ITextStyle} [style] - Style setting to use.\n * Strongly recommend using an HTMLTextStyle object. Providing a PIXI.TextStyle\n * will convert the TextStyle to an HTMLTextStyle and will no longer be linked.\n */\n constructor(text = '', style: HTMLTextStyle | TextStyle | Partial<ITextStyle> = {})\n {\n super(Texture.EMPTY);\n\n const image = new Image();\n const texture = Texture.from<ImageResource>(image, {\n scaleMode: settings.SCALE_MODE,\n resourceOptions: {\n autoLoad: false,\n },\n });\n\n texture.orig = new Rectangle();\n texture.trim = new Rectangle();\n\n this.texture = texture;\n\n const nssvg = 'http://www.w3.org/2000/svg';\n const nsxhtml = 'http://www.w3.org/1999/xhtml';\n const svgRoot = document.createElementNS(nssvg, 'svg');\n const foreignObject = document.createElementNS(nssvg, 'foreignObject');\n const domElement = document.createElementNS(nsxhtml, 'div');\n const styleElement = document.createElementNS(nsxhtml, 'style');\n\n // Arbitrary max size\n foreignObject.setAttribute('width', '10000');\n foreignObject.setAttribute('height', '10000');\n foreignObject.style.overflow = 'hidden';\n svgRoot.appendChild(foreignObject);\n\n this.maxWidth = HTMLText.defaultMaxWidth;\n this.maxHeight = HTMLText.defaultMaxHeight;\n this._domElement = domElement;\n this._styleElement = styleElement;\n this._svgRoot = svgRoot;\n this._foreignObject = foreignObject;\n this._foreignObject.appendChild(styleElement);\n this._foreignObject.appendChild(domElement);\n this._image = image;\n this._loadImage = new Image();\n this._autoResolution = HTMLText.defaultAutoResolution;\n this._resolution = HTMLText.defaultResolution ?? settings.RESOLUTION;\n this.text = text;\n this.style = style;\n }\n\n /**\n * Calculate the size of the output text without actually drawing it.\n * This includes the `padding` in the `style` object.\n * This can be used as a fast-pass to do things like text-fitting.\n * @param {object} [overrides] - Overrides for the text, style, and resolution.\n * @param {string} [overrides.text] - The text to measure, if not specified, the current text is used.\n * @param {PIXI.HTMLTextStyle} [overrides.style] - The style to measure, if not specified, the current style is used.\n * @param {number} [overrides.resolution] - The resolution to measure, if not specified, the current resolution is used.\n * @returns {PIXI.ISize} Width and height of the measured text.\n */\n measureText(overrides?: { text?: string, style?: HTMLTextStyle, resolution?: number }): ISize\n {\n const { text, style, resolution } = Object.assign({\n text: this._text,\n style: this._style,\n resolution: this._resolution,\n }, overrides);\n\n Object.assign(this._domElement, {\n innerHTML: text,\n style: style.toCSS(resolution),\n });\n this._styleElement.textContent = style.toGlobalCSS();\n\n // Measure the contents using the shadow DOM\n document.body.appendChild(this._svgRoot);\n const contentBounds = this._domElement.getBoundingClientRect();\n\n this._svgRoot.remove();\n\n const { width, height } = contentBounds;\n\n if (process.env.DEBUG)\n {\n if (width > this.maxWidth || height > this.maxHeight)\n {\n console.warn('[HTMLText] Large expanse of text, increase HTMLText.maxWidth or HTMLText.maxHeight property.');\n }\n }\n\n const contentWidth = Math.min(this.maxWidth, Math.ceil(width));\n const contentHeight = Math.min(this.maxHeight, Math.ceil(height));\n\n this._svgRoot.setAttribute('width', contentWidth.toString());\n this._svgRoot.setAttribute('height', contentHeight.toString());\n\n // Undo the changes to the DOM element\n if (text !== this._text)\n {\n this._domElement.innerHTML = this._text as string;\n }\n if (style !== this._style)\n {\n Object.assign(this._domElement, { style: this._style?.toCSS(resolution) });\n this._styleElement.textContent = this._style?.toGlobalCSS() as string;\n }\n\n return {\n width: contentWidth + (style.padding * 2),\n height: contentHeight + (style.padding * 2),\n };\n }\n\n /**\n * Manually refresh the text.\n * @public\n * @param {boolean} respectDirty - Whether to abort updating the\n * text if the Text isn't dirty and the function is called.\n */\n async updateText(respectDirty = true): Promise<void>\n {\n const { style, _image: image, _loadImage: loadImage } = this;\n\n // check if style has changed..\n if (this.localStyleID !== style.styleID)\n {\n this.dirty = true;\n this.localStyleID = style.styleID;\n }\n\n if (!this.dirty && respectDirty)\n {\n return;\n }\n\n const { width, height } = this.measureText();\n\n // Make sure canvas is at least 1x1 so it drawable\n // for sub-pixel sizes, round up to avoid clipping\n // we update both images, to make sure bounds are correct synchronously\n image.width = loadImage.width = Math.ceil((Math.max(1, width)));\n image.height = loadImage.height = Math.ceil((Math.max(1, height)));\n\n this._updateID++;\n\n const updateID = this._updateID;\n\n await new Promise<void>((resolve) =>\n {\n loadImage.onload = async () =>\n {\n if (updateID < this._updateID)\n {\n resolve();\n\n return;\n }\n\n // Fake waiting for the image to load\n await style.onBeforeDraw();\n\n // Swap image and loadImage, we do this to avoid\n // flashes between updateText calls, usually when\n // the onload time is longer than updateText time\n image.src = loadImage.src;\n loadImage.onload = null;\n loadImage.src = '';\n\n // Force update the texture\n this.updateTexture();\n resolve();\n };\n const svgURL = new XMLSerializer().serializeToString(this._svgRoot);\n\n loadImage.src = `data:image/svg+xml;charset=utf8,${encodeURIComponent(svgURL)}`;\n });\n }\n\n /** The raw image element that is rendered under-the-hood. */\n public get source(): HTMLImageElement\n {\n return this._image;\n }\n\n /**\n * Update the texture resource.\n * @private\n */\n updateTexture()\n {\n const { style, texture, _image: image, resolution } = this;\n const { padding } = style;\n const { baseTexture } = texture;\n\n texture.trim.width = texture._frame.width = image.width / resolution;\n texture.trim.height = texture._frame.height = image.height / resolution;\n texture.trim.x = -padding;\n texture.trim.y = -padding;\n\n texture.orig.width = texture._frame.width - (padding * 2);\n texture.orig.height = texture._frame.height - (padding * 2);\n\n // call sprite onTextureUpdate to update scale if _width or _height were set\n this._onTextureUpdate();\n\n baseTexture.setRealSize(image.width, image.height, resolution);\n\n this.dirty = false;\n }\n\n /**\n * Renders the object using the WebGL renderer\n * @param {PIXI.Renderer} renderer - The renderer\n * @private\n */\n _render(renderer: Renderer)\n {\n if (this._autoResolution && this._resolution !== renderer.resolution)\n {\n this._resolution = renderer.resolution;\n this.dirty = true;\n }\n\n this.updateText(true);\n\n super._render(renderer);\n }\n\n /**\n * Renders the object using the Canvas Renderer.\n * @private\n * @param {PIXI.CanvasRenderer} renderer - The renderer\n */\n _renderCanvas(renderer: IRenderer)\n {\n if (this._autoResolution && this._resolution !== renderer.resolution)\n {\n this._resolution = renderer.resolution;\n this.dirty = true;\n }\n\n this.updateText(true);\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n super._renderCanvas(renderer);\n }\n\n /**\n * Get the local bounds.\n * @param {PIXI.Rectangle} rect - Input rectangle.\n * @returns {PIXI.Rectangle} Local bounds\n */\n getLocalBounds(rect: Rectangle)\n {\n this.updateText(true);\n\n return super.getLocalBounds(rect);\n }\n\n _calculateBounds()\n {\n this.updateText(true);\n this.calculateVertices();\n // if we have already done this on THIS frame.\n (this as any)._bounds.addQuad(this.vertexData);\n }\n\n /**\n * Handle dirty style changes\n * @private\n */\n _onStyleChange()\n {\n this.dirty = true;\n }\n\n /**\n * Destroy this Text object. Don't use after calling.\n * @param {boolean|object} options - Same as Sprite destroy options.\n */\n destroy(options?: boolean | IDestroyOptions | undefined)\n {\n if (typeof options === 'boolean')\n {\n options = { children: options };\n }\n\n options = Object.assign({}, HTMLText.defaultDestroyOptions, options);\n\n super.destroy(options);\n\n const forceClear: any = null;\n\n // Remove any loaded fonts if we created the HTMLTextStyle\n if (this.ownsStyle)\n {\n this._style?.cleanFonts();\n }\n this._style = forceClear;\n this._svgRoot?.remove();\n this._svgRoot = forceClear;\n this._domElement?.remove();\n this._domElement = forceClear;\n this._foreignObject?.remove();\n this._foreignObject = forceClear;\n this._styleElement?.remove();\n this._styleElement = forceClear;\n\n this._loadImage.src = '';\n this._loadImage.onload = null;\n this._loadImage = forceClear;\n this._image.src = '';\n this._image = forceClear;\n }\n\n /**\n * Get the width in pixels.\n * @member {number}\n */\n get width()\n {\n this.updateText(true);\n\n return Math.abs(this.scale.x) * this._image.width / this.resolution;\n }\n\n set width(value) // eslint-disable-line require-jsdoc\n {\n this.updateText(true);\n\n const s = utils.sign(this.scale.x) || 1;\n\n this.scale.x = s * value / this._image.width / this.resolution;\n this._width = value;\n }\n\n /**\n * Get the height in pixels.\n * @member {number}\n */\n get height()\n {\n this.updateText(true);\n\n return Math.abs(this.scale.y) * this._image.height / this.resolution;\n }\n\n set height(value) // eslint-disable-line require-jsdoc\n {\n this.updateText(true);\n\n const s = utils.sign(this.scale.y) || 1;\n\n this.scale.y = s * value / this._image.height / this.resolution;\n this._height = value;\n }\n\n /** The base style to render with text. */\n get style(): HTMLTextStyle\n {\n return this._style as HTMLTextStyle;\n }\n\n set style(style: HTMLTextStyle | TextStyle | Partial<ITextStyle>) // eslint-disable-line require-jsdoc\n {\n // Don't do anything if we're re-assigning\n if (this._style === style)\n {\n return;\n }\n\n style = style || {};\n\n if (style instanceof HTMLTextStyle)\n {\n this.ownsStyle = false;\n this._style = style;\n }\n // Clone TextStyle\n else if (style instanceof TextStyle)\n {\n console.warn('[HTMLText] Cloning TextStyle, if this is not what you want, use HTMLTextStyle');\n\n this.ownsStyle = true;\n this._style = HTMLTextStyle.from(style);\n }\n else\n {\n this.ownsStyle = true;\n this._style = new HTMLTextStyle(style);\n }\n\n this.localStyleID = -1;\n this.dirty = true;\n }\n\n /**\n * Contents of text. This can be HTML text and include tags.\n * @example\n * const text = new HTMLText('This is a <em>styled</em> text!');\n * @member {string}\n */\n get text()\n {\n return this._text;\n }\n\n set text(text) // eslint-disable-line require-jsdoc\n {\n text = String(text === '' || text === null || text === undefined ? ' ' : text);\n text = this.sanitiseText(text);\n\n if (this._text === text)\n {\n return;\n }\n this._text = text;\n this.dirty = true;\n }\n\n /**\n * The resolution / device pixel ratio of the canvas.\n * This is set to automatically match the renderer resolution by default, but can be overridden by setting manually.\n * @member {number}\n * @default 1\n */\n get resolution(): number\n {\n return this._resolution;\n }\n\n set resolution(value: number) // eslint-disable-line require-jsdoc\n {\n this._autoResolution = false;\n\n if (this._resolution === value)\n {\n return;\n }\n\n this._resolution = value;\n this.dirty = true;\n }\n\n /**\n * Sanitise text - replace `<br>` with `<br/>`, `&nbsp;` with `&#160;`\n * @param text\n * @see https://www.sitepoint.com/community/t/xhtml-1-0-transitional-xml-parsing-error-entity-nbsp-not-defined/3392/3\n */\n private sanitiseText(text: string): string\n {\n return text\n .replace(/<br>/gi, '<br/>')\n .replace(/<hr>/gi, '<hr/>')\n .replace(/&nbsp;/gi, '&#160;');\n }\n}\n"],"names":["_HTMLText"],"mappings":"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"}