Best way to create and animate custom button styles, like for a disabled state?

I’ve been working on some custom buttons for a UI I’m building. The buttons use custom SVG images for the background and another SVG image for the primary content inside the button. Its essentially an icon-button.

I found the various button pointer animation properties (pointerEnterAnimation, pointerDownAnimation, pointerUpAnimation, pointerOutAnimation) available which has enabled me to easily create a unique style for the button’s normal, hover, and focus states.

The isEnabled does a nice job preventing interaction when the button is not enabled. Now I’m trying to figure out the best way to handle the button’s when they are in a disabled state.

Playground Example

For my case, I want to change the background image and foreground image when the button enters a disabled state. But generally speaking, each element in a button (background, images, text) may need changed for a disabled state. I don’t see this being any different than the pointer animations. Also, this same question comes into play again when I start building my Toggle Buttons.

Is there a recommended way to define and animate a unique state for a button, but specifically for when the button is disabled?

This is a great question and we do not have a state for that YET :slight_smile:

We have two options here:

  • You can create an issue for it and wait for someone who will be willing to help to do the work (I could probably do it in a few weeks)
  • You can create an issue for it and submit a PR :wink: (this is my favorite option :D)

I created a new feature request which can be found here.

1 Like

@Deltakosh My project officially required a toggle button yesterday, so I extended the Button class into a new Toggle class. I’ve never contributed code to a project of this scale before, but if you don’t mind helping me with the process, I’d be happy to try putting together a pull request.

Here we are:

I’m looking forward getting your PR :smiley:

Apologies if I missed this when I read through the Contributing docs, but should I be working from the master or preview branch?

Master:)

1 Like

I’ve created a gitpod from the master repo, added a new script called Toggle.ts to the folder gui/src/2D/controls. This is my first time using gitpod and I’ve never had a simpler experience getting started in a project!

That said, I think I’m missing a step somewhere. When I save the new script, I don’t see webpack recompile. I even saved the script with a syntax error and restarted the compiler with npm run start and no error is produced.

Do I need to add the new script to an index, config, or something?

EDIT: Okay, I got a compiler error with npm run build, so I’m guessing npm run start is only serving the build folder. But please let me know if I should be auto-build on save is possible.

you need to ensure you Toggle.ts is exported by gui/src/2d/controls or it won t be taken in account in the build which might be your issue here.

1 Like

Blast! Thanks @sebavan, my eyes just didn’t want to see that index file.

I’m still struggling to figure out how to test my work locally though. I’d like to use a local playground with the files in the preview release folder. However, I can’t seem to get it to work.

I tried a few different files with no luck and eventually resorted to creating a playground.html file in the localDev folder. I copied the contents of Playground/index.html into this new file and then updated all the babylon urls to point to the /dist/preview release files.

While I can see the files are loaded in locally when viewing the network inspector, the file ‘babylon.gui.d.ts’ still pulls in from the preview domain. I think that might be why I can’t get the new class to be recognized. I know it’s in the build because I can see the new class name in the newly built files.

Can anyone suggest way to use the playground with my local build?

It should work out of the box if you setup your env dev as described in Start Contributing to Babylon.js | Babylon.js Documentation

The Playground (and all other sub systems) will use the current version of your files, you don’t need to change any pointers.

Hmm… well if that’s true then I must have missed a step in my dev environment. I’ve have read through the entire ‘Develop with Babylon.js’ section of the docs including the ‘Contributing Guide’ multiple times now and I’m familiar with webpack projects.

If the dev environment is setup correctly, should Playground/index-local.html utilize the local version of my files? Or a different playground file?

I checked out a freshly forked repo and took these steps to test this issue with `babylon.gui.js:


From Clean Master

  1. Fork repo and checkout master locally
  2. Open project in VSCode
  3. cd Tools/Gulp
  4. npm install
  5. npm run start
  6. In chrome with the network panel open and cacheing disable, loaded http://localhost:1338/Playground/index-local.html
  7. Confirmed babylon.gui.js loaded from localhost.

    Note: Most Babylon files are coming from localhost except the d.ts files

After Creating ToggleButton Class

  1. Created new ToggleButton class in gui/src/2D/controls/toggleButton.ts Class is exported.
  2. Registered type using _TypeStore
  3. Exported toggleButton in gui/src/2D/controls/index.ts
  4. Saved all files
  5. npm run build finished passing 158/158 tests
  6. Confirmed the build output included the ToggleClass in babylon.gui.js and babylon.gui.d.ts
  7. In chrome with the network panel open and cacheing disable, loaded http://localhost:1338/Playground/index-local.html
  8. Confirmed babylon.gui.js loaded from localhost. Note the d.ts comes from remote
  9. In the playground, tried to create a ToggleButton, but I get a type error “Property of ‘ToggleButton’ does not exist on ‘typeof GUI’. (2339)”.

Anyone see any missings steps or errors preventing me from using the new ToggleButton class in the playground?

Fwiw, I can recreate this issue when using a fresh GitPod as well.

  1. Open new GitPod from Master and let it load
  2. Created new ToggleButton class in gui/src/2D/controls/toggleButton.ts Class is exported and the type is registered.
  3. Exported toggleButton in gui/src/2D/controls/index.ts
  4. Saved all files, the project sees a new babylon.gui.js
  5. Open Playground/index-local.html on port 1338
  6. I confirmed the ToggleButton class is in the source file using the network inspector. I can also confirm the d.ts file is coming from preview.babylonjs.com.
  7. In the playground, a type error is thrown when trying to use the new ToggleButton class.

Same results as in my local dev environment.

Well, I’m never using typescript in the local playground, only javascript…

Even in javascript the completion will not show you the new things you created but they do work (try to create your new button in Playground javascript, it should work). Maybe @RaananW or @sebavan will be able to shed some lights on the possibility to have the completion/typescript version of the PG works with the new code added locally.

Also, in your steps described above, you don’t have to rebuild everything to test in the Playground: just do your changes as in steps 1/2/3/4 and you can test them in the local PG.

1 Like

The declarations are all a server only in the ts playground:

const declarations = [
            "https://preview.babylonjs.com/babylon.d.ts",
            "https://preview.babylonjs.com/gui/babylon.gui.d.ts",
            "https://preview.babylonjs.com/glTF2Interface/babylon.glTF2Interface.d.ts",
            "https://preview.babylonjs.com/loaders/babylonjs.loaders.d.ts",
            "https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.d.ts",
            "https://preview.babylonjs.com/nodeEditor/babylon.nodeEditor.d.ts",
            "https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.d.ts",
            "https://preview.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.d.ts",
            "https://preview.babylonjs.com/serializers/babylonjs.serializers.d.ts",
            "https://preview.babylonjs.com/inspector/babylon.inspector.d.ts",
        ];

You could change this in the monaco manager for a quick try.

As the d ts are normally only a full build feature, we do not use them locally at the moment.

2 Likes

Thanks for clarifying this. I got confused because I wasn’t seeing any of my new properties/classes so didn’t know it was actually serving a dev build. This is working exactly as expected now that I understand the cause of this problem.

This suggestion worked! I simply updated the declaration for the GUI to use the file in the preview release and the Playground is now utilizing the type definitions. This makes testing and creating examples so much easier. Especially considering I prefer Typescript.

Thank you for your support! I look forward to creating a pull request for this new feature next week.

2 Likes