Customize scrollbar

Hi, the task is to customize the scrollbar with the assets below, I have not found a way to do this, are there any ideas? Thank )

How about barColor and barBackground?


Thank.Ok, can I change the shape of the scroll bar? To have rounded edges? as in this picture

@MartynovOleg, unfortunately looking at the docs there’s not a lot of customization you can do to the Babylon.GUI.Scrollbar other than basic positioning, color and size.

@Deltakosh, got any ideas of how to replicate the wireframe?

1 Like

It’s sad. Thank you)) I thought maybe there are some workarounds, etc.)

Well, it isn’t pretty, but you can always overwrite functions of a GUI component:

Making an official way to do it would be best of course…


@Gijs Not a bad start! @MartynovOleg you can also look into creating an HTML form for your menu that displays over the BabylonJS Canvas.

1 Like

Pinging @JohnK as he is the author of the scrollbar

Very cool! :slight_smile: Thank you)

will wait))

Will have a look at adding image based scrollbars into the scrollviewer unless @Gijs who showed the way to do it would like to do the PR.


It’s hard for me personally to understand how his code works, but I really want to)

@JohnK It would be great if you could implement that feature!

@MartynovOleg Mostly the code is from:

But with images instead of filled rectangles

1 Like

Am working on it. Hopefully I should have a PR ready within 24 hours.



24 Hours was a bit optimistic, especially as I spent a few hours tracking, in the wrong place, an error I made. Should be done over the weekend - fingers crossed.


Getting there and now need some help. I have been unable to do two things I wanted to

  1. Size the vertical images so that they are thin as in @Gijs example
  2. Rotate a landscape image to fit into vertical scroll bar and rotate a portrait image to fit into a horizontal scroll bar.

Would you have a look at 1. please @Gijs. I could not work out how to move the drawImage call from your PG into the Babylon.js coding structure for the ScrollViewer.

Here is a working example Scroller

Javascript code for this is at oddsNEdnds/babylon.gui.js at master · BabylonJSGuide/oddsNEdnds · GitHub

(Note I changed the variable name _thumbMeasure to _tempMeasure as that was what it was)

How I have done it so far

i. Created a new ImageScrollBar class ISB Code Babylon.js/imageScrollBar.ts at master · BabylonJSGuide/Babylon.js · GitHub

ii. Added an extra parameter to ScrollViewer which when true allows images for the scroll bars see SV Code Line 97

iii. Forced the thumb to be in proportion to the image used and extend the width using thumbSize SV Code lines 378 / 379

iv. Set the measures for the bar background and bar (thumb) ISB lines 92 - 117 which the calls Image._draw

v. The Image._draw call goes to Babylon.js/image.ts at master · BabylonJSGuide/Babylon.js · GitHub line 615 where the drawImage parameters are set and called depending on a switch state line 648. The ScrollViewer for both ScrollBar and ImageScrollBar go through Line 653 STRETCH_FILL and the private function _drawImage is called Line 598

I experimented with creating different switch calls named IMAGE_VERTICAL, IMAGE_HORIZONTAL but couldn’t work out the parameters to use to get the same effect as @Gijs. (probably something fairly straight forward but I couldn’t get my head around them, probably shouldn’t have tried to do the rotate at the same time)

For 2 I tried using transform and rotate on the canvas image but got completely lost and ended up with my head spinning.

In the end I decided it was best to ask for help. Perhaps @Deltakosh could give me some advice.

So apologies for not yet completing the feature yet.

1 Like

If you want to submit a draft PR so we can chat over the code, I’ll gladly help


Great work @JohnK, it’s suprisingly confusing all those measurements :weary: Your renaming of _thumbMeasure didn’t help, as I thought it was a temporary measure before becoming a current measure, but it actually is the current measure of the thumb :dizzy_face:

What I have now is just doing a context.draw of the BABYLON.GUI.Image's domImage, first saving the transform of the context, then translating to the center of the bar, then rotating (0 deg for vertical, 90 deg for horizontal), then drawing the image, then restoring the transform:

    // Background
    if (this._backgroundImage) {
        let transform = context.getTransform();
        if (this.isVertical) {
            this._tempMeasure.left = left - this._effectiveBarOffset;
   = + thumbPosition;
            this._tempMeasure.width = this._currentMeasure.width;
            this._tempMeasure.height = this._effectiveThumbThickness;

            context.translate(this._currentMeasure.left + (this._currentMeasure.width - this._backgroundImage.domImage.naturalWidth) / 2, + this._currentMeasure.height / 2);
            context.drawImage(this._backgroundImage.domImage, 0, / 2 - this._effectiveThumbThickness, this._backgroundImage.domImage.naturalWidth, this._currentMeasure.height);
        } else {
            this._tempMeasure.left = this._currentMeasure.left + thumbPosition;
            this._tempMeasure.width = this._effectiveThumbThickness;
            this._tempMeasure.height = this._currentMeasure.height;

            context.translate(this._currentMeasure.left + this._currentMeasure.width / 2, + (this._currentMeasure.height - this._backgroundImage.domImage.naturalWidth) / 2);
            context.rotate(Math.PI / 2);
            context.drawImage(this._backgroundImage.domImage, 0, -this._currentMeasure.width / 2, this._backgroundImage.domImage.naturalWidth, this._currentMeasure.width);


For easy testing, I put your working demo in the Babylon.js root dir of my git clone:


Sorry about that. I kept getting confused because it was not a measure of the thumb but was a temporary measure for the thumb and the bar background.

1 Like