mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-07-31 06:58:30 +00:00
Allow smooth scrolling animated chat (#452)
* Allow smooth scrolling animated chat * update to use requestAnimationFrame
This commit is contained in:
parent
5626a3c389
commit
be1e1bfd47
1 changed files with 90 additions and 2 deletions
|
@ -45,6 +45,23 @@ export default class Scroller extends Module {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.settings.add('chat.scroller.smooth-scroll', {
|
||||||
|
default: 0,
|
||||||
|
ui: {
|
||||||
|
path: 'Chat > Behavior >> General',
|
||||||
|
title: 'Smooth Scrolling',
|
||||||
|
description: 'Animates new chat messages into view. Will speed up if necessary to keep up with chat.',
|
||||||
|
component: 'setting-select-box',
|
||||||
|
data: [
|
||||||
|
{value: 0, title: 'Disabled'},
|
||||||
|
{value: 1, title: 'Slow'},
|
||||||
|
{value: 2, title: 'Medium'},
|
||||||
|
{value: 3, title: 'Fast'},
|
||||||
|
{value: 4, title: 'Very Fast'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onEnable() {
|
onEnable() {
|
||||||
|
@ -64,6 +81,15 @@ export default class Scroller extends Module {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.smoothScroll = this.chat.context.get('chat.scroller.smooth-scroll');
|
||||||
|
this.chat.context.on('changed:chat.scroller.smooth-scroll', val => {
|
||||||
|
this.smoothScroll = val;
|
||||||
|
|
||||||
|
for(const inst of this.ChatScroller.instances) {
|
||||||
|
inst.ffzSetSmoothScroll(val);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.ChatScroller.ready((cls, instances) => {
|
this.ChatScroller.ready((cls, instances) => {
|
||||||
const t = this,
|
const t = this,
|
||||||
old_catch = cls.prototype.componentDidCatch,
|
old_catch = cls.prototype.componentDidCatch,
|
||||||
|
@ -223,6 +249,56 @@ export default class Scroller extends Module {
|
||||||
//this.ffzHideFrozen();
|
//this.ffzHideFrozen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cls.prototype.smoothScrollBottom = function() {
|
||||||
|
if(this.state.ffzSmoothAnimation){
|
||||||
|
cancelAnimationFrame(this.state.ffzSmoothAnimation);
|
||||||
|
}
|
||||||
|
this.isScrollingToBottom = true;
|
||||||
|
// Step setting value is # pixels to scroll per 10ms.
|
||||||
|
// 1 is pretty slow, 2 medium, 3 fast, 4 very fast.
|
||||||
|
let step = this.ffz_smooth_scroll;
|
||||||
|
const scrollContent = this.scroll.scrollContent;
|
||||||
|
const targetTop = scrollContent.scrollHeight - scrollContent.clientHeight;
|
||||||
|
const difference = targetTop - scrollContent.scrollTop;
|
||||||
|
|
||||||
|
// If we are falling behind speed us up
|
||||||
|
if (difference > scrollContent.clientHeight) {
|
||||||
|
// we are a full scroll away, just jump there
|
||||||
|
step = difference;
|
||||||
|
} else if (difference > 200) {
|
||||||
|
// we are starting to fall behind, speed it up a bit
|
||||||
|
step += step * parseInt(difference / 200, 10);
|
||||||
|
}
|
||||||
|
let prevTime = Date.now();
|
||||||
|
const smoothAnimation = () => {
|
||||||
|
if(this.state.ffzFrozen) {
|
||||||
|
this.isScrollingToBottom = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// See how much time has passed to get a step based off the delta
|
||||||
|
const currentTime = Date.now();
|
||||||
|
const delta = currentTime - prevTime;
|
||||||
|
const currentStep = step * (delta / 10);
|
||||||
|
// we need to move at least one full pixel for scrollTop to do anything in this delta.
|
||||||
|
if (currentStep >= 1) {
|
||||||
|
prevTime = currentTime;
|
||||||
|
if (scrollContent.scrollTop < (scrollContent.scrollHeight - scrollContent.clientHeight)) {
|
||||||
|
scrollContent.scrollTop += currentStep;
|
||||||
|
this.state.ffzSmoothAnimation = requestAnimationFrame(smoothAnimation);
|
||||||
|
} else {
|
||||||
|
scrollContent.scrollTop = scrollContent.scrollHeight - scrollContent.clientHeight;
|
||||||
|
this.isScrollingToBottom = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// the frame happened so quick since last update we didn't move a full pixel yet.
|
||||||
|
// should only be possible if the FPS of a browser went over 60fps.
|
||||||
|
this.state.ffzSmoothAnimation = requestAnimationFrame(smoothAnimation);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
smoothAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cls.prototype.ffzInstallHandler = function() {
|
cls.prototype.ffzInstallHandler = function() {
|
||||||
if ( this._ffz_handleScroll )
|
if ( this._ffz_handleScroll )
|
||||||
|
@ -231,8 +307,13 @@ export default class Scroller extends Module {
|
||||||
const t = this;
|
const t = this;
|
||||||
this._old_scroll = this.scrollToBottom;
|
this._old_scroll = this.scrollToBottom;
|
||||||
this.scrollToBottom = function() {
|
this.scrollToBottom = function() {
|
||||||
if ( ! this.ffz_freeze_enabled || ! this.state.ffzFrozen )
|
if ( ! this.ffz_freeze_enabled || ! this.state.ffzFrozen ) {
|
||||||
return this._old_scroll();
|
if (this.ffz_smooth_scroll !== 0) {
|
||||||
|
this.smoothScrollBottom();
|
||||||
|
} else {
|
||||||
|
this._old_scroll();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._ffz_handleScroll = this.handleScrollEvent;
|
this._ffz_handleScroll = this.handleScrollEvent;
|
||||||
|
@ -394,6 +475,11 @@ export default class Scroller extends Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cls.prototype.ffzSetSmoothScroll = function(value) {
|
||||||
|
this.ffz_smooth_scroll = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for(const inst of instances)
|
for(const inst of instances)
|
||||||
this.onMount(inst);
|
this.onMount(inst);
|
||||||
});
|
});
|
||||||
|
@ -420,6 +506,8 @@ export default class Scroller extends Module {
|
||||||
|
|
||||||
if ( this.freeze !== 0 )
|
if ( this.freeze !== 0 )
|
||||||
inst.ffzEnableFreeze();
|
inst.ffzEnableFreeze();
|
||||||
|
|
||||||
|
inst.ffzSetSmoothScroll(this.smoothScroll);
|
||||||
}
|
}
|
||||||
|
|
||||||
onUnmount(inst) { // eslint-disable-line class-methods-use-this
|
onUnmount(inst) { // eslint-disable-line class-methods-use-this
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue