Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(animation): add playground for group example #3025

Merged
merged 13 commits into from
Jul 11, 2023
203 changes: 3 additions & 200 deletions docs/utilities/animations.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,208 +316,11 @@ Each keyframe object contains an `offset` property. `offset` is a value between

Multiple elements can be animated at the same time and controlled via a single parent animation object. Child animations inherit properties such as duration, easing, and iterations unless otherwise specified. A parent animation's `onFinish` callback will not be called until all child animations have completed.

### 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 squareA = createAnimation()
.addElement(document.querySelector('.square-a'))
.keyframes([
{ offset: 0, transform: 'scale(1) rotate(0)' },
{ offset: 0.5, transform: 'scale(1.2) rotate(45deg)' },
{ offset: 1, transform: 'scale(1) rotate(45deg)' }
]);

const squareB = createAnimation()
.addElement(document.querySelector('.square-b'))
.keyframes([
{ offset: 0, transform: 'scale(1))', opacity: '1' },
{ offset: 0.5, transform: 'scale(1.2)', opacity: '0.3' },
{ offset: 1, transform: 'scale(1)', opacity: '1' }
]);

const squareC = createAnimation()
.addElement(document.querySelector('.square-c'))
.duration(5000)
.keyframes([
{ offset: 0, transform: 'scale(1))', opacity: '0.5' },
{ offset: 0.5, transform: 'scale(0.8)', opacity: '1' },
{ offset: 1, transform: 'scale(1)', opacity: '0.5' }
]);

const parent = createAnimation()
.duration(2000)
.iterations(Infinity)
.addAnimation([squareA, squareB, squareC]);
```

</TabItem>
<TabItem value="angular">

```javascript
const squareA = this.animationCtrl.create()
.addElement(this.squareA.nativeElement)
.keyframes([
{ offset: 0, transform: 'scale(1) rotate(0)' },
{ offset: 0.5, transform: 'scale(1.2) rotate(45deg)' },
{ offset: 1, transform: 'scale(1) rotate(45deg)' }
]);

const squareB = this.animationCtrl.create()
.addElement(this.squareB.nativeElement)
.keyframes([
{ offset: 0, transform: 'scale(1))', opacity: '1' },
{ offset: 0.5, transform: 'scale(1.2)', opacity: '0.3' },
{ offset: 1, transform: 'scale(1)', opacity: '1' }
]);

const squareC = this.animationCtrl.create()
.addElement(this.squareC.nativeElement)
.duration(5000)
.keyframes([
{ offset: 0, transform: 'scale(1))', opacity: '0.5' },
{ offset: 0.5, transform: 'scale(0.8)', opacity: '1' },
{ offset: 1, transform: 'scale(1)', opacity: '0.5' }
]);

const parent = this.animationCtrl.create()
.duration(2000)
.iterations(Infinity)
.addAnimation([squareA, squareB, squareC]);
```

</TabItem>
<TabItem value="react">

```tsx
private parentRef: React.RefObject<CreateAnimation> = React.createRef();
private squareARef: React.RefObject<CreateAnimation> = React.createRef();
private squareBRef: React.RefObject<CreateAnimation> = React.createRef();
private squareCRef: React.RefObject<CreateAnimation> = React.createRef();

...

componentDidMount() {
const parent = this.parentRef.current!.animation;
const squareA = this.squareARef.current!.animation;
const squareB = this.squareBRef.current!.animation;
const squareC = this.squareCRef.current!.animation;

parent.addAnimation([squareA, squareB, squareC]);
}

render() {
return (
<>
<CreateAnimation
ref={this.parentRef}
duration={2000}
iterations={Infinity}
></CreateAnimation>

<CreateAnimation
ref={this.squareARef}
keyframes={[
{ offset: 0, transform: 'scale(1) rotate(0)' },
{ offset: 0.5, transform: 'scale(1.2) rotate(45deg)' },
{ offset: 1, transform: 'scale(1) rotate(0deg)' }
]}
>
<div className="square"></div>
</CreateAnimation>

<CreateAnimation
ref={this.squareBRef}
keyframes={[
{ offset: 0, transform: 'scale(1)', opacity: '1' },
{ offset: 0.5, transform: 'scale(1.2)', opacity: '0.3' },
{ offset: 1, transform: 'scale(1)', opacity: '1' }
]}
>
<div className="square"></div>
</CreateAnimation>

<CreateAnimation
ref={this.squareCRef}
duration={5000}
keyframes={[
{ offset: 0, transform: 'scale(1)', opacity: '0.5' },
{ offset: 0.5, transform: 'scale(0.8)', opacity: '1' },
{ offset: 1, transform: 'scale(1)', opacity: '0.5' }
]}
>
<div className="square"></div>
</CreateAnimation>
</>
)
}
```

</TabItem>
<TabItem value="vue">

```javascript
import { createAnimation } from '@ionic/vue';
import { ref } from 'vue';

...

const squareARef = ref();
const squareBRef = ref();
const squareCRef = ref();

...

const squareA = createAnimation()
.addElement(squareARef.value)
.keyframes([
{ offset: 0, transform: 'scale(1) rotate(0)' },
{ offset: 0.5, transform: 'scale(1.2) rotate(45deg)' },
{ offset: 1, transform: 'scale(1) rotate(45deg)' }
]);

const squareB = createAnimation()
.addElement(squareBRef.value)
.keyframes([
{ offset: 0, transform: 'scale(1))', opacity: '1' },
{ offset: 0.5, transform: 'scale(1.2)', opacity: '0.3' },
{ offset: 1, transform: 'scale(1)', opacity: '1' }
]);

const squareC = createAnimation()
.addElement(squareCRef.value)
.duration(5000)
.keyframes([
{ offset: 0, transform: 'scale(1))', opacity: '0.5' },
{ offset: 0.5, transform: 'scale(0.8)', opacity: '1' },
{ offset: 1, transform: 'scale(1)', opacity: '0.5' }
]);

const parent = createAnimation()
.duration(2000)
.iterations(Infinity)
.addAnimation([squareA, squareB, squareC]);
```

</TabItem>
</Tabs>
````
This example shows 3 child animations controlled by a single parent animation. Animations `cardA` and `cardB` inherit the parent animation's duration of 2000ms, but animation `cardC` has a duration of 5000ms since it was explicitly set.

This example shows 3 child animations controlled by a single parent animation. Animations `squareA` and `squareB` inherit the parent animation's duration of 2000ms, but animation `squareC` has a duration of 5000ms since it was explicitly set.
import Group from '@site/static/usage/v7/animations/group/index.md';

<Codepen user="ionic" slug="oNvdogM" height="460" />
<Group />

## Before and After Hooks

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
```html
<ion-card>
<ion-card-content>Card 1</ion-card-content>
</ion-card>

<ion-card>
<ion-card-content>Card 2</ion-card-content>
</ion-card>

<ion-card>
<ion-card-content>Card 3</ion-card-content>
</ion-card>

<ion-button id="play" (click)="play()">Play</ion-button>
<ion-button id="pause" (click)="pause()">Pause</ion-button>
<ion-button id="stop" (click)="stop()">Stop</ion-button>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
```ts
import { Component, ElementRef, ViewChildren } from '@angular/core';
import type { QueryList } from '@angular/core';
import type { Animation } from '@ionic/angular';
import { AnimationController, IonCard } from '@ionic/angular';

@Component({
selector: 'app-example',
templateUrl: 'example.component.html',
})
export class ExampleComponent {
@ViewChildren(IonCard, { read: ElementRef }) cardElements: QueryList<ElementRef<HTMLIonCardElement>>;

private animation: Animation;

constructor(private animationCtrl: AnimationController) {}

ngAfterViewInit() {
const cardA = this.animationCtrl
.create()
.addElement(this.cardElements.get(0).nativeElement)
.keyframes([
{ offset: 0, transform: 'scale(1) rotate(0)' },
{ offset: 0.5, transform: 'scale(1.5) rotate(45deg)' },
{ offset: 1, transform: 'scale(1) rotate(0) ' },
]);

const cardB = this.animationCtrl
.create()
.addElement(this.cardElements.get(1).nativeElement)
.keyframes([
{ offset: 0, transform: 'scale(1)', opacity: '1' },
{ offset: 0.5, transform: 'scale(1.5)', opacity: '0.3' },
{ offset: 1, transform: 'scale(1)', opacity: '1' },
]);

const cardC = this.animationCtrl
.create()
.addElement(this.cardElements.get(2).nativeElement)
.duration(5000)
.keyframes([
{ offset: 0, transform: 'scale(1)', opacity: '0.5' },
{ offset: 0.5, transform: 'scale(0.5)', opacity: '1' },
{ offset: 1, transform: 'scale(1)', opacity: '0.5' },
]);

this.animation = this.animationCtrl
.create()
.duration(2000)
.iterations(Infinity)
.addAnimation([cardA, cardB, cardC]);
}

play() {
this.animation.play();
}

pause() {
this.animation.pause();
}

stop() {
this.animation.stop();
}
}
```
87 changes: 87 additions & 0 deletions static/usage/v7/animations/group/demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Animation</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 { createAnimation } from 'https://cdn.jsdelivr.net/npm/@ionic/core@7/dist/ionic/index.esm.js';
window.createAnimation = createAnimation;

const cardA = createAnimation()
.addElement(document.querySelector('#card-a'))
.keyframes([
{ offset: 0, transform: 'scale(1) rotate(0)' },
{ offset: 0.5, transform: 'scale(1.5) rotate(45deg)' },
{ offset: 1, transform: 'scale(1) rotate(0) ' },
]);

const cardB = createAnimation()
.addElement(document.querySelector('#card-b'))
.keyframes([
{ offset: 0, transform: 'scale(1)', opacity: '1' },
{ offset: 0.5, transform: 'scale(1.5)', opacity: '0.3' },
{ offset: 1, transform: 'scale(1)', opacity: '1' },
]);

const cardC = createAnimation()
.addElement(document.querySelector('#card-c'))
.duration(5000)
.keyframes([
{ offset: 0, transform: 'scale(1)', opacity: '0.5' },
{ offset: 0.5, transform: 'scale(0.5)', opacity: '1' },
{ offset: 1, transform: 'scale(1)', opacity: '0.5' },
]);

const animation = createAnimation().duration(2000).iterations(Infinity).addAnimation([cardA, cardB, cardC]);

document.querySelector('#play').addEventListener('click', () => {
animation.play();
});

document.querySelector('#pause').addEventListener('click', () => {
animation.pause();
});

document.querySelector('#stop').addEventListener('click', () => {
animation.stop();
});
</script>

<style>
.container {
flex-direction: column;
}

ion-card {
width: 70%;
}
</style>
</head>

<body>
<div class="container">
<ion-card id="card-a">
<ion-card-content>Card 1</ion-card-content>
</ion-card>

<ion-card id="card-b">
<ion-card-content>Card 2</ion-card-content>
</ion-card>

<ion-card id="card-c">
<ion-card-content>Card 3</ion-card-content>
</ion-card>

<div>
<ion-button id="play">Play</ion-button>
<ion-button id="pause">Pause</ion-button>
<ion-button id="stop">Stop</ion-button>
</div>
</div>
</body>
</html>
Loading