mirror of
https://github.com/discourse/discourse.git
synced 2024-11-27 11:53:44 +08:00
UX: Prevent initial jump when dragging topic timeline scroller (#23291)
Previously, when dragging the timeline scroller, we would position it purely based on the current cursor position. That means that if you started dragging it from anywhere other than the centre, the scroller will 'jump' suddenly to centre itself on the cursor. This commit measures the offset of your cursor when the drag starts, and maintains it throughout the drag. So for example, if you start dragging at the bottom of the scroller and drag one pixel up, the scroller will only move by 1px. This should make the UX much smoother, especially on large topics.
This commit is contained in:
parent
6f1d666323
commit
81d8c6ba6c
|
@ -73,7 +73,11 @@
|
|||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="timeline-scrollarea" style={{this.timelineScrollareaStyle}}>
|
||||
<div
|
||||
class="timeline-scrollarea"
|
||||
style={{this.timelineScrollareaStyle}}
|
||||
{{did-insert this.registerScrollarea}}
|
||||
>
|
||||
<div
|
||||
class="timeline-padding"
|
||||
style={{this.beforePadding}}
|
||||
|
@ -89,6 +93,7 @@
|
|||
@didStartDrag={{this.didStartDrag}}
|
||||
@dragMove={{this.dragMove}}
|
||||
@didEndDrag={{this.didEndDrag}}
|
||||
{{did-insert this.registerScroller}}
|
||||
/>
|
||||
<div
|
||||
class="timeline-padding"
|
||||
|
|
|
@ -37,6 +37,9 @@ export default class TopicTimelineScrollArea extends Component {
|
|||
@tracked excerpt = "";
|
||||
|
||||
intersectionObserver = null;
|
||||
scrollareaElement = null;
|
||||
scrollerElement = null;
|
||||
dragOffset = null;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
|
@ -272,17 +275,33 @@ export default class TopicTimelineScrollArea extends Component {
|
|||
|
||||
@bind
|
||||
updatePercentage(e) {
|
||||
// pageY for mouse and mobile
|
||||
const y = e.pageY || e.touches[0].pageY;
|
||||
const area = document.querySelector(".timeline-scrollarea");
|
||||
const areaTop = domUtils.offset(area).top;
|
||||
const currentCursorY = e.pageY || e.touches[0].pageY;
|
||||
|
||||
this.percentage = this.clamp(parseFloat(y - areaTop) / area.offsetHeight);
|
||||
const desiredScrollerCentre = currentCursorY - this.dragOffset;
|
||||
|
||||
const areaTop = domUtils.offset(this.scrollareaElement).top;
|
||||
const areaHeight = this.scrollareaElement.offsetHeight;
|
||||
const scrollerHeight = this.scrollerElement.offsetHeight;
|
||||
|
||||
// The range of possible positions for the centre of the scroller
|
||||
const scrollableTop = areaTop + scrollerHeight / 2;
|
||||
const scrollableHeight = areaHeight - scrollerHeight;
|
||||
|
||||
this.percentage = this.clamp(
|
||||
parseFloat(desiredScrollerCentre - scrollableTop) / scrollableHeight
|
||||
);
|
||||
this.commit();
|
||||
}
|
||||
|
||||
@bind
|
||||
didStartDrag() {
|
||||
didStartDrag(event) {
|
||||
const y = event.pageY || event.touches[0].pageY;
|
||||
|
||||
const scrollerCentre =
|
||||
domUtils.offset(this.scrollerElement).top +
|
||||
this.scrollerElement.offsetHeight / 2;
|
||||
|
||||
this.dragOffset = y - scrollerCentre;
|
||||
this.dragging = true;
|
||||
}
|
||||
|
||||
|
@ -296,6 +315,7 @@ export default class TopicTimelineScrollArea extends Component {
|
|||
@bind
|
||||
didEndDrag() {
|
||||
this.dragging = false;
|
||||
this.dragOffset = null;
|
||||
this.commit();
|
||||
}
|
||||
|
||||
|
@ -393,6 +413,16 @@ export default class TopicTimelineScrollArea extends Component {
|
|||
return this.clamp(parseFloat(postIndex) / total);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
registerScrollarea(element) {
|
||||
this.scrollareaElement = element;
|
||||
}
|
||||
|
||||
@action
|
||||
registerScroller(element) {
|
||||
this.scrollerElement = element;
|
||||
}
|
||||
}
|
||||
|
||||
export function scrollareaHeight() {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
didEndDrag=@didEndDrag
|
||||
dragMove=@dragMove
|
||||
}}
|
||||
...attributes
|
||||
>
|
||||
{{#if @fullscreen}}
|
||||
<div class="timeline-scroller-content">
|
||||
|
|
Loading…
Reference in New Issue
Block a user