Skip to content

Commit

Permalink
docs(animation): add playground for group example (#3025)
Browse files Browse the repository at this point in the history
  • Loading branch information
liamdebeasi authored Jul 11, 2023
1 parent 15817f4 commit 2c7303e
Show file tree
Hide file tree
Showing 8 changed files with 408 additions and 200 deletions.
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
17 changes: 17 additions & 0 deletions static/usage/v7/animations/group/angular/example_component_html.md
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>
```
66 changes: 66 additions & 0 deletions static/usage/v7/animations/group/angular/example_component_ts.md
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

1 comment on commit 2c7303e

@vercel
Copy link

@vercel vercel bot commented on 2c7303e Jul 11, 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-ionic1.vercel.app
ionic-docs-git-main-ionic1.vercel.app
ionic-docs-gqykycf8t.vercel.app

Please sign in to comment.