PixiJs reusable button class

class PixiButton extends PIXI.Container {
  constructor(options) {
    super();

    // Default options
    const defaultOptions = {
      width: 150,
      height: 50,
      cornerRadius: 10,
      backgroundColor: 0x3498db,
      textColor: 0xffffff,
      icon: null,
      text: 'Button',
      opacity: 1,
      hoverColor: 0x2980b9,
      callback: () => {},
    };

    this.options = { ...defaultOptions, ...options };

    this.background = new PIXI.Graphics();
    this.addChild(this.background);

    if (this.options.icon) {
      this.icon = PIXI.Sprite.from(this.options.icon);
      this.icon.anchor.set(0.5);
      this.icon.position.set(15, this.options.height / 2);
      this.addChild(this.icon);
    } else {
        this.createFallbackIcon();
    }

    this.label = new PIXI.Text(this.options.text, {
      fill: this.options.textColor,
      fontSize: 18,
      fontWeight: 'bold',
    });
    this.label.anchor.set(0.5, 1);
    this.label.position.set(this.options.icon ? 40 : 0, this.options.height / 5);
    this.addChild(this.label);

    this.interactive = true;
    this.buttonMode = true;

    this.on('pointerover', this.onButtonOver.bind(this));
    this.on('pointerout', this.onButtonOut.bind(this));
    this.on('pointerdown', this.onButtonDown.bind(this));
    this.on('pointerup', this.onButtonUp.bind(this));

    this.redraw();
  }
  createFallbackIcon() {
    const fallbackIcon = new PIXI.Graphics();
    fallbackIcon.beginFill(0xffffff, 1);
    fallbackIcon.drawCircle(100, 100, 12);
    fallbackIcon.endFill();
    return fallbackIcon;
  }

  redraw() {
    const { width, height, cornerRadius, backgroundColor, opacity } = this.options;

    this.background.clear();
    this.background.beginFill(backgroundColor, opacity);
    this.background.drawRoundedRect(0, 0, width, height, cornerRadius);
    this.background.endFill();
    this.background.pivot.set(width*0.5,height*0.5);
  }

  onButtonOver() {
    this.options.backgroundColor = this.options.hoverColor;
    this.redraw();
    this.label.style.fill = this.options.hoverTextColor || this.options.textColor;
  }

  onButtonOut() {
    this.options.backgroundColor = this.options.defaultColor;
    this.redraw();
    this.label.style.fill = this.options.textColor;
  }

  onButtonDown() {
    this.scale.set(0.95);
  }

  onButtonUp() {
    this.scale.set(1);
    this.options.callback();
  }
}

// Usage
const app = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    backgroundColor: 0x2c3e50
});
document.body.appendChild(app.view);

const button = new PixiButton({
  width: 150,
  height: 50,
  text: 'Click Me',
  callback: () => {
    clickedText.text = 'Button Clicked!';
  },
});
button.position.set(325, 275);
app.stage.addChild(button);

const clickedText = new PIXI.Text('', { fontSize: 24 });
clickedText.anchor.set(0.5);
clickedText.position.set(app.screen.width / 2, app.screen.height - 50);
app.stage.addChild(clickedText);

In this example, a rectangle with a width of 100 and a height of 50 is created, and its position is set to the center of the stage using the center point. The drawRect function is used to draw the rectangle with a centered position.

Keep in mind that if you want to scale or rotate the rectangle, you might need to adjust the pivot point as well to ensure it rotates around the center properly. The pivot point can be set using the pivot property of the display object.

Leave a Reply

Your email address will not be published. Required fields are marked *.

*
*
You may use these <abbr title="HyperText Markup Language">HTML</abbr> tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>