Skip to content

Commit

Permalink
docs(animation): add playground example for double-click gesture (#3042)
Browse files Browse the repository at this point in the history
Co-authored-by: dillionmegida < [email protected]>

Co-authored-by: Maria Hutt <[email protected]>
  • Loading branch information
mapsandapps and thetaPC authored Jul 14, 2023
1 parent 4d8f605 commit 1acc6e4
Show file tree
Hide file tree
Showing 11 changed files with 349 additions and 170 deletions.
172 changes: 3 additions & 169 deletions docs/utilities/gestures.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,177 +272,11 @@ In this example, our app listens for gestures on the `.rectangle` element. When

## Double Click Gesture

### Usage

````mdx-code-block
<Tabs
groupId="framework"
defaultValue="javascript"
values={[
{ value: 'javascript', label: 'JavaScript' },
{ value: 'angular', label: 'Angular' },
{ value: 'react', label: 'React' },
{ value: 'vue', label: 'Vue' },
]
}>
<TabItem value="javascript">
```javascript
const backgrounds = ['rgba(0, 0, 255, 0.5)', 'rgba(0, 255, 0.5)', 'rgba(255, 0, 0, 0.5)', 'rgba(255, 255, 0, 0.5)', 'rgba(255, 0, 255, 0.5)', 'rgba(0, 255, 255, 0.5)'];
const DOUBLE_CLICK_THRESHOLD = 500;
const rectangle = document.querySelector('.rectangle');
const gesture = createGesture({
el: rectangle,
threshold: 0,
onStart: () => { onStart(); }
});
gesture.enable();
let lastOnStart = 0;
let currentColor = 'rgba(0, 0, 255, 0.5)';
const onStart = () => {
const now = Date.now();
if (Math.abs(now - lastOnStart) <= DOUBLE_CLICK_THRESHOLD) {
rectangle.style.setProperty('background', getRandomBackground());
lastOnStart = 0;
} else {
lastOnStart = now;
}
}
const getRandomBackground = () => {
const options = backgrounds.filter(bg => bg !== currentColor);
currentColor = options[Math.floor(Math.random() * options.length)];
return currentColor;
}
```
</TabItem>
<TabItem value="angular">
```tsx
@ViewChild('rectangle') rectangle: ElementRef;
private backgrounds: string[] = ['rgba(0, 0, 255, 0.5)', 'rgba(0, 255, 0.5)', 'rgba(255, 0, 0, 0.5)', 'rgba(255, 255, 0, 0.5)', 'rgba(255, 0, 255, 0.5)', 'rgba(0, 255, 255, 0.5)'];
private currentColor: string = 'rgba(0, 0, 255, 0.5)';
private lastOnStart: number = 0;
private DOUBLE_CLICK_THRESHOLD: number = 500;
ngOnInit() {
const gesture = this.gestureCtrl.create({
el: this.rectangle.nativeElement,
threshold: 0,
onStart: () => { this.onStart(); }
});
gesture.enable();
}
private onStart() {
const now = Date.now();
if (Math.abs(now - this.lastOnStart) <= this.DOUBLE_CLICK_THRESHOLD) {
this.rectangle.nativeElement.style.setProperty('background', this.getRandomBackground());
this.lastOnStart = 0;
} else {
this.lastOnStart = now;
}
}
private getRandomBackground() {
const options = this.backgrounds.filter(bg => bg !== this.currentColor);
this.currentColor = options[Math.floor(Math.random() * options.length)];
return this.currentColor;
}
```
</TabItem>
<TabItem value="react">
```javascript
const backgrounds = ['rgba(0, 0, 255, 0.5)', 'rgba(0, 255, 0.5)', 'rgba(255, 0, 0, 0.5)', 'rgba(255, 255, 0, 0.5)', 'rgba(255, 0, 255, 0.5)', 'rgba(0, 255, 255, 0.5)'];
const DOUBLE_CLICK_THRESHOLD = 500;
const rectangle = document.querySelector('.rectangle');
const gesture = createGesture({
el: rectangle,
threshold: 0,
onStart: () => { onStart(); }
});
gesture.enable();
let lastOnStart = 0;
let currentColor = 'rgba(0, 0, 255, 0.5)';
const onStart = () => {
const now = Date.now();
if (Math.abs(now - lastOnStart) <= DOUBLE_CLICK_THRESHOLD) {
rectangle.style.setProperty('background', getRandomBackground());
lastOnStart = 0;
} else {
lastOnStart = now;
}
}
const getRandomBackground = () => {
const options = backgrounds.filter(bg => bg !== currentColor);
currentColor = options[Math.floor(Math.random() * options.length)];
return currentColor;
}
```
</TabItem>
<TabItem value="vue">
```javascript
import { createGesture } from '@ionic/vue';
import { ref } from 'vue';
...
const backgrounds = ['rgba(0, 0, 255, 0.5)', 'rgba(0, 255, 0.5)', 'rgba(255, 0, 0, 0.5)', 'rgba(255, 255, 0, 0.5)', 'rgba(255, 0, 255, 0.5)', 'rgba(0, 255, 255, 0.5)'];
const DOUBLE_CLICK_THRESHOLD = 500;
const rectangleRef = ref();
const gesture = createGesture({
el: rectangleRef.value,
threshold: 0,
onStart: () => { onStart(); }
});
gesture.enable();
let lastOnStart = 0;
let currentColor = 'rgba(0, 0, 255, 0.5)';
const onStart = () => {
const now = Date.now();
if (Math.abs(now - lastOnStart) <= DOUBLE_CLICK_THRESHOLD) {
rectangleRef.value.style.setProperty('background', getRandomBackground());
lastOnStart = 0;
} else {
lastOnStart = now;
}
}
const getRandomBackground = () => {
const options = backgrounds.filter(bg => bg !== currentColor);
currentColor = options[Math.floor(Math.random() * options.length)];
return currentColor;
}
```
</TabItem>
</Tabs>
````
import DoubleClick from '@site/static/usage/v7/gestures/double-click/index.md';

In the example above, we want to be able to detect double clicks on an element. By setting our `threshold` to `0`, we can ensure our gesture object can detect clicks. Additionally, we define a click threshold so that only 2 clicks that occur in quick succession count as a double click.
In the example below, we want to be able to detect double clicks on an element. By setting our `threshold` to `0`, we can ensure our gesture object can detect clicks. Additionally, we define a click threshold so that only 2 clicks that occur in quick succession count as a double click.

<Codepen user="ionic" slug="oNvVEwE" />
<DoubleClick />

## Gesture Animations

Expand Down
3 changes: 2 additions & 1 deletion static/code/stackblitz/v7/html/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineCustomElements } from '@ionic/core/loader';

import { createAnimation, loadingController, modalController, pickerController, toastController } from '@ionic/core';
import { createAnimation, createGesture, loadingController, modalController, pickerController, toastController } from '@ionic/core';

/* Core CSS required for Ionic components to work properly */
import '@ionic/core/css/core.css';
Expand Down Expand Up @@ -28,3 +28,4 @@ defineCustomElements();
(window as any).pickerController = pickerController;
(window as any).toastController = toastController;
(window as any).createAnimation = createAnimation;
(window as any).createGesture = createGesture;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
```css
ion-card {
transform: translateX(0);
user-select: none;
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
```html
<ion-card #card>
<ion-card-content>Double click me to move the card.</ion-card-content>
</ion-card>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
```ts
import { Component, ElementRef, ViewChild } from '@angular/core';
import { GestureController, IonCard } from '@ionic/angular';

@Component({
selector: 'app-example',
templateUrl: 'example.component.html',
styleUrls: ['./example.component.css'],
})
export class ExampleComponent {
@ViewChild('card', { read: ElementRef }) card: ElementRef<HTMLIonCardElement>;

private currentOffset: number = 0;
private lastOnStart: number = 0;
private DOUBLE_CLICK_THRESHOLD: number = 500;

constructor(private el: ElementRef, private gestureCtrl: GestureController) {}

ngAfterViewInit() {
const gesture = this.gestureCtrl.create({
el: this.card.nativeElement,
threshold: 0,
onStart: () => this.onStart(),
gestureName: 'double-click',
});

gesture.enable();
}

private onStart() {
const now = Date.now();

if (Math.abs(now - this.lastOnStart) <= this.DOUBLE_CLICK_THRESHOLD) {
this.card.nativeElement.style.setProperty('transform', this.getNewTransform());
this.lastOnStart = 0;
} else {
this.lastOnStart = now;
}
}

private getNewTransform() {
if (this.currentOffset >= 100) {
this.currentOffset = 0;
} else {
this.currentOffset += 20;
}

return `translateX(${this.currentOffset}px)`;
}
}
```
67 changes: 67 additions & 0 deletions static/usage/v7/gestures/double-click/demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Double-Click Gestures</title>
<link rel="stylesheet" href="../../../common.css" />
<script src="../../../common.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core@7/dist/ionic/ionic.esm.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core@7/css/ionic.bundle.css" />

<script type="module">
import { createGesture } from 'https://cdn.jsdelivr.net/npm/@ionic/core@7/dist/ionic/index.esm.js';
window.createGesture = createGesture;

const DOUBLE_CLICK_THRESHOLD = 500;
const card = document.querySelector('ion-card');
const gesture = createGesture({
el: card,
threshold: 0,
onStart: () => onStart(),
gestureName: 'double-click',
});

gesture.enable();

let lastOnStart = 0;
let currentOffset = 0;

const onStart = () => {
const now = Date.now();

if (Math.abs(now - lastOnStart) <= DOUBLE_CLICK_THRESHOLD) {
card.style.setProperty('transform', getNewTransform());
lastOnStart = 0;
} else {
lastOnStart = now;
}
};

const getNewTransform = () => {
if (currentOffset >= 100) {
currentOffset = 0;
} else {
currentOffset += 20;
}

return `translateX(${currentOffset}px)`;
};
</script>

<style>
ion-card {
transform: translateX(0);
user-select: none;
}
</style>
</head>

<body>
<ion-content>
<ion-card>
<ion-card-content>Double click me to move the card.</ion-card-content>
</ion-card>
</ion-content>
</body>
</html>
34 changes: 34 additions & 0 deletions static/usage/v7/gestures/double-click/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Playground from '@site/src/components/global/Playground';

import javascript from './javascript.md';

import react_main_tsx from './react/main_tsx.md';
import react_main_css from './react/main_css.md';

import vue from './vue.md';

import angular_example_component_html from './angular/example_component_html.md';
import angular_example_component_ts from './angular/example_component_ts.md';
import angular_example_component_css from './angular/example_component_css.md';

<Playground
version="7"
code={{
javascript,
react: {
files: {
'src/main.tsx': react_main_tsx,
'src/main.css': react_main_css,
},
},
vue,
angular: {
files: {
'src/app/example.component.html': angular_example_component_html,
'src/app/example.component.ts': angular_example_component_ts,
'src/app/example.component.css': angular_example_component_css,
},
},
}}
src="usage/v7/gestures/double-click/demo.html"
/>
Loading

1 comment on commit 1acc6e4

@vercel
Copy link

@vercel vercel bot commented on 1acc6e4 Jul 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

ionic-docs – ./

ionic-docs-gqykycf8t.vercel.app
ionic-docs-ionic1.vercel.app
ionic-docs-git-main-ionic1.vercel.app

Please sign in to comment.