Scrolling problem in Ink web runner

I’m using the Ink web runner for my Spring Thing entry, and overall, everything works great. But there’s one debilitating bug that’s really hurting player experience, and I’m not good enough with JavaScript to know how to fix it.

(All my beta-testers reading this are probably breathing a sigh of relief that this might finally get fixed. It’s bad.)

Specifically, in the web runner, there’s this function, which is called whenever a new block of text is printed. I’ve added the console.log line for diagnostics.

function scrollDown(previousBottomEdge) {

	// Line up top of screen with the bottom of where the previous content ended
	var target = previousBottomEdge;

	// Can't go further than the very bottom of the page
	var limit = outerScrollContainer.scrollHeight - outerScrollContainer.clientHeight;
	if( target > limit ) target = limit;

	var start = outerScrollContainer.scrollTop;

	var dist = target - start;
	var duration = 300 + 300*dist/100;
	var startTime = null;
	function step(time) {
		if( startTime == null ) startTime = time;
		var t = (time-startTime) / duration;
		var lerp = 3*t*t - 2*t*t*t; // ease in/out
		outerScrollContainer.scrollTo(0, (1.0-lerp)*start + lerp*target);
		if( t < 1 ) requestAnimationFrame(step);
	}
	
	console.log("Scroll: target " + target + " limit " + limit + " start " + start + " dist " + dist + " duration " + duration);
	
	requestAnimationFrame(step);
}

Every once in a while, during gameplay, this will produce a zero or negative distance. Normally this isn’t a problem. Here are some examples of what’s printed to the console.

Scroll: target 32141 limit 32141 start 31848 dist 293 duration 1179
Scroll: target 32392 limit 32585 start 32140 dist 252 duration 1056
Scroll: target 32516 limit 34009 start 32585 dist -69 duration 93
Scroll: target 33786 limit 33786 start 33786 dist 0 duration 300
Scroll: target 34037 limit 34303 start 33786 dist 251 duration 1053

(This is after playing for quite a while, so the text box has gotten pretty big.)

However, occasionally this happens.

Scroll: target 34084 limit 34256 start 34228 dist -144 duration -132

This completely throws off the lerp code, and the result is that the browser scrolls all the way back to the top and stays there, preventing the user from scrolling back down. The animation never ends so it keeps trying to set a negative value forever.

Now, it looks like the problem is a negative value of duration. It shouldn’t be too hard to put a minimum on this—just check if duration is below zero (or perhaps below 300?), and clamp it if so.

But I’m not comfortable enough with JavaScript, or with this code, to have a good sense of what this would do. Is this the right solution? Or is there some better way to fix this?

3 Likes

I don’t know JS either, but this line seems off to me. For consistent timing should it not be something like this?

var duration = 300 + 300*Math.abs(dist)/100;
2 Likes

Hmm, yeah, it’s dividing by duration, so you don’t want that to be zero. But it’ll be positive until distance gets to -100, so I think I’d clamp the distance to be non-negative? Looks to me like that should be totally safe.

var dist = Math.max(0, target - start);

Or you could just do if(dist < 0) return and not scroll at all if you’d be scrolling up?

1 Like

I think this is it! I think when it’s calculating duration it should use the absolute value of dist, because it should take the same amount of time to scroll down as to scroll up.

I’m going to try this now and see what happens!

1 Like

Do you have pictures displayed in your game ?

Nope, but sometimes the list of choices can get pretty long.