fix(scroll): simplify scroll

This commit is contained in:
Manu Mtz.-Almeida
2018-01-29 18:55:16 +01:00
parent 619f929f97
commit 7e81e63294
6 changed files with 63 additions and 44 deletions

View File

@ -272,10 +272,8 @@ export class Gesture {
let startPos = positions.length - 1; let startPos = positions.length - 1;
// move pointer to position measured 100ms ago // move pointer to position measured 100ms ago
for (; while (startPos > 0 && positions[startPos] > timeRange) {
startPos > 0 && positions[startPos] > timeRange; startPos -= 3;
startPos -= 3) {
// TODO why is this empty?
} }
if (startPos > 1) { if (startPos > 1) {

View File

@ -1,4 +1,4 @@
import { Component, Element, Event, EventEmitter, Listen, Method, Prop, State, Watch } from '@stencil/core'; import { Component, Element, Event, EventEmitter, EventListenerEnable, Listen, Method, Prop, State, Watch } from '@stencil/core';
import { DomController, ScrollDetail, StencilElement } from '../../index'; import { DomController, ScrollDetail, StencilElement } from '../../index';
const enum Position { const enum Position {
@ -14,7 +14,7 @@ const enum Position {
export class InfiniteScroll { export class InfiniteScroll {
private thrPx = 0; private thrPx = 0;
private thrPc = 0.15; private thrPc = 0;
private scrollEl: HTMLIonScrollElement; private scrollEl: HTMLIonScrollElement;
private didFire = false; private didFire = false;
private isBusy = false; private isBusy = false;
@ -24,7 +24,7 @@ export class InfiniteScroll {
@State() isLoading = false; @State() isLoading = false;
@Prop({ context: 'dom' }) dom: DomController; @Prop({ context: 'dom' }) dom: DomController;
@Prop({ context: 'enableListener' }) enableListener: any; @Prop({ context: 'enableListener' }) enableListener: EventListenerEnable;
/** /**
* @input {string} The threshold distance from the bottom * @input {string} The threshold distance from the bottom
@ -142,14 +142,6 @@ export class InfiniteScroll {
return 4; return 4;
} }
private canStart(): boolean {
return (
!this.disabled &&
!this.isBusy &&
this.scrollEl &&
!this.isLoading);
}
/** /**
* Call `complete()` within the `infinite` output event handler when * Call `complete()` within the `infinite` output event handler when
* your async operation has completed. For example, the `loading` * your async operation has completed. For example, the `loading`
@ -212,11 +204,20 @@ export class InfiniteScroll {
* Pass a promise inside `waitFor()` within the `infinite` output event handler in order to * Pass a promise inside `waitFor()` within the `infinite` output event handler in order to
* change state of infiniteScroll to "complete" * change state of infiniteScroll to "complete"
*/ */
@Method()
waitFor(action: Promise<any>) { waitFor(action: Promise<any>) {
const enable = this.complete.bind(this); const enable = this.complete.bind(this);
action.then(enable, enable); action.then(enable, enable);
} }
private canStart(): boolean {
return (
!this.disabled &&
!this.isBusy &&
this.scrollEl &&
!this.isLoading);
}
private enableScrollEvents(shouldListen: boolean) { private enableScrollEvents(shouldListen: boolean) {
this.enableListener(this, 'ionScroll', shouldListen, this.scrollEl); this.enableListener(this, 'ionScroll', shouldListen, this.scrollEl);
} }

View File

@ -66,8 +66,20 @@ export class Modal {
@Prop({ context: 'config' }) config: Config; @Prop({ context: 'config' }) config: Config;
@Prop({ context: 'dom' }) dom: DomController; @Prop({ context: 'dom' }) dom: DomController;
@Prop() mode: string; /**
* @input {string} The color to use from your Sass `$colors` map.
* Default options are: `"primary"`, `"secondary"`, `"danger"`, `"light"`, and `"dark"`.
* For more information, see [Theming your App](/docs/theming/theming-your-app).
*/
@Prop() color: string; @Prop() color: string;
/**
* @input {string} The mode determines which platform styles to use.
* Possible values are: `"ios"` or `"md"`.
* For more information, see [Platform Styles](/docs/theming/platform-specific-styles).
*/
@Prop() mode: 'ios' | 'md';
@Prop() component: any; @Prop() component: any;
@Prop() data: any = {}; @Prop() data: any = {};
@Prop() cssClass: string; @Prop() cssClass: string;

View File

@ -67,8 +67,20 @@ export class Popover {
@Prop({ context: 'config' }) config: Config; @Prop({ context: 'config' }) config: Config;
@Prop({ context: 'dom' }) dom: DomController; @Prop({ context: 'dom' }) dom: DomController;
@Prop() mode: string; /**
* @input {string} The color to use from your Sass `$colors` map.
* Default options are: `"primary"`, `"secondary"`, `"danger"`, `"light"`, and `"dark"`.
* For more information, see [Theming your App](/docs/theming/theming-your-app).
*/
@Prop() color: string; @Prop() color: string;
/**
* @input {string} The mode determines which platform styles to use.
* Possible values are: `"ios"` or `"md"`.
* For more information, see [Platform Styles](/docs/theming/platform-specific-styles).
*/
@Prop() mode: 'ios' | 'md';
@Prop() component: string; @Prop() component: string;
@Prop() data: any = {}; @Prop() data: any = {};
@Prop() cssClass: string; @Prop() cssClass: string;

View File

@ -49,9 +49,6 @@ export class ReorderGroup {
@Prop() disabled = true; @Prop() disabled = true;
/**
* @input {string} Which side of the view the ion-reorder should be placed. Default `"end"`.
*/
@Watch('disabled') @Watch('disabled')
protected disabledChanged(disabled: boolean) { protected disabledChanged(disabled: boolean) {
if (!disabled) { if (!disabled) {

View File

@ -15,9 +15,8 @@ export class Scroll {
private tmr: any; private tmr: any;
private queued = false; private queued = false;
private app: HTMLIonAppElement; private app: HTMLIonAppElement;
private isScrolling = false;
isScrolling = false; private detail: ScrollDetail = {};
detail: ScrollDetail = {};
@Element() private el: HTMLElement; @Element() private el: HTMLElement;
@ -197,6 +196,7 @@ export class Scroll {
// ******** DOM READ **************** // ******** DOM READ ****************
detail.scrollLeft = el.scrollLeft; detail.scrollLeft = el.scrollLeft;
if (!this.isScrolling) { if (!this.isScrolling) {
// currently not scrolling, so this is a scroll start // currently not scrolling, so this is a scroll start
this.isScrolling = true; this.isScrolling = true;
@ -214,34 +214,33 @@ export class Scroll {
} }
this.ionScrollStart.emit(detail); this.ionScrollStart.emit(detail);
} }
detail.deltaY = (detail.scrollTop - detail.startY);
detail.deltaX = (detail.scrollLeft - detail.startX);
// actively scrolling // actively scrolling
positions.push(detail.scrollTop, detail.scrollLeft, detail.timeStamp); positions.push(detail.scrollTop, detail.scrollLeft, detail.timeStamp);
if (positions.length > 3) {
// we've gotten at least 2 scroll events so far
detail.deltaY = (detail.scrollTop - detail.startY);
detail.deltaX = (detail.scrollLeft - detail.startX);
const endPos = (positions.length - 1);
let startPos = endPos;
const timeRange = (detail.timeStamp - 100);
// move pointer to position measured 100ms ago // move pointer to position measured 100ms ago
for (let i = endPos; i > 0 && positions[i] > timeRange; i -= 3) { const timeRange = timeStamp - 100;
startPos = i; let startPos = positions.length - 1;
while (startPos > 0 && positions[startPos] > timeRange) {
startPos -= 3;
} }
if (startPos !== endPos) { if (startPos > 3) {
// compute relative movement between these two points // compute relative movement between these two points
const deltaY = (positions[startPos - 2] - positions[endPos - 2]); const frequency = 1 / (positions[startPos] - timeStamp);
const deltaX = (positions[startPos - 1] - positions[endPos - 1]); const movedY = positions[startPos - 1] - detail.scrollLeft;
const factor = 1 / (positions[startPos] - positions[endPos]); const movedX = positions[startPos - 2] - detail.scrollTop;
// based on XXms compute the movement to apply for each render step // based on XXms compute the movement to apply for each render step
detail.velocityY = deltaY * factor; // velocity = space/time = s*(1/t) = s*frequency
detail.velocityX = deltaX * factor; detail.velocityX = movedX * frequency;
} detail.velocityY = movedY * frequency;
} else {
detail.velocityX = 0;
detail.velocityY = 0;
} }
clearTimeout(this.tmr); clearTimeout(this.tmr);