mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 03:00:58 +08:00
add press recognizer
This commit is contained in:
1
core/src/components.d.ts
vendored
1
core/src/components.d.ts
vendored
@ -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.
|
||||||
|
@ -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';
|
||||||
|
1
core/src/interface.d.ts
vendored
1
core/src/interface.d.ts
vendored
@ -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';
|
||||||
|
46
core/src/utils/gesture/recognizers/press.ts
Normal file
46
core/src/utils/gesture/recognizers/press.ts
Normal 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()
|
||||||
|
});
|
||||||
|
};
|
76
core/src/utils/gesture/recognizers/tests/press/e2e.ts
Normal file
76
core/src/utils/gesture/recognizers/tests/press/e2e.ts
Normal 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))
|
||||||
|
};
|
||||||
|
};
|
69
core/src/utils/gesture/recognizers/tests/press/index.html
Normal file
69
core/src/utils/gesture/recognizers/tests/press/index.html
Normal 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>
|
||||||
|
|
Reference in New Issue
Block a user