In this Phaser 3 example, I step away from sprites and plans for collisions as I am working on something this fits in well with. I need a toolbar for another project and created a short example scene.

I was looking at creating a toolbar for another side project and found to be close to what I imagined.

The example is for opening multiple scenes, which is not quite what I needed. I just wanted a draggable container I could add buttons/controls to.

toolbar scene image
Phaser 3 Toolbar Scene
class ToolbarScene extends Phaser.Scene {
    //phaser 3 toolbar example scene
    private toolbarContainer: Phaser.GameObjects.Container;
    private rotateCcw: Phaser.GameObjects.Image;
    private rotateCw: Phaser.GameObjects.Image;
    private windmill: Phaser.GameObjects.Image;
    constructor() {
            key: 'ToolbarScene'
    preload() {
        console.log('Toolbar scene preload');

        //made by me just a simple rectangle - CC0
        this.load.image('toolbar', '/assets/toolbar.png');
        //rotate-cw and rotate-ccw from
        this.load.image('rotate-cw', '/assets/rotate-cw.png');//rotate clockwise
        this.load.image('rotate-ccw', '/assets/rotate-ccw.png');//rotate counter clockwise
        //picture of windmill near Vantage Washington taken by me sometime in August 2019 - CC0
        this.load.image('windmill', '/assets/windmill.jpg');
    create() {
        let menuItem: Phaser.GameObjects.Text = this.add.text(15, 10, "Home", 
{ fontFamily: 'Verdana, "Times New Roman", Tahoma, serif', fontSize: 25, color: '#3333ff' });
        menuItem.setInteractive({ cursor: 'pointer' }).on('pointerdown', () => {
            window.history.replaceState({}, 'Phaser 3 Examples', './');
        let toolbar = this.add.image(0, 0, 'toolbar').setOrigin(0);
        this.rotateCcw = this.add.image(25, 10, 'rotate-ccw').setOrigin(0).setInteractive({ cursor: 'pointer' });
        this.rotateCw = this.add.image(25, 50, 'rotate-cw').setOrigin(0).setInteractive({ cursor: 'pointer' });
        this.toolbarContainer = this.add.container(15, 50, [toolbar, this.rotateCw, this.rotateCcw]);
        this.toolbarContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, toolbar.width, toolbar.height), Phaser.Geom.Rectangle.Contains);
        this.windmill = this.add.image(screen.width / 2, screen.height / 2, 'windmill');
        //pointer isn't used but in testing it is required or things go wrong. using _pointer to avoid the warning of unused parameter.
        this.toolbarContainer.on('drag', function (_pointer: Phaser.Input.Pointer, dragX: number, dragY: number) {
            this.x = dragX;
            this.y = dragY;
        });//not binding to this as the this we want is toolbarContainer. If I bound to this then we'd need this.toolbarContainer.x ...

        this.windmill.on('drag', function (_pointer: Phaser.Input.Pointer, dragX: number, dragY: number) {
            this.x = dragX;
            this.y = dragY;

        this.rotateCcw.on('pointerdown', function () {
            this.windmill.angle -= 1;
        }, this); //binding to this as we need to access outside of rotateCcw

        this.rotateCw.on('pointerdown', function () {
            this.windmill.angle += 1;
        }, this); // could use () => {} and not bind, but following

export default ToolbarScene;

Phaser 3 Example Toolbar Scene

The spin clockwise / counterclockwise images came from some from me.

Full project source code at

In this latest commit Phaser 3 was updated to 3.19.0 Phaser v3.19.0-FB (WebGL | Web Audio)

Leave a comment

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