Steps to make background color transparent in Phaser 3

Issue

I encountered a problem when adding two Text objects to a scene. The background color of the latter one could not be set to transparent.

Is there anyone who can assist me with this?

Below is a screenshot for reference.


Attempted Solutions

I attempted to make the Text objects have a transparent background but was unsuccessful.

I tried setting the backgroundColor like so:

this.scene.add.text(0, 0, "hoge", {
  backgroundColor: "rgb(255 255 255 / 0.5)",
});

However, this method did not work as expected.


Reference Source Code

The Text object displayed in the source code above has a transparent background.

    this.text = (() => {
      const text = this.scene.add.text(0, 0, "x: -, y: -", {
        padding: {
          y: 50 / this.scene.cameras.main.zoom,
        },
        align: "center",
        fixedWidth: containerWidth,
        fixedHeight: containerHeight,
        fontSize: `${100 / this.scene.cameras.main.zoom}px`,
        lineSpacing: 0,
      });

      return text;
    })();

Conversely, the Text displayed in the above source code has a black background.

    this.text = (() => {
      const text = this.scene.add.text(0, 0, [
        "a10a",
        "VIT: 0",
      ], {
        fixedWidth: containerWidth,
        fixedHeight: containerHeight,
        fontSize: `${100 / this.scene.cameras.main.zoom}px`,
      });

      return text;
    })();

Minimal Reproducible Example

I have created a minimal reproducible example which reveals that setting type: CANVAS in new PhaserGame and using this.load.image affects the background transparency of the text.

By commenting out those lines, I could achieve a transparent background. However, since loading images is essential and causes other issues when changing type: CANVAS, this is not a viable solution.

+ app/
  + _components/
  |  + game/
  |     + scenes/
  |     |   + main-scene/
  |     |       + index.ts
  |     |
  |     + index.tsx
  |
  + globals.css
  + layout.tsx
  + page.tsx
  • _components/game/index.tsx
"use client";

import { CANVAS, Game as PhaserGame, Scale } from "phaser";
import { useEffect, useRef } from "react";
import { MainScene } from "./scenes/main-scene";

export function Game() {
  const game = useRef<Phaser.Game | null>(null);

  useEffect(() => {
    if (game.current === null) {
      game.current = new PhaserGame({
        parent: "game-container",
        // If AUTO, it doesn't work on smartphone browser
        type: CANVAS,
        width: 100,
        height: 100,
        scale: {
          mode: Scale.ScaleModes.FIT,
        },
        backgroundColor: "#028af8",
        scene: [
          MainScene,
        ],
      });
    }

    return () => {
      if (game.current) {
        game.current.destroy(true);
        
        if (game.current !== null) {
          game.current = null;
        }
      }
    }
  }, []);

  return (
    <div id="game-container"></div>
  );
}

export default Game;
  • _components/game/scenes/main-scene/index.ts
import { Scene } from "phaser";

export class MainScene extends Scene {
  constructor () {
    super("MainScene");
  }

  preload() {
    this.load.image("tiles", "assets/tiles.1.png");
  }

  create () {
    this.add.text(0, 0, "Text 1", {
      fontSize: `10px`,
    });

    this.add.text(0, 20, "Text 2", {
      fontSize: `10px`,
    });
  }
}

GitHub

(clone stackoverflow/questions/78791454 branch and run npm run dev to reproduce)


Environment Dependence

This issue seems to be specific to the Chrome browser.

  • Reproducible
    • Chrome (126.0.6478.183) in MacOS (14.5)
  • Not Reproducible
    • Safari (17.5) in MacOS (14.5)
    • Chrome (127.0.6533.56) in iOS (17.5.1)
    • Safari in iOS (17.5.1)

Answer №1

Recent Update as of July 26, 2024: Two Potential "Solutions":

After further investigation, I have discovered two solutions to the issue at hand:

  1. One possible fix for the problem related to a canvas cleanup issue is to reset the Phaser "CanvasPool" to an empty list in the destructor function before destroying the game object. This action would prompt the creation of new HTML-canvas objects.

    // ...
    return () => {
      if (game.current) {
        Phaser.Display.Canvas.CanvasPool.pool = [];
        game.current.destroy(true);      
    
        if (game.current !== null) {
          game.current = null;
        }
      }
    } //...
    
  2. It appears that the issue of double calling the useEffect may be attributed to running the application in development mode (StrictMode). By initiating the application in production mode (npm run build and npm run start), Phaser will not start so rapidly one after the other, hence preventing this error from occurring. No additional changes required (this insight is derived from this Stack Overflow answer and a brief review of the documentation)

I have tested both solutions using your MRE and they both function properly.

This is a Phaser-based "Workaround" (Initial Answer)

You may want to consider utilizing Phaser BitmapFonts. The Bitmap Text GameObject is rendered/generated differently than the regular Text GameObject (not on a hidden internal canvas), thus avoiding the issue altogether.

I have tested your demo application with the bitmap font, and it functions perfectly (tested on Windows 11 with Chrome 126+).

While Bitmap Text may not be as versatile as normal Text, it offers better performance. There are various font conversion tools available that may be helpful if you require a specific font. Additionally, there are numerous Bitmap Fonts readily available (such as these or in the Phaser bitmap font examples, ...).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the method for adjusting the size of text while rendering on a canvas?

When it comes to scaling text with CSS transform scale, for instance: transform: scale(2, 4); fontSize: 20px // Is including fontSize necessary? I also have the task of displaying the same text on a canvas element. function draw() { const ctx = document ...

Modify/Adjust/Move the image uploaded by the user in VueJS before transferring it to an aws s3 bucket

Can you resize images in vuejs using vanilla js? I've managed to upload an image and send it to my s3 bucket using vue, but I'm struggling to figure out how to transform an image within vuejs and display it. Document.querySelector doesn't se ...

Ways to alert user prior to exiting page without initiating a redirect

I have a feature on my website where users can create and edit posts. I want to notify them before leaving the page in these sections. Here's how I can accomplish that: //Add warning only if user is on a New or Edit page if(window.location.href.index ...

AngularTS regex that enforces the use of a decimal point in numbers

I am working on a requirement where the input should only accept decimal characters, negative or positive. I need to use regex to make the decimal point mandatory, however it is currently allowing negative whole numbers which is not the desired behavior. I ...

Error occurred during npm build with Browserify: Module not found

When I run npm build with the following command: "build": "browserify -t [ babelify --presets [ es2015 react ] ] app/assets/app.jsx -o public/javascripts/app.js" I encounter the error message below: Error: Cannot find module 'components/maininput.j ...

Can a script be executed on a node.js module?

I have been developing a node package with an installation script that establishes a basic application structure. This script simply creates a few folders and generates an "admin" user if one does not already exist. Currently, the script performs multiple ...

How to effectively manage time and regularly execute queries every second using Node.js?

Currently working on developing a web software using node js with an Mssql database. There is a table in the database that includes a datetime value and a bit value. The bit value remains at 0 until the real-time matches the datetime value, at which point ...

Showing exclusively JavaScript data in a select element

I am struggling with getting a select tag to display only JavaScript values. Here is the code snippet: <select id="pname"> <option>som data</option> </select> After running a JavaScript function, I want to update the select ta ...

Applying Validators manually in Angular 2 beta 17

We are currently working on a legacy project that needs to be maintained until the final version with angular-final is deployed. Once we upgrade to the final version, I will be able to easily apply conditional Validators using: this.myForm.controls[&apos ...

The jQuery mousedown() function seems to be malfunctioning and unable to trigger the drag event

I am attempting to initiate a drag event using jQuery. You can access the fiddle by clicking here http://jsfiddle.net/sgsvenkatesh/hepbob75/5/ I tried using the following code to initiate the drag event, but it doesn't seem to be working: $(documen ...

Issue with ngFor displaying only the second item in the array

There are supposed to be two editable input fields for each section, with corresponding data. However, only the second JSON from the sample is being displayed in both sections. The JSON in the TypeScript file appears as follows: this.sample = [ { "se ...

The custom confirmation popup is experiencing technical issues

Currently, I am utilizing a plugin to modify the appearance of the confirm popup. Although I have successfully customized the confirm popup, I am encountering an issue where upon clicking the delete icon, the custom confirm popup appears momentarily before ...

Issue: (SystemJS) the exports variable is not defined

In the process of developing a .net core mvc + angular application, I encountered an interesting situation. The MVC framework handles user management, and Angular takes over when users navigate to specific areas of the application. Initially, I integrated ...

Encountering a TypeScript issue when integrating @material-tailwind/react with Next.js 14

Attempting to incorporate "@material-tailwind/react": "^2.1.9" with "next": "14.1.4" "use client"; import { Button } from "@material-tailwind/react"; export default function Home() { return <Button>Test MUI</Button>; } However, the button i ...

What is the best way to show/hide group items in a PrimeNG dropdown menu?

Is it possible to show or hide group items when clicking on the group header if the group contains items? For instance, I would like to display 3 items (AA, BB, CC) in a dropdown menu. The first 2 options (AA and BB) should be selectable, but when I click ...

Are you looking to convert this JSON using underscore or any other JavaScript utility tool?

Looking at this JSON data: [{"target": "mydata.12.2", "datapoints": [[763.7, 1368821100], [762.1, 1368821160], [223.11, 1368821220], [886.54, 1368821280], [112.3, 1368821340]]}] I need to strip the first key and square brackets so it appears like this: ...

Working with node.js to set up an ordering function

I am working with node.js and express3. To use mongodb, I decided to install the mongo-lazy package. This is the simple GET router I have set up: var db = require('mongo-lazy').open({ db: 'somedb', host: '127.0.0.1' ...

Sub-menu disappears upon resizing the screen

Currently, I am working on creating a unique responsive navigation system that transforms into a 100% width pulldown menu for mobile devices. To achieve this functionality, I have implemented some JavaScript code that hides any open sub-menu items when the ...

Keypress Lagging woes: Latest Meteor Update

While I am updating a MongoDB model immediately upon keypress, it seems to lag behind due to the value being attached to that model. What would be the most effective way to update the model both on keypress and when refreshing the page so that the input re ...

What is the most efficient method for transferring images to Google Cloud Storage?

Context: I am currently working on incorporating a new feature that allows users to upload their profile image to Google Cloud Storage (GCS). I am aware of two methods for uploading objects using the client library: The conventional method (refer here: h ...