Skip to main content
Participant
March 9, 2025
Question

How to lock a scrollbar to the right border of a panel?

  • March 9, 2025
  • 0 replies
  • 105 views

Hi, I'm trying to implement a scrollbar for a script in After Effects. I don't know how to code, so I asked ChatGPT for help. Everything is working fine except for the scrollbar's position in X.

 

What does the code do?

It creates a list of 15 white rectangles in a resizeable dockable panel. If the panel is not big enough to display all the rectangles, a scrollbar appears so you can scroll through all the rectangles.

Now, the problem is that the scrollbar position in X is just at the right side of the rectangles and I want it locked to the right border of the panel.

 

The next image shows where the scrollbar position in X is right now (red arrow) and where it should be (blue arrow).

 

This is the code:

// Crear panel dockeable o ventana flotante
var myPanel = (this instanceof Panel)
    ? this
    : new Window("palette", "Panel Dockeable", undefined, {resizeable: true});

myPanel.orientation = "column";
myPanel.alignChildren = ["fill", "top"];

// Contenedor principal que agrupa los rectángulos y la scrollbar
var scrollContainer = myPanel.add("group");
scrollContainer.orientation = "row";
scrollContainer.alignChildren = ["fill", "top"];

// Contenedor visible de los rectángulos (altura variable según el panel)
var viewport = scrollContainer.add("group");
viewport.orientation = "stack"; // Evita desplazamiento horizontal
viewport.alignChildren = ["fill", "top"];
viewport.margins = 0;

// Grupo que se desplazará con la scrollbar
var contentGroup = viewport.add("group");
contentGroup.orientation = "column";
contentGroup.alignChildren = ["fill", "top"];
contentGroup.spacing = 5;

// Crear 15 rectángulos dentro del grupo desplazable
var rectArray = [];
for (var i = 0; i < 15; i++) {
    var rectPanel = contentGroup.add("panel", undefined, "");
    rectPanel.preferredSize = [100, 50];
    if (rectPanel.graphics) {
        rectPanel.graphics.backgroundColor =
            rectPanel.graphics.newBrush(rectPanel.graphics.BrushType.SOLID_COLOR, [1, 1, 1, 1]);
    }
    rectArray.push(rectPanel);
}

// Crear la scrollbar VERTICAL con valor inicial (fallback)
var scrollbar = scrollContainer.add("scrollbar", undefined, 0, 0, 100);
scrollbar.stepdelta = 10;
scrollbar.preferredSize = [20, 250];

// Evento para mover el contenido con la scrollbar
scrollbar.onChanging = function () {
    contentGroup.location = [contentGroup.location[0], -scrollbar.value];
};

function updateScrollbar() {
    // Obtener la altura actual del panel
    var panelHeight = myPanel.bounds.height;
    // Calcular la altura total del contenido (paneles de 50px + 5px de espacio)
    var totalContentHeight = rectArray.length * (50 + 5);
    // Calcular la altura disponible (ajustando un margen superior de 50px)
    var availableHeight = panelHeight - 50;
    viewport.maximumSize = [100, availableHeight];

    if (totalContentHeight > availableHeight) {
        // Guardar la posición relativa actual antes de recalcular (valor entre 0 y 1)
        var oldMax = scrollbar.maxvalue || 100; // Si no está definido, usar 100 (valor inicial)
        var relativePos = oldMax ? scrollbar.value / oldMax : 0;
        
        // Actualizar el valor máximo según el nuevo tamaño
        scrollbar.maxvalue = totalContentHeight - availableHeight;
        scrollbar.minvalue = 0;
        // Aplicar el mismo porcentaje a la nueva escala
        scrollbar.value = scrollbar.maxvalue * relativePos;
        scrollbar.visible = true;
        
        // Actualizar los bounds de la scrollbar para reflejar la nueva altura disponible
        var sbBounds = scrollbar.bounds;
        scrollbar.bounds = [sbBounds[0], sbBounds[1], sbBounds[0] + 20, sbBounds[1] + availableHeight];
    } else {
        scrollbar.visible = false;
        contentGroup.location.y = 0;
    }
    // Ajustar la posición del contenido en función del valor de la scrollbar
    contentGroup.location = [contentGroup.location[0], -scrollbar.value];
    myPanel.layout.layout(true);
}

// Actualizar la scrollbar al redimensionar el panel sin reiniciar la posición relativa
myPanel.onResize = function () {
    updateScrollbar();
};

myPanel.layout.layout(true);
updateScrollbar();

// Mostrar la ventana si no es dockeable
if (myPanel instanceof Window) {
    myPanel.center();
    myPanel.show();
}

 Can anyone help me? Thanks.