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 */
|
||||
/**
|
||||
* This is an autogenerated file created by the Stencil compiler.
|
||||
|
@ -3,6 +3,8 @@ import 'ionicons';
|
||||
export { createAnimation } from './utils/animation/animation';
|
||||
export { getTimeGivenProgression } from './utils/animation/cubic-bezier';
|
||||
export { createGesture } from './utils/gesture';
|
||||
export { createPressRecognizer } from './utils/gesture/recognizers/press';
|
||||
|
||||
export { isPlatform, Platforms, getPlatforms } from './utils/platform';
|
||||
|
||||
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 './global/config';
|
||||
export { Gesture, GestureDetail } from './utils/gesture';
|
||||
export { PressRecognizerOptions } from './utils/gesture/recognizers/press';
|
||||
|
||||
// Global aux types
|
||||
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