pixi-tagged-text icon indicating copy to clipboard operation
pixi-tagged-text copied to clipboard

Add BitmapText support?

Open reececomo opened this issue 7 months ago • 13 comments

Any chance of support for using PIXI.BitmapText(...) under-the-hood instead of PIXI.Text(...)?

This library is awesome, but for performance reasons (especially on mobile devices), it would be phenomenal to leverage PIXI.BitmapText instead of PIXI.Text.

Example:

This is an almost drop-in replacement, that shouldn't be too much of a performance hit in 99% of cases:

Obviously there would be other downstream implications. Like if style is changed dynamically at runtime, the text fields and fonts would need to be regenerated at runtime.

// main/src/TaggedText.ts

export default class TaggedText extends PIXI.Sprite {


  // ----- NEW PROPERTIES: -----

  /**
   * Global default BitmapFont options. 
   * @see {PIXI.IBitmapFontOptions}
   */
  public static BITMAP_FONT_OPTIONS?: PIXI.IBitmapFontOptions;

  /**
   * Cache to make sure BitmapFonts are re-used wherever possible.
   */
  private static _cachedBitmapFonts = Map<string, PIXI.BitmapFont>();


  // ----- MODIFIED METHODS: -----

  private createTextFieldForToken(token: TextSegmentToken): PIXI.BitmapText | PIXI.Text {
    /** ... */

    // Creates textfield as PIXI.BitmapText instead of PIXI.Text
    const textField = createBitmapText(text, sanitizedStyle)

    /** ... */
  }


  // ----- NEW METHODS: -----

  private createBitmapText(text: string, style: Partial<PIXI.TextStyle>): PIXI.BitmapText {
    const fontName = this.loadBitmapFontNameFor(sanitizedStyle);
    const bitmapTextStyle = { ...style, fontName } as Partial<PIXI.IBitmapTextStyle>;

    return new PIXI.BitmapText(text, bitmapTextStyle);
  }

  /**
   * Generates a PIXI.BitmapFont for this style configuration (or re-use cached).
   * @returns Unique identifier for this configuration. Use as `fontName` in `PIXI.IBitmapTextStyle`.
   */
  private loadBitmapFontNameFor(style: Partial<TextStyle>, options:): string {
    const fontName: string = md5(JSON.stringify(style));
    const existing = TaggedText._cachedBitmapFonts.get(fontName);

    if (!existing) {
      const font = PIXI.BitmapFont.from(fontName, style, TaggedText.BITMAP_FONT_OPTIONS);
      TaggedText._cachedBitmapFonts.set(fontName, font);
    }

    return fontName;
  }
}

reececomo avatar Jan 09 '24 07:01 reececomo