Вопрос со скоростью клипа отпал, поэтому оставалось только решить проблему с расчетом расстояний. Для меня сработало следующее:
document.addEventListener('scroll', function () {
for (let i = 0; i < nav1.length; i++) {
elemHeight = nav1[i].offsetHeight;
getClip(nav1[i], elemHeight);
}
});
function getClip (element, height) {
let coords = element.getBoundingClientRect();
if (coords.y <= topDistance){ //когда заголовок за верхней "границей"
element.style.color = '#3F3E3E';
element.style.clip = 'rect( 0px, '+ windowWidth+'px, 0px , 0 )';
} else if (coords.y > topDistance && coords.y < bottomDistance){ //когда заголовок в середине экрана
element.style.clip = 'rect( '+((topDistance+height)-coords.y)+'px, '+ windowWidth+'px, '+ windowHeight +'px , 0 )';
} else { // и когда заголовок пересекает нижнюю "границу"
element.style.clip = 'rect( 0px, '+ windowWidth+'px, '+ ((bottomDistance+height)-coords.y) +'px , 0 )';
}
}
То есть я вычисляю высоту каждого элемента, прибавляю её к расстоянию либо снизу экрана, либо сверху и из этого числа отнимаю координаты, на которых сейчас находится элемент.
Посмотреть как это работает можно по прежнему
Здесь
Заранее: это не работает в браузерах, не поддерживающих -webkit-text-stroke и -webkit-text-fill-color