add press recognizer

This commit is contained in:
Liam DeBeasi
2019-11-07 15:03:05 -05:00
parent a3666ddf0c
commit 12a4c974b4
6 changed files with 194 additions and 1 deletions

View File

@ -1,4 +1,3 @@
/* eslint-disable */
/* tslint:disable */ /* tslint:disable */
/** /**
* This is an autogenerated file created by the Stencil compiler. * This is an autogenerated file created by the Stencil compiler.

View File

@ -3,6 +3,8 @@ import 'ionicons';
export { createAnimation } from './utils/animation/animation'; export { createAnimation } from './utils/animation/animation';
export { getTimeGivenProgression } from './utils/animation/cubic-bezier'; export { getTimeGivenProgression } from './utils/animation/cubic-bezier';
export { createGesture } from './utils/gesture'; export { createGesture } from './utils/gesture';
export { createPressRecognizer } from './utils/gesture/recognizers/press';
export { isPlatform, Platforms, getPlatforms } from './utils/platform'; export { isPlatform, Platforms, getPlatforms } from './utils/platform';
export * from './utils/config'; export * from './utils/config';

View File

@ -35,6 +35,7 @@ export { Animation, AnimationBuilder } from './utils/animation/animation-interfa
export * from './utils/overlays-interface'; export * from './utils/overlays-interface';
export * from './global/config'; export * from './global/config';
export { Gesture, GestureDetail } from './utils/gesture'; export { Gesture, GestureDetail } from './utils/gesture';
export { PressRecognizerOptions } from './utils/gesture/recognizers/press';
// Global aux types // Global aux types
export type TextFieldTypes = 'date' | 'email' | 'number' | 'password' | 'search' | 'tel' | 'text' | 'url' | 'time'; export type TextFieldTypes = 'date' | 'email' | 'number' | 'password' | 'search' | 'tel' | 'text' | 'url' | 'time';

View File

@ -0,0 +1,46 @@
import { GestureDetail, createGesture } from '../index';
export interface PressRecognizerOptions {
el: HTMLElement;
time: number;
threshold: number;
onPressHandler: () => void;
}
export const createPressRecognizer = (opts: PressRecognizerOptions) => {
const THRESHOLD = opts.threshold || 10;
let timeout: any;
const onStart = () => {
clearGestureTimeout();
timeout = setTimeout(() => {
opts.onPressHandler();
clearGestureTimeout();
}, opts.time || 500);
};
const onMove = (detail: GestureDetail) => {
if (Math.abs(detail.deltaX) + Math.abs(detail.deltaY) <= THRESHOLD) {
return;
}
clearGestureTimeout();
};
const clearGestureTimeout = () => {
if (timeout) {
clearTimeout(timeout);
timeout = undefined;
}
};
return createGesture({
el: opts.el,
gestureName: 'press',
threshold: 0,
onStart,
onMove,
onEnd: () => clearGestureTimeout()
});
};

View File

@ -0,0 +1,76 @@
import { newE2EPage } from '@stencil/core/testing';
test(`gesture: press`, async () => {
const page = await newE2EPage({ url: '/src/utils/gesture/recognizers/tests/press' });
const screenshotCompares = [];
screenshotCompares.push(await page.compareScreenshot());
const square = await page.$('.square');
const { x, y } = await coords(square);
page.mouse.move(x, y);
page.mouse.down();
await page.waitFor(300);
page.mouse.up();
const squareAgain = await page.find('.square');
expect(squareAgain).toHaveClass('pressed');
screenshotCompares.push(await page.compareScreenshot('end press'));
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();
}
});
test(`gesture: press:short press`, async () => {
const page = await newE2EPage({ url: '/src/utils/gesture/recognizers/tests/press' });
const screenshotCompares = [];
screenshotCompares.push(await page.compareScreenshot());
const square = await page.$('.square');
const { x, y } = await coords(square);
page.mouse.move(x, y);
page.mouse.down();
await page.waitFor(50);
page.mouse.up();
const squareAgain = await page.find('.square');
expect(squareAgain).not.toHaveClass('pressed');
screenshotCompares.push(await page.compareScreenshot('end press'));
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();
}
});
test(`gesture: press:click`, async () => {
const page = await newE2EPage({ url: '/src/utils/gesture/recognizers/tests/press' });
const screenshotCompares = [];
screenshotCompares.push(await page.compareScreenshot());
await page.click('.square');
const square = await page.find('.square');
expect(square).not.toHaveClass('pressed');
screenshotCompares.push(await page.compareScreenshot('end press'));
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();
}
});
const coords = async el => {
const box = await el.boundingBox();
return {
x: Math.floor(box.x + (box.width / 2)),
y: Math.floor(box.y + (box.height / 2))
};
};

View File

@ -0,0 +1,69 @@
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta charset="UTF-8">
<title>Gesture - Press</title>
<meta name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link href="../../../../../../css/ionic.bundle.css" rel="stylesheet">
<link href="../../../../../../scripts/testing/styles.css" rel="stylesheet">
<script src="../../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../../dist/ionic/ionic.esm.js"></script>
<script type="module">
import { createPressRecognizer } from '../../../../../dist/ionic/index.esm.js';
const square = document.querySelector('.square');
const onPress = () => {
square.classList.toggle('pressed');
}
const pan = createPressRecognizer({
el: square,
time: 251,
threshold: 10,
onPressHandler: () => onPress(),
});
pan.enable(true);
</script>
<style>
.square {
width: 100px;
height: 100px;
background: rgba(255, 0, 0, 0.5);
text-align: center;
line-height: 100px;
margin-left: 25px;
margin-top: 25px;
transition: 0.2s all ease-in-out;
cursor: pointer;
}
.pressed {
transform: scale(1.5);
background: rgba(0, 255, 0, 0.5);
}
</style>
</head>
<body>
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>Gesture - Press</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<div class="ion-padding">
<div class="square">Hello</div>
</div>
</ion-content>
</ion-app>
</body>
</html>