Improve mobile scrolling

cache
Varun Patil 2022-10-11 17:49:31 -07:00
parent e6d1d96e2f
commit 889fd65390
1 changed files with 50 additions and 17 deletions

View File

@ -73,7 +73,10 @@
<!-- Timeline scroller --> <!-- Timeline scroller -->
<div ref="timelineScroll" class="timeline-scroll" <div ref="timelineScroll" class="timeline-scroll"
v-bind:class="{ scrolling }" v-bind:class="{
'scrolling-recycler': scrollingRecycler,
'scrolling-timeline': scrollingTimeline,
}"
@mousemove="timelineHover" @mousemove="timelineHover"
@touchmove="timelineTouch" @touchmove="timelineTouch"
@mouseleave="timelineLeave" @mouseleave="timelineLeave"
@ -82,7 +85,8 @@
:style="{ transform: `translateY(${timelineCursorY}px)` }"></span> :style="{ transform: `translateY(${timelineCursorY}px)` }"></span>
<span class="cursor hv" <span class="cursor hv"
:style="{ transform: `translateY(${timelineHoverCursorY}px)` }"> :style="{ transform: `translateY(${timelineHoverCursorY}px)` }">
{{ timelineHoverCursorText }} <div class="text"> {{ timelineHoverCursorText }} </div>
<div class="icon"> <ScrollIcon :size="18" /> </div>
</span> </span>
<div v-for="tick of visibleTimelineTicks" :key="tick.dayId" <div v-for="tick of visibleTimelineTicks" :key="tick.dayId"
@ -207,6 +211,7 @@ import OpenInNewIcon from 'vue-material-design-icons/OpenInNew.vue';
import PeopleIcon from 'vue-material-design-icons/AccountMultiple.vue'; import PeopleIcon from 'vue-material-design-icons/AccountMultiple.vue';
import ImageMultipleIcon from 'vue-material-design-icons/ImageMultiple.vue'; import ImageMultipleIcon from 'vue-material-design-icons/ImageMultiple.vue';
import CloseIcon from 'vue-material-design-icons/Close.vue'; import CloseIcon from 'vue-material-design-icons/Close.vue';
import ScrollIcon from 'vue-material-design-icons/UnfoldMoreHorizontal.vue';
const SCROLL_LOAD_DELAY = 100; // Delay in loading data when scrolling const SCROLL_LOAD_DELAY = 100; // Delay in loading data when scrolling
const MAX_PHOTO_WIDTH = 175; // Max width of a photo const MAX_PHOTO_WIDTH = 175; // Max width of a photo
@ -246,6 +251,7 @@ for (const [key, value] of Object.entries(API_ROUTES)) {
PeopleIcon, PeopleIcon,
ImageMultipleIcon, ImageMultipleIcon,
CloseIcon, CloseIcon,
ScrollIcon,
} }
}) })
export default class Timeline extends Mixins(GlobalMixin, UserConfig) { export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
@ -281,10 +287,14 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
private currentStart = 0; private currentStart = 0;
/** Current end index */ /** Current end index */
private currentEnd = 0; private currentEnd = 0;
/** Scrolling currently */ /** Scrolling recycler currently */
private scrolling = false; private scrollingRecycler = false;
/** Scrolling timer */ /** Scrolling recycler timer */
private scrollTimer = null as number | null; private scrollingRecyclerTimer = null as number | null;
/** Scrolling using the timeline currently */
private scrollingTimeline = false;
/** Scrolling timeline timer */
private scrollingTimelineTimer = null as number | null;
/** Resizing timer */ /** Resizing timer */
private resizeTimer = null as number | null; private resizeTimer = null as number | null;
/** View size reflow timer */ /** View size reflow timer */
@ -445,13 +455,11 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
this.timelineCursorY = event ? event.target.scrollTop * this.timelineHeight / this.viewHeight : 0; this.timelineCursorY = event ? event.target.scrollTop * this.timelineHeight / this.viewHeight : 0;
this.timelineMoveHoverCursor(this.timelineCursorY); this.timelineMoveHoverCursor(this.timelineCursorY);
if (this.scrollTimer) { if (this.scrollingRecyclerTimer) window.clearTimeout(this.scrollingRecyclerTimer);
window.clearTimeout(this.scrollTimer); this.scrollingRecycler = true;
} this.scrollingRecyclerTimer = window.setTimeout(() => {
this.scrolling = true; this.scrollingRecycler = false;
this.scrollTimer = window.setTimeout(() => { this.scrollingRecyclerTimer = null;
this.scrolling = false;
this.scrollTimer = null;
}, 1500); }, 1500);
} }
@ -1048,6 +1056,7 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
timelineClick(event: MouseEvent) { timelineClick(event: MouseEvent) {
const recycler: any = this.$refs.recycler; const recycler: any = this.$refs.recycler;
recycler.scrollToPosition(this.getTimelinePosition(event.offsetY)); recycler.scrollToPosition(this.getTimelinePosition(event.offsetY));
this.handleTimelineScroll();
} }
/** Handle touch on right timeline */ /** Handle touch on right timeline */
@ -1058,6 +1067,17 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
recycler.scrollToPosition(this.getTimelinePosition(y)); recycler.scrollToPosition(this.getTimelinePosition(y));
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
this.handleTimelineScroll();
}
/** Update that timeline is being used to scroll recycler */
handleTimelineScroll() {
if (this.scrollingTimelineTimer) window.clearTimeout(this.scrollingTimelineTimer);
this.scrollingTimeline = true;
this.scrollingTimelineTimer = window.setTimeout(() => {
this.scrollingTimeline = false;
this.scrollingTimelineTimer = null;
}, 1500);
} }
/** Get recycler equivalent position from event */ /** Get recycler equivalent position from event */
@ -1448,16 +1468,24 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
opacity: 0; opacity: 0;
transition: opacity .2s ease-in-out; transition: opacity .2s ease-in-out;
// Show ticks on hover or scroll of main window // Show timeline on hover or scroll of main window
&:hover, &.scrolling { &:hover, &.scrolling-recycler {
opacity: 1; opacity: 1;
} }
// Hide ticks on mobile unless hovering // Hide ticks on mobile unless hovering
@include phone { @include phone {
&:not(:hover) > .tick { &:not(.scrolling-timeline) {
opacity: 0; .cursor.hv {
left: 15px;
border: 2px solid var(--color-primary);
border-radius: 10px;
> .text { display: none; }
> .icon { display: block; }
} }
> .tick { opacity: 0; }
}
.cursor.st { display: none; }
} }
> .tick { > .tick {
@ -1511,6 +1539,11 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
z-index: 100; z-index: 100;
font-size: 0.95em; font-size: 0.95em;
font-weight: 600; font-weight: 600;
> .icon {
display: none;
transform: translateX(-5px);
}
} }
} }
&:hover > .cursor.st { &:hover > .cursor.st {