mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-09-16 18:06:55 +00:00
4.20.37
* Fixed: Chat scrolling after Twitch's update yesterday. * Fixed: In-line actions that depend on holding modifier keys not appearing correctly.
This commit is contained in:
parent
a771f337a4
commit
943e0fdc18
2 changed files with 55 additions and 194 deletions
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "frankerfacez",
|
"name": "frankerfacez",
|
||||||
"author": "Dan Salvato LLC",
|
"author": "Dan Salvato LLC",
|
||||||
"version": "4.20.36",
|
"version": "4.20.37",
|
||||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -41,7 +41,7 @@ export default class Scroller extends Module {
|
||||||
description: 'Automatically stop chat from scrolling when moving the mouse over it or holding a key.\n\n**Note:** Scrolling up in chat will always prevent automatic scrolling, regardless of this setting.',
|
description: 'Automatically stop chat from scrolling when moving the mouse over it or holding a key.\n\n**Note:** Scrolling up in chat will always prevent automatic scrolling, regardless of this setting.',
|
||||||
component: 'setting-select-box',
|
component: 'setting-select-box',
|
||||||
data: [
|
data: [
|
||||||
{value: 0, title: 'Disabled'},
|
{value: 0, title: 'Use Twitch Setting'},
|
||||||
{value: 1, title: 'On Hover'},
|
{value: 1, title: 'On Hover'},
|
||||||
{value: 2, title: 'When Ctrl is Held'},
|
{value: 2, title: 'When Ctrl is Held'},
|
||||||
{value: 3, title: 'When Meta is Held'},
|
{value: 3, title: 'When Meta is Held'},
|
||||||
|
@ -163,19 +163,8 @@ export default class Scroller extends Module {
|
||||||
|
|
||||||
this.ChatScroller.ready((cls, instances) => {
|
this.ChatScroller.ready((cls, instances) => {
|
||||||
const old_catch = cls.prototype.componentDidCatch,
|
const old_catch = cls.prototype.componentDidCatch,
|
||||||
old_snapshot = cls.prototype.getSnapshotBeforeUpdate,
|
|
||||||
old_render = cls.prototype.render;
|
old_render = cls.prototype.render;
|
||||||
|
|
||||||
if ( old_snapshot )
|
|
||||||
cls.prototype.getSnapshotBeforeUpdate = function() {
|
|
||||||
const out = old_snapshot.call(this);
|
|
||||||
this._ffz_snapshot = out || (this.lastLine && {
|
|
||||||
lastLine: this.lastLine,
|
|
||||||
offsetTop: this.lastLine.offsetTop
|
|
||||||
}) || null;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try catching errors. With any luck, maybe we can
|
// Try catching errors. With any luck, maybe we can
|
||||||
// recover from the error when we re-build?
|
// recover from the error when we re-build?
|
||||||
cls.prototype.componentDidCatch = function(err, info) {
|
cls.prototype.componentDidCatch = function(err, info) {
|
||||||
|
@ -231,7 +220,7 @@ export default class Scroller extends Module {
|
||||||
const children = out?.props?.children?.props?.children,
|
const children = out?.props?.children?.props?.children,
|
||||||
child = children?.[2];
|
child = children?.[2];
|
||||||
|
|
||||||
if ( child?.type?.displayName === 'ChatScrollFooter' )
|
if ( child?.type?.displayName === 'ChatPausedFooter' )
|
||||||
children[2] = this.ffzRenderFooter();
|
children[2] = this.ffzRenderFooter();
|
||||||
} catch(err) { /* no-op */ }
|
} catch(err) { /* no-op */ }
|
||||||
|
|
||||||
|
@ -246,109 +235,37 @@ export default class Scroller extends Module {
|
||||||
this._ffz_installed = true;
|
this._ffz_installed = true;
|
||||||
const inst = this;
|
const inst = this;
|
||||||
|
|
||||||
|
inst.ffz_oldScrollEvent = inst.handleScrollEvent;
|
||||||
|
inst.ffz_oldScroll = inst.scrollToBottom;
|
||||||
|
|
||||||
inst.ffz_outside = true;
|
inst.ffz_outside = true;
|
||||||
inst._ffz_accessor = `_ffz_contains_${last_id++}`;
|
inst._ffz_accessor = `_ffz_contains_${last_id++}`;
|
||||||
|
|
||||||
t.on('tooltips:mousemove', this.ffzTooltipHover, this);
|
t.on('tooltips:mousemove', this.ffzTooltipHover, this);
|
||||||
t.on('tooltips:leave', this.ffzTooltipLeave, this);
|
t.on('tooltips:leave', this.ffzTooltipLeave, this);
|
||||||
|
|
||||||
inst.ffz_oldScrollEvent = inst.handleScrollEvent;
|
|
||||||
inst.ffz_oldScroll = inst.scrollToBottom;
|
|
||||||
|
|
||||||
// New Scroll to Bottom
|
|
||||||
inst.ffz_doScroll = function() {
|
|
||||||
inst._ffz_scroll_frame = null;
|
|
||||||
if ( inst.state.isAutoScrolling && ! inst.state.isPaused ) {
|
|
||||||
if ( inst.ffz_smooth_scroll && ! inst._ffz_one_fast_scroll )
|
|
||||||
inst.smoothScrollBottom();
|
|
||||||
else {
|
|
||||||
inst._ffz_one_fast_scroll = false;
|
|
||||||
inst._ffz_snapshot = null;
|
|
||||||
inst.ffz_oldScroll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inst.scrollToBottom = function() {
|
|
||||||
if ( inst._ffz_scroll_request )
|
|
||||||
return;
|
|
||||||
|
|
||||||
inst._ffz_scroll_request = requestAnimationFrame(inst._scrollToBottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
inst._scrollToBottom = function() {
|
|
||||||
inst._ffz_scroll_request = null;
|
|
||||||
|
|
||||||
// WIP: Trying to fix the scroll position changing so that we can
|
|
||||||
// smooth scroll from the previous position.
|
|
||||||
if ( inst.ffz_smooth_scroll && ! inst._ffz_one_fast_scroll && inst._ffz_snapshot ) {
|
|
||||||
const adjustment = inst._ffz_snapshot && inst._ffz_snapshot.lastLine ? inst._ffz_snapshot.lastLine.offsetTop - inst._ffz_snapshot.offsetTop: 0;
|
|
||||||
if ( inst.scroll && inst.scroll.scrollContent && adjustment != 0 )
|
|
||||||
inst.scroll.scrollContent.scrollTop += adjustment;
|
|
||||||
}
|
|
||||||
|
|
||||||
inst._ffz_snapshot = null;
|
|
||||||
if ( inst.state.isAutoScrolling && ! inst.state.isPaused ) {
|
|
||||||
if ( inst.ffz_smooth_scroll && ! inst._ffz_one_fast_scroll )
|
|
||||||
inst.smoothScrollBottom();
|
|
||||||
else {
|
|
||||||
inst._ffz_one_fast_scroll = false;
|
|
||||||
inst.ffz_oldScroll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// New Scroll Event Handling
|
|
||||||
inst.handleScrollEvent = function(event) {
|
inst.handleScrollEvent = function(event) {
|
||||||
if ( ! inst.scroll || ! inst.scroll.scrollContent )
|
if ( ! inst.scrollRef?.scrollContent )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO: Check for mousedown?
|
|
||||||
|
|
||||||
if ( !(event.which > 0 || event.type === 'mousewheel' || event.type === 'wheel' || event.type === 'touchmove') )
|
if ( !(event.which > 0 || event.type === 'mousewheel' || event.type === 'wheel' || event.type === 'touchmove') )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// How far are we scrolled up?
|
// How far are we scrolled up?
|
||||||
const scroller = inst.scroll.scrollContent,
|
const scroller = inst.scrollRef.scrollContent,
|
||||||
offset = scroller.scrollHeight - scroller.scrollTop - scroller.offsetHeight;
|
offset = scroller.scrollHeight - scroller.scrollTop - scroller.offsetHeight,
|
||||||
|
scrolled_up = offset > 10;
|
||||||
|
|
||||||
// If we're less than 10 pixels from the bottom and we aren't autoscrolling, resume
|
if ( scrolled_up !== inst.state.ffz_scrolled_up )
|
||||||
if ( offset <= 10 && ! inst.state.isAutoScrolling )
|
inst.setState({ffz_scrolled_up: scrolled_up});
|
||||||
inst.resume();
|
|
||||||
|
|
||||||
// If we are autoscrolling and we're more than 10 pixels up, then
|
if ( inst.state.isPaused && scrolled_up )
|
||||||
// stop autoscrolling without setting paused.
|
inst.setLoadMoreEnabled(true);
|
||||||
else if ( inst.state.isAutoScrolling && offset > 10 ) {
|
|
||||||
// If we're paused, unpause.
|
|
||||||
if ( inst.state.isPaused ) {
|
|
||||||
inst.setState({
|
|
||||||
isPaused: false
|
|
||||||
}, () => {
|
|
||||||
if ( inst.props.setPaused )
|
|
||||||
inst.props.setPaused(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
inst.setLoadMoreEnabled(true);
|
if ( inst.state.isPaused && ! scrolled_up )
|
||||||
}
|
inst.ffzMaybeUnpause();
|
||||||
|
else if ( ! inst.state.isPaused && scrolled_up )
|
||||||
inst.setState({
|
inst.pause();
|
||||||
isAutoScrolling: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inst.pause = function() {
|
|
||||||
// If we already aren't scrolling, we don't want to further
|
|
||||||
// pause things.
|
|
||||||
if ( ! inst.state.isAutoScrolling )
|
|
||||||
return;
|
|
||||||
|
|
||||||
inst.setState({
|
|
||||||
isPaused: true
|
|
||||||
}, () => {
|
|
||||||
if ( inst.props.setPaused )
|
|
||||||
inst.props.setPaused(true);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const old_resume = inst.resume;
|
const old_resume = inst.resume;
|
||||||
|
@ -359,9 +276,8 @@ export default class Scroller extends Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
inst.resume = function() {
|
inst.resume = function() {
|
||||||
clearInterval(inst._ffz_hover_timer);
|
inst.setState({ffz_scrolled_up: false});
|
||||||
inst._ffz_hover_timer = null;
|
old_resume.call(this);
|
||||||
old_resume.call(inst);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event Registration
|
// Event Registration
|
||||||
|
@ -383,7 +299,7 @@ export default class Scroller extends Module {
|
||||||
if ( node )
|
if ( node )
|
||||||
node.addEventListener('mousemove', inst.hoverPause);
|
node.addEventListener('mousemove', inst.hoverPause);
|
||||||
|
|
||||||
const scroller = this.scroll && this.scroll.scrollContent;
|
const scroller = this.scrollRef?.scrollContent;
|
||||||
if ( scroller ) {
|
if ( scroller ) {
|
||||||
for(const event of SCROLL_EVENTS) {
|
for(const event of SCROLL_EVENTS) {
|
||||||
scroller.removeEventListener(event, inst.ffz_oldScrollEvent);
|
scroller.removeEventListener(event, inst.ffz_oldScrollEvent);
|
||||||
|
@ -424,7 +340,7 @@ export default class Scroller extends Module {
|
||||||
|
|
||||||
this.ffzUpdateKeyTags();
|
this.ffzUpdateKeyTags();
|
||||||
|
|
||||||
if ( (t.pause_hover && this.ffz_outside) || t.pause < 2 )
|
if ( (t.pause_hover && this.ffz_outside) || this.ffzGetMode() < 2 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const should_pause = this.ffzShouldBePaused(),
|
const should_pause = this.ffzShouldBePaused(),
|
||||||
|
@ -433,7 +349,8 @@ export default class Scroller extends Module {
|
||||||
if ( changed )
|
if ( changed )
|
||||||
if ( should_pause ) {
|
if ( should_pause ) {
|
||||||
this.pause();
|
this.pause();
|
||||||
this.setLoadMoreEnabled(false);
|
if ( ! this.state.ffz_scrolled_up )
|
||||||
|
this.setLoadMoreEnabled(false);
|
||||||
} else
|
} else
|
||||||
this.resume();
|
this.resume();
|
||||||
}
|
}
|
||||||
|
@ -483,7 +400,8 @@ export default class Scroller extends Module {
|
||||||
if ( should_pause ) {
|
if ( should_pause ) {
|
||||||
this.pause();
|
this.pause();
|
||||||
this.ffzInstallHoverTimer();
|
this.ffzInstallHoverTimer();
|
||||||
this.setLoadMoreEnabled(false);
|
if ( ! this.state.ffz_scrolled_up )
|
||||||
|
this.setLoadMoreEnabled(false);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
this.resume();
|
this.resume();
|
||||||
|
@ -500,7 +418,7 @@ export default class Scroller extends Module {
|
||||||
|
|
||||||
cls.prototype.ffzTooltipHover = function(target, tip, event) {
|
cls.prototype.ffzTooltipHover = function(target, tip, event) {
|
||||||
if ( target[this._ffz_accessor] == null ) {
|
if ( target[this._ffz_accessor] == null ) {
|
||||||
const scroller = this.scroll && this.scroll.scrollContent;
|
const scroller = this.scrollRef?.scrollContent;
|
||||||
target[this._ffz_accessor] = scroller ? scroller.contains(target) : false;
|
target[this._ffz_accessor] = scroller ? scroller.contains(target) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,7 +431,7 @@ export default class Scroller extends Module {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( target[this._ffz_accessor] == null ) {
|
if ( target[this._ffz_accessor] == null ) {
|
||||||
const scroller = this.scroll && this.scroll.scrollContent;
|
const scroller = this.scrollRef?.scrollContent;
|
||||||
target[this._ffz_accessor] = scroller ? scroller.contains(target) : false;
|
target[this._ffz_accessor] = scroller ? scroller.contains(target) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,13 +452,13 @@ export default class Scroller extends Module {
|
||||||
if ( ! t.use_keys && this.ffz_use_keys === t.use_keys )
|
if ( ! t.use_keys && this.ffz_use_keys === t.use_keys )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( ! this.scroll || ! this.scroll.root )
|
if ( ! this.scrollRef?.root )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.ffz_use_keys = t.use_keys;
|
this.ffz_use_keys = t.use_keys;
|
||||||
this.scroll.root.classList.toggle('ffz--keys', t.use_keys);
|
this.scrollRef.root.classList.toggle('ffz--keys', t.use_keys);
|
||||||
|
|
||||||
const ds = this.scroll.root.dataset;
|
const ds = this.scrollRef.root.dataset;
|
||||||
|
|
||||||
if ( ! t.use_keys ) {
|
if ( ! t.use_keys ) {
|
||||||
delete ds.alt;
|
delete ds.alt;
|
||||||
|
@ -563,17 +481,34 @@ export default class Scroller extends Module {
|
||||||
if ( since == null )
|
if ( since == null )
|
||||||
since = Date.now() - this.ffz_last_move;
|
since = Date.now() - this.ffz_last_move;
|
||||||
|
|
||||||
const mode = t.pause,
|
if ( this.state.ffz_scrolled_up )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const mode = this.ffzGetMode(),
|
||||||
require_hover = t.pause_hover;
|
require_hover = t.pause_hover;
|
||||||
|
|
||||||
return (! require_hover || ! this.ffz_outside) && this.state.isAutoScrolling && (
|
return (! require_hover || ! this.ffz_outside) && (
|
||||||
(this.ffz_ctrl && (mode === 2 || mode === 6)) ||
|
(this.ffz_ctrl && (mode === 2 || mode === 6)) ||
|
||||||
(this.ffz_meta && (mode === 3 || mode === 7)) ||
|
(this.ffz_meta && (mode === 3 || mode === 7)) ||
|
||||||
(this.ffz_alt && (mode === 4 || mode === 8)) ||
|
(this.ffz_alt && (mode === 4 || mode === 8)) ||
|
||||||
(this.ffz_shift && (mode === 5 || mode === 9)) ||
|
(this.ffz_shift && (mode === 5 || mode === 9)) ||
|
||||||
(! this.ffz_outside && since < t.pause_delay && (mode === 1 || mode > 5))
|
(! this.ffz_outside && since < t.pause_delay && (mode === 1 || mode > 5))
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
cls.prototype.ffzGetMode = function() {
|
||||||
|
let mode = t.pause;
|
||||||
|
if ( mode === 0 && ! this.props.mouseoverPausingDisabled ) {
|
||||||
|
const setting = this.props.pauseSetting;
|
||||||
|
if ( setting === 'MOUSEOVER_ALTKEY' )
|
||||||
|
mode = 8;
|
||||||
|
else if ( setting === 'MOUSEOVER' )
|
||||||
|
mode = 1;
|
||||||
|
else if ( setting === 'ALTKEY' )
|
||||||
|
mode = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
cls.prototype.ffzMaybeUnpause = function() {
|
cls.prototype.ffzMaybeUnpause = function() {
|
||||||
|
@ -587,8 +522,10 @@ export default class Scroller extends Module {
|
||||||
|
|
||||||
cls.prototype.ffzRenderFooter = function() {
|
cls.prototype.ffzRenderFooter = function() {
|
||||||
let msg, cls = '';
|
let msg, cls = '';
|
||||||
if ( this.state.isPaused ) {
|
if ( this.state.ffz_scrolled_up )
|
||||||
const f = t.pause,
|
msg = t.i18n.t('chat.messages-below', 'Chat Paused Due to Scroll');
|
||||||
|
else if ( this.state.isPaused ) {
|
||||||
|
const f = this.ffzGetMode(),
|
||||||
reason = f === 2 ? t.i18n.t('key.ctrl', 'Ctrl Key') :
|
reason = f === 2 ? t.i18n.t('key.ctrl', 'Ctrl Key') :
|
||||||
f === 3 ? t.i18n.t('key.meta', 'Meta Key') :
|
f === 3 ? t.i18n.t('key.meta', 'Meta Key') :
|
||||||
f === 4 ? t.i18n.t('key.alt', 'Alt Key') :
|
f === 4 ? t.i18n.t('key.alt', 'Alt Key') :
|
||||||
|
@ -602,12 +539,10 @@ export default class Scroller extends Module {
|
||||||
msg = t.i18n.t('chat.paused', 'Chat Paused Due to {reason}', {reason});
|
msg = t.i18n.t('chat.paused', 'Chat Paused Due to {reason}', {reason});
|
||||||
cls = 'ffz--freeze-indicator';
|
cls = 'ffz--freeze-indicator';
|
||||||
|
|
||||||
} else if ( this.state.isAutoScrolling )
|
} else
|
||||||
return createElement('div', {
|
return createElement('div', {
|
||||||
className: `chat-scroll-footer__placeholder tw-flex tw-justify-content-center tw-relative ${cls}`
|
className: `chat-scroll-footer__placeholder tw-flex tw-justify-content-center tw-relative ${cls}`
|
||||||
}, null);
|
}, null);
|
||||||
else
|
|
||||||
msg = t.i18n.t('chat.messages-below', 'Chat Paused Due to Scroll');
|
|
||||||
|
|
||||||
return createElement('div', {
|
return createElement('div', {
|
||||||
className: `chat-scroll-footer__placeholder tw-flex tw-justify-content-center tw-relative ${cls}`
|
className: `chat-scroll-footer__placeholder tw-flex tw-justify-content-center tw-relative ${cls}`
|
||||||
|
@ -622,80 +557,6 @@ export default class Scroller extends Module {
|
||||||
}, createElement('div', {
|
}, createElement('div', {
|
||||||
className: 'tw-flex-grow-0'
|
className: 'tw-flex-grow-0'
|
||||||
}, msg)))));
|
}, msg)))));
|
||||||
|
|
||||||
/*return createElement('div', {
|
|
||||||
className: `chat-list__list-footer tw-absolute tw-align-items-center tw-border-radius-medium tw-bottom-0 tw-flex tw-justify-content-center tw-mg-b-1 tw-pd-x-2 tw-pd-y-05 ${cls}`,
|
|
||||||
onClick: this.ffzFastResume
|
|
||||||
}, createElement('div', null, msg));*/
|
|
||||||
|
|
||||||
/*return createElement('div', {
|
|
||||||
className: `chat-list__list-footer tw-absolute tw-align-items-center tw-border-radius-medium tw-bottom-0 tw-flex tw-full-width tw-justify-content-center tw-pd-05 ${cls}`,
|
|
||||||
onClick: this.ffzFastResume
|
|
||||||
}, createElement('div', null, msg));*/
|
|
||||||
}
|
|
||||||
|
|
||||||
cls.prototype.smoothScrollBottom = function() {
|
|
||||||
if ( this._ffz_smooth_animation )
|
|
||||||
cancelAnimationFrame(this._ffz_smooth_animation);
|
|
||||||
|
|
||||||
this.ffz_is_smooth_scrolling = 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,
|
|
||||||
old_time = Date.now();
|
|
||||||
|
|
||||||
const scroll_content = this.scroll.scrollContent;
|
|
||||||
if ( ! scroll_content )
|
|
||||||
return;
|
|
||||||
|
|
||||||
const target_top = scroll_content.scrollHeight - scroll_content.clientHeight,
|
|
||||||
difference = target_top - scroll_content.scrollTop;
|
|
||||||
|
|
||||||
// If we are falling behind speed us up
|
|
||||||
if ( difference > scroll_content.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 * Math.floor(difference / 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
const smoothAnimation = () => {
|
|
||||||
if ( this.state.isPaused || ! this.state.isAutoScrolling )
|
|
||||||
return this.ffz_is_smooth_scrolling = false;
|
|
||||||
|
|
||||||
// See how much time has passed to get a step based off the delta
|
|
||||||
const current_time = Date.now(),
|
|
||||||
delta = current_time - old_time,
|
|
||||||
current_step = step * (delta / 10);
|
|
||||||
|
|
||||||
// we need to move at least one full pixel for scrollTop to do anything in this delta.
|
|
||||||
if ( current_step >= 1 ) {
|
|
||||||
const scroll_top = scroll_content.scrollTop,
|
|
||||||
next_top = scroll_top + current_step,
|
|
||||||
target_top = scroll_content.scrollHeight - scroll_content.clientHeight;
|
|
||||||
|
|
||||||
old_time = current_time;
|
|
||||||
if ( next_top < target_top ) {
|
|
||||||
scroll_content.scrollTop = scroll_top + current_step;
|
|
||||||
this._ffz_smooth_animation = requestAnimationFrame(smoothAnimation);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// We've reached the bottom.
|
|
||||||
scroll_content.scrollTop = target_top;
|
|
||||||
this.ffz_is_smooth_scrolling = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// The frame happened so quick since last update that we haven't moved a full pixel.
|
|
||||||
// Just wait.
|
|
||||||
this._ffz_smooth_animation = requestAnimationFrame(smoothAnimation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
smoothAnimation();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do the thing~
|
// Do the thing~
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue