Fix flickering date
Fix jumping scroll on slicing
This commit is contained in:
parent
51fed91103
commit
731cbd5e7f
@ -43,7 +43,7 @@ import PollElement from "../poll";
|
|||||||
import AudioElement from "../audio";
|
import AudioElement from "../audio";
|
||||||
import { ChatInvite, Message, MessageEntity, MessageMedia, MessageReplyHeader, Photo, PhotoSize, ReactionCount, ReplyMarkup, SponsoredMessage, Update, WebPage } from "../../layer";
|
import { ChatInvite, Message, MessageEntity, MessageMedia, MessageReplyHeader, Photo, PhotoSize, ReactionCount, ReplyMarkup, SponsoredMessage, Update, WebPage } from "../../layer";
|
||||||
import { NULL_PEER_ID, REPLIES_PEER_ID } from "../../lib/mtproto/mtproto_config";
|
import { NULL_PEER_ID, REPLIES_PEER_ID } from "../../lib/mtproto/mtproto_config";
|
||||||
import { FocusDirection } from "../../helpers/fastSmoothScroll";
|
import { FocusDirection, ScrollStartCallbackDimensions } from "../../helpers/fastSmoothScroll";
|
||||||
import useHeavyAnimationCheck, { getHeavyAnimationPromise, dispatchHeavyAnimationEvent, interruptHeavyAnimation } from "../../hooks/useHeavyAnimationCheck";
|
import useHeavyAnimationCheck, { getHeavyAnimationPromise, dispatchHeavyAnimationEvent, interruptHeavyAnimation } from "../../hooks/useHeavyAnimationCheck";
|
||||||
import { fastRaf, fastRafPromise } from "../../helpers/schedulers";
|
import { fastRaf, fastRafPromise } from "../../helpers/schedulers";
|
||||||
import { deferredPromise } from "../../helpers/cancellablePromise";
|
import { deferredPromise } from "../../helpers/cancellablePromise";
|
||||||
@ -119,6 +119,7 @@ type GenerateLocalMessageType<IsService> = IsService extends true ? Message.mess
|
|||||||
|
|
||||||
const SPONSORED_MESSAGE_ID_OFFSET = 1;
|
const SPONSORED_MESSAGE_ID_OFFSET = 1;
|
||||||
const STICKY_OFFSET = 3;
|
const STICKY_OFFSET = 3;
|
||||||
|
const SCROLLED_DOWN_THRESHOLD = 300;
|
||||||
|
|
||||||
export default class ChatBubbles {
|
export default class ChatBubbles {
|
||||||
public bubblesContainer: HTMLDivElement;
|
public bubblesContainer: HTMLDivElement;
|
||||||
@ -207,7 +208,8 @@ export default class ChatBubbles {
|
|||||||
private hoverBubble: HTMLElement;
|
private hoverBubble: HTMLElement;
|
||||||
private hoverReaction: HTMLElement;
|
private hoverReaction: HTMLElement;
|
||||||
private sliceViewportDebounced: DebounceReturnType<ChatBubbles['sliceViewport']>;
|
private sliceViewportDebounced: DebounceReturnType<ChatBubbles['sliceViewport']>;
|
||||||
resizeObserver: ResizeObserver;
|
private resizeObserver: ResizeObserver;
|
||||||
|
private willScrollOnLoad: boolean;
|
||||||
|
|
||||||
// private reactions: Map<number, ReactionsElement>;
|
// private reactions: Map<number, ReactionsElement>;
|
||||||
|
|
||||||
@ -1758,21 +1760,38 @@ export default class ChatBubbles {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public onScroll = () => {
|
public onScroll = (ignoreHeavyAnimation?: boolean, scrollDimensions?: ScrollStartCallbackDimensions) => {
|
||||||
//return;
|
//return;
|
||||||
|
|
||||||
// * В таком случае, кнопка не будет моргать если чат в самом низу, и правильно отработает случай написания нового сообщения и проскролла вниз
|
if(this.isHeavyAnimationInProgress) {
|
||||||
if(this.isHeavyAnimationInProgress && this.scrolledDown) {
|
|
||||||
if(this.sliceViewportDebounced) {
|
if(this.sliceViewportDebounced) {
|
||||||
this.sliceViewportDebounced.clearTimeout();
|
this.sliceViewportDebounced.clearTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
// * В таком случае, кнопка не будет моргать если чат в самом низу, и правильно отработает случай написания нового сообщения и проскролла вниз
|
||||||
|
if(this.scrolledDown && !ignoreHeavyAnimation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(this.chat.topbar.pinnedMessage) {
|
||||||
|
this.chat.topbar.pinnedMessage.setCorrectIndexThrottled(this.scrollable.lastScrollDirection);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.sliceViewportDebounced) {
|
||||||
|
this.sliceViewportDebounced();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setStickyDateManually();
|
||||||
}
|
}
|
||||||
|
|
||||||
//lottieLoader.checkAnimations(false, 'chat');
|
//lottieLoader.checkAnimations(false, 'chat');
|
||||||
|
|
||||||
const distanceToEnd = this.scrollable.getDistanceToEnd();
|
if(scrollDimensions && scrollDimensions.distanceToEnd < SCROLLED_DOWN_THRESHOLD && this.scrolledDown) {
|
||||||
if(/* !IS_TOUCH_SUPPORTED && */this.scrollable.lastScrollDirection !== 0 && distanceToEnd > 0) {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const distanceToEnd = scrollDimensions?.distanceToEnd ?? this.scrollable.getDistanceToEnd();
|
||||||
|
if(/* !IS_TOUCH_SUPPORTED && */(this.scrollable.lastScrollDirection !== 0 && distanceToEnd > 0) || scrollDimensions) {
|
||||||
if(this.isScrollingTimeout) {
|
if(this.isScrollingTimeout) {
|
||||||
clearTimeout(this.isScrollingTimeout);
|
clearTimeout(this.isScrollingTimeout);
|
||||||
} else if(!this.chatInner.classList.contains('is-scrolling')) {
|
} else if(!this.chatInner.classList.contains('is-scrolling')) {
|
||||||
@ -1782,26 +1801,16 @@ export default class ChatBubbles {
|
|||||||
this.isScrollingTimeout = window.setTimeout(() => {
|
this.isScrollingTimeout = window.setTimeout(() => {
|
||||||
this.chatInner.classList.remove('is-scrolling');
|
this.chatInner.classList.remove('is-scrolling');
|
||||||
this.isScrollingTimeout = 0;
|
this.isScrollingTimeout = 0;
|
||||||
}, 1350);
|
}, 1350 + (scrollDimensions?.duration ?? 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(distanceToEnd < 300 && (this.scrollable.loadedAll.bottom || this.chat.setPeerPromise || !this.peerId)) {
|
if(distanceToEnd < SCROLLED_DOWN_THRESHOLD && (this.scrollable.loadedAll.bottom || this.chat.setPeerPromise || !this.peerId)) {
|
||||||
this.bubblesContainer.classList.add('scrolled-down');
|
this.bubblesContainer.classList.add('scrolled-down');
|
||||||
this.scrolledDown = true;
|
this.scrolledDown = true;
|
||||||
} else if(this.bubblesContainer.classList.contains('scrolled-down')) {
|
} else if(this.bubblesContainer.classList.contains('scrolled-down')) {
|
||||||
this.bubblesContainer.classList.remove('scrolled-down');
|
this.bubblesContainer.classList.remove('scrolled-down');
|
||||||
this.scrolledDown = false;
|
this.scrolledDown = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.chat.topbar.pinnedMessage) {
|
|
||||||
this.chat.topbar.pinnedMessage.setCorrectIndexThrottled(this.scrollable.lastScrollDirection);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.sliceViewportDebounced) {
|
|
||||||
this.sliceViewportDebounced();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setStickyDateManually();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public setScroll() {
|
public setScroll() {
|
||||||
@ -1917,6 +1926,7 @@ export default class ChatBubbles {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.scrollable.ignoreNextScrollEvent();
|
||||||
if(permanent && this.chat.selection.isSelecting) {
|
if(permanent && this.chat.selection.isSelecting) {
|
||||||
this.chat.selection.deleteSelectedMids(this.peerId, mids);
|
this.chat.selection.deleteSelectedMids(this.peerId, mids);
|
||||||
}
|
}
|
||||||
@ -2080,7 +2090,11 @@ export default class ChatBubbles {
|
|||||||
const diff = rowsWrapperHeight - 54;
|
const diff = rowsWrapperHeight - 54;
|
||||||
return rect.height + diff; */
|
return rect.height + diff; */
|
||||||
} : undefined,
|
} : undefined,
|
||||||
fallbackToElementStartWhenCentering
|
fallbackToElementStartWhenCentering,
|
||||||
|
startCallback: (dimensions) => {
|
||||||
|
// this.onScroll(true, this.scrolledDown && dimensions.distanceToEnd <= SCROLLED_DOWN_THRESHOLD ? undefined : dimensions);
|
||||||
|
this.onScroll(true, dimensions);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// fix flickering date when opening unread chat and focusing message
|
// fix flickering date when opening unread chat and focusing message
|
||||||
@ -2409,7 +2423,8 @@ export default class ChatBubbles {
|
|||||||
this.chat.dispatchEvent('setPeer', lastMsgId, false);
|
this.chat.dispatchEvent('setPeer', lastMsgId, false);
|
||||||
} else if(topMessage && !isJump) {
|
} else if(topMessage && !isJump) {
|
||||||
//this.log('will scroll down', this.scroll.scrollTop, this.scroll.scrollHeight);
|
//this.log('will scroll down', this.scroll.scrollTop, this.scroll.scrollHeight);
|
||||||
scrollable.setScrollTopSilently(scrollable.scrollHeight);
|
// scrollable.setScrollTopSilently(scrollable.scrollHeight);
|
||||||
|
this.scrollToEnd();
|
||||||
this.chat.dispatchEvent('setPeer', lastMsgId, true);
|
this.chat.dispatchEvent('setPeer', lastMsgId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2473,6 +2488,12 @@ export default class ChatBubbles {
|
|||||||
|
|
||||||
this.lazyLoadQueue.lock();
|
this.lazyLoadQueue.lock();
|
||||||
|
|
||||||
|
const haveToScrollToBubble = (topMessage && (isJump || samePeer)) || isTarget;
|
||||||
|
const fromUp = maxBubbleId > 0 && (maxBubbleId < lastMsgId || lastMsgId < 0);
|
||||||
|
const scrollFromDown = !fromUp && samePeer;
|
||||||
|
const scrollFromUp = !scrollFromDown && fromUp/* && (samePeer || forwardingUnread) */;
|
||||||
|
this.willScrollOnLoad = scrollFromDown || scrollFromUp;
|
||||||
|
|
||||||
let result: ReturnType<ChatBubbles['getHistory']>;
|
let result: ReturnType<ChatBubbles['getHistory']>;
|
||||||
if(!savedPosition) {
|
if(!savedPosition) {
|
||||||
result = this.getHistory(lastMsgId, true, isJump, additionMsgId);
|
result = this.getHistory(lastMsgId, true, isJump, additionMsgId);
|
||||||
@ -2547,11 +2568,10 @@ export default class ChatBubbles {
|
|||||||
const distance = savedPosition.top - top;
|
const distance = savedPosition.top - top;
|
||||||
scrollable.scrollTop += distance;
|
scrollable.scrollTop += distance;
|
||||||
} */
|
} */
|
||||||
} else if((topMessage && isJump) || isTarget) {
|
} else if(haveToScrollToBubble) {
|
||||||
const fromUp = maxBubbleId > 0 && (maxBubbleId < lastMsgId || lastMsgId < 0);
|
if(scrollFromDown) {
|
||||||
if(!fromUp && samePeer) {
|
|
||||||
scrollable.setScrollTopSilently(99999);
|
scrollable.setScrollTopSilently(99999);
|
||||||
} else if(fromUp/* && (samePeer || forwardingUnread) */) {
|
} else if(scrollFromUp) {
|
||||||
scrollable.setScrollTopSilently(0);
|
scrollable.setScrollTopSilently(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2564,7 +2584,7 @@ export default class ChatBubbles {
|
|||||||
// ! sometimes there can be no bubble
|
// ! sometimes there can be no bubble
|
||||||
if(bubble) {
|
if(bubble) {
|
||||||
this.scrollToBubble(bubble, followingUnread ? 'start' : 'center', !samePeer ? FocusDirection.Static : undefined);
|
this.scrollToBubble(bubble, followingUnread ? 'start' : 'center', !samePeer ? FocusDirection.Static : undefined);
|
||||||
if(!followingUnread) {
|
if(!followingUnread && isTarget) {
|
||||||
this.highlightBubble(bubble);
|
this.highlightBubble(bubble);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3971,7 +3991,7 @@ export default class ChatBubbles {
|
|||||||
|
|
||||||
if(this.getRenderedLength() && !this.chat.setPeerPromise) {
|
if(this.getRenderedLength() && !this.chat.setPeerPromise) {
|
||||||
const viewportSlice = this.getViewportSlice();
|
const viewportSlice = this.getViewportSlice();
|
||||||
this.deleteViewportSlice(viewportSlice);
|
this.deleteViewportSlice(viewportSlice, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollSaver.save();
|
scrollSaver.save();
|
||||||
@ -4032,12 +4052,20 @@ export default class ChatBubbles {
|
|||||||
const dateMessage = this.dateMessages[timestamp];
|
const dateMessage = this.dateMessages[timestamp];
|
||||||
dateMessage.div.classList.add('is-sticky');
|
dateMessage.div.classList.add('is-sticky');
|
||||||
} */
|
} */
|
||||||
|
|
||||||
const middleware = this.getMiddleware();
|
const middleware = this.getMiddleware();
|
||||||
setTimeout(() => {
|
const callback = () => {
|
||||||
if(!middleware()) return;
|
if(!middleware()) return;
|
||||||
this.bubblesContainer.classList.add('has-sticky-dates');
|
this.bubblesContainer.classList.add('has-sticky-dates');
|
||||||
}, 600);
|
};
|
||||||
|
|
||||||
|
if(this.willScrollOnLoad) {
|
||||||
|
callback();
|
||||||
|
} else {
|
||||||
|
setTimeout(callback, 600);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.willScrollOnLoad = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4489,15 +4517,33 @@ export default class ChatBubbles {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public deleteViewportSlice(slice: ReturnType<ChatBubbles['getViewportSlice']>) {
|
public deleteViewportSlice(slice: ReturnType<ChatBubbles['getViewportSlice']>, ignoreScrollSaving?: boolean) {
|
||||||
|
// return;
|
||||||
|
|
||||||
const {invisibleTop, invisibleBottom} = slice;
|
const {invisibleTop, invisibleBottom} = slice;
|
||||||
const invisible = invisibleTop.concat(invisibleBottom);
|
const invisible = invisibleTop.concat(invisibleBottom);
|
||||||
|
if(!invisible.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(invisibleTop.length) this.setLoaded('top', false);
|
if(invisibleTop.length) this.setLoaded('top', false);
|
||||||
if(invisibleBottom.length) this.setLoaded('bottom', false);
|
if(invisibleBottom.length) this.setLoaded('bottom', false);
|
||||||
|
|
||||||
const mids = invisible.map(({element}) => +element.dataset.mid);
|
const mids = invisible.map(({element}) => +element.dataset.mid);
|
||||||
|
|
||||||
|
let scrollSaver: ScrollSaver;
|
||||||
|
if(!!invisibleTop.length !== !!invisibleBottom.length && !ignoreScrollSaving) {
|
||||||
|
scrollSaver = new ScrollSaver(this.scrollable, !!invisibleTop.length);
|
||||||
|
scrollSaver.save();
|
||||||
|
}
|
||||||
|
|
||||||
this.deleteMessagesByIds(mids, false, true);
|
this.deleteMessagesByIds(mids, false, true);
|
||||||
|
|
||||||
|
if(scrollSaver) {
|
||||||
|
scrollSaver.restore();
|
||||||
|
} else if(invisibleTop.length) {
|
||||||
|
this.scrollable.lastScrollPosition = this.scrollable.scrollTop;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sliceViewport(ignoreHeavyAnimation?: boolean) {
|
public sliceViewport(ignoreHeavyAnimation?: boolean) {
|
||||||
@ -4511,7 +4557,7 @@ export default class ChatBubbles {
|
|||||||
const slice = this.getViewportSlice();
|
const slice = this.getViewportSlice();
|
||||||
// if(IS_SAFARI) slice.invisibleTop = [];
|
// if(IS_SAFARI) slice.invisibleTop = [];
|
||||||
this.deleteViewportSlice(slice);
|
this.deleteViewportSlice(slice);
|
||||||
// scrollSaver.restore(false);
|
// scrollSaver.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
private setLoaded(side: SliceSides, value: boolean, checkPlaceholders = true) {
|
private setLoaded(side: SliceSides, value: boolean, checkPlaceholders = true) {
|
||||||
@ -4641,7 +4687,7 @@ export default class ChatBubbles {
|
|||||||
|
|
||||||
const isBroadcast = this.appPeersManager.isBroadcast(peerId);
|
const isBroadcast = this.appPeersManager.isBroadcast(peerId);
|
||||||
//console.time('appImManager call getHistory');
|
//console.time('appImManager call getHistory');
|
||||||
const pageCount = Math.min(30, windowSize.height / 48/* * 1.25 */ | 0);
|
const pageCount = Math.min(30, windowSize.height / 40/* * 1.25 */ | 0);
|
||||||
//const loadCount = Object.keys(this.bubbles).length > 0 ? 50 : pageCount;
|
//const loadCount = Object.keys(this.bubbles).length > 0 ? 50 : pageCount;
|
||||||
const realLoadCount = isBroadcast ? 20 : (Object.keys(this.bubbles).length > 0 ? Math.max(35, pageCount) : pageCount);
|
const realLoadCount = isBroadcast ? 20 : (Object.keys(this.bubbles).length > 0 ? Math.max(35, pageCount) : pageCount);
|
||||||
//const realLoadCount = pageCount;//const realLoadCount = 50;
|
//const realLoadCount = pageCount;//const realLoadCount = 50;
|
||||||
@ -4753,7 +4799,11 @@ export default class ChatBubbles {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(justLoad) {
|
if(justLoad) {
|
||||||
this.scrollable.onScroll(); // нужно делать из-за ранней прогрузки
|
// нужно делать из-за ранней прогрузки
|
||||||
|
this.scrollable.onScroll();
|
||||||
|
// fastRaf(() => {
|
||||||
|
// this.scrollable.checkForTriggers();
|
||||||
|
// });
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//console.timeEnd('appImManager call getHistory');
|
//console.timeEnd('appImManager call getHistory');
|
||||||
@ -4772,6 +4822,8 @@ export default class ChatBubbles {
|
|||||||
cached = false;
|
cached = false;
|
||||||
promise = processPromise(result);
|
promise = processPromise(result);
|
||||||
} else if(justLoad) {
|
} else if(justLoad) {
|
||||||
|
// нужно делать из-за ранней прогрузки
|
||||||
|
this.scrollable.onScroll();
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
cached = true;
|
cached = true;
|
||||||
|
@ -179,7 +179,8 @@ export class ScrollableBase {
|
|||||||
this.lastScrollDirection = this.lastScrollPosition === scrollPosition ? 0 : (this.lastScrollPosition < scrollPosition ? 1 : -1); // * 1 - bottom, -1 - top
|
this.lastScrollDirection = this.lastScrollPosition === scrollPosition ? 0 : (this.lastScrollPosition < scrollPosition ? 1 : -1); // * 1 - bottom, -1 - top
|
||||||
this.lastScrollPosition = scrollPosition;
|
this.lastScrollPosition = scrollPosition;
|
||||||
|
|
||||||
if(this.onAdditionalScroll && this.lastScrollDirection !== 0) {
|
// lastScrollDirection check is useless here, every callback should decide on its own
|
||||||
|
if(this.onAdditionalScroll/* && this.lastScrollDirection !== 0 */) {
|
||||||
this.onAdditionalScroll();
|
this.onAdditionalScroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,6 +281,12 @@ export default class Scrollable extends ScrollableBase {
|
|||||||
|
|
||||||
public setScrollTopSilently(value: number) {
|
public setScrollTopSilently(value: number) {
|
||||||
this.lastScrollPosition = value;
|
this.lastScrollPosition = value;
|
||||||
|
this.ignoreNextScrollEvent();
|
||||||
|
|
||||||
|
this.scrollTop = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ignoreNextScrollEvent() {
|
||||||
if(this.removeHeavyAnimationListener) {
|
if(this.removeHeavyAnimationListener) {
|
||||||
this.removeScrollListener();
|
this.removeScrollListener();
|
||||||
this.container.addEventListener('scroll', (e) => {
|
this.container.addEventListener('scroll', (e) => {
|
||||||
@ -287,8 +294,6 @@ export default class Scrollable extends ScrollableBase {
|
|||||||
this.addScrollListener();
|
this.addScrollListener();
|
||||||
}, {capture: true, passive: false, once: true});
|
}, {capture: true, passive: false, once: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.scrollTop = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get scrollHeight() {
|
get scrollHeight() {
|
||||||
|
@ -24,6 +24,15 @@ export enum FocusDirection {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type ScrollGetNormalSizeCallback = (options: {rect: DOMRect}) => number;
|
export type ScrollGetNormalSizeCallback = (options: {rect: DOMRect}) => number;
|
||||||
|
export type ScrollStartCallbackDimensions = {
|
||||||
|
scrollSize: number,
|
||||||
|
scrollPosition: number,
|
||||||
|
distanceToEnd: number,
|
||||||
|
path: number,
|
||||||
|
duration: number,
|
||||||
|
containerRect: DOMRect,
|
||||||
|
elementRect: DOMRect,
|
||||||
|
};
|
||||||
|
|
||||||
export type ScrollOptions = {
|
export type ScrollOptions = {
|
||||||
container: HTMLElement,
|
container: HTMLElement,
|
||||||
@ -35,7 +44,8 @@ export type ScrollOptions = {
|
|||||||
forceDuration?: number,
|
forceDuration?: number,
|
||||||
axis?: 'x' | 'y',
|
axis?: 'x' | 'y',
|
||||||
getNormalSize?: ScrollGetNormalSizeCallback,
|
getNormalSize?: ScrollGetNormalSizeCallback,
|
||||||
fallbackToElementStartWhenCentering?: HTMLElement
|
fallbackToElementStartWhenCentering?: HTMLElement,
|
||||||
|
startCallback?: (dimensions: ScrollStartCallbackDimensions) => void
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function fastSmoothScroll(options: ScrollOptions) {
|
export default function fastSmoothScroll(options: ScrollOptions) {
|
||||||
@ -266,6 +276,19 @@ function scrollWithJs(options: ScrollOptions): Promise<void> {
|
|||||||
|
|
||||||
}); */
|
}); */
|
||||||
|
|
||||||
|
if(options.startCallback) {
|
||||||
|
const distanceToEnd = scrollSize - Math.round(target + container[axis === 'y' ? 'offsetHeight' : 'offsetWidth']);
|
||||||
|
options.startCallback({
|
||||||
|
scrollSize,
|
||||||
|
scrollPosition,
|
||||||
|
distanceToEnd,
|
||||||
|
path,
|
||||||
|
duration,
|
||||||
|
containerRect,
|
||||||
|
elementRect
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return animateSingle(tick, container);
|
return animateSingle(tick, container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user