Turns out it was simpler than I thought. Overthought it a bit:
Main bulk of the code:
// initialize code called once per entity
MoveToLevelButton.prototype.initialize = function() {
this._scroll = new pc.Vec2();
this.entity.button.on('click', function() {
var scrollView = this.scrollViewEntity.scrollview;
var contentEntity = this.scrollViewEntity.findByName('Content');
var viewportEntity = this.scrollViewEntity.findByName('Viewport');
// Find the level button (assume that they are all in order children)
var levelButtonEntity = contentEntity.children[this.levelNumber - 1];
if (levelButtonEntity) {
// Inverse the position to work with
var y = contentEntity.element.height - levelButtonEntity.getLocalPosition().y;
this._scroll.copy(scrollView.scroll);
this._scroll.y = pc.math.clamp(y / (contentEntity.element.height - viewportEntity.element.height), 0, 1);
scrollView.scroll = this._scroll;
}
}, this);
};