Skip to content

Commit 99b5f8a

Browse files
docs(animation): add gesture animation playground (#3043)
Co-authored-by: dillionmegida <[email protected]>
1 parent 1acc6e4 commit 99b5f8a

File tree

10 files changed

+580
-315
lines changed

10 files changed

+580
-315
lines changed

docs/utilities/animations.md

Lines changed: 3 additions & 315 deletions
Original file line numberDiff line numberDiff line change
@@ -275,323 +275,11 @@ import Chain from '@site/static/usage/v7/animations/chain/index.md';
275275

276276
Ionic Animations gives developers the ability to create powerful gesture-based animations by integrating seamlessly with [Ionic Gestures](gestures.md).
277277

278-
### Usage
279-
280-
````mdx-code-block
281-
<Tabs
282-
groupId="framework"
283-
defaultValue="javascript"
284-
values={[
285-
{ value: 'javascript', label: 'JavaScript' },
286-
{ value: 'angular', label: 'Angular' },
287-
{ value: 'react', label: 'React' },
288-
{ value: 'vue', label: 'Vue' },
289-
]
290-
}>
291-
<TabItem value="javascript">
292-
293-
```javascript
294-
let initialStep = 0;
295-
let started = false;
296-
297-
const square = document.querySelector('.square');
298-
const MAX_TRANSLATE = 400;
299-
300-
const animation = createAnimation()
301-
.addElement(square)
302-
.duration(1000)
303-
.fromTo('transform', 'translateX(0)', `translateX(${MAX_TRANSLATE}px)`);
304-
305-
const gesture = createGesture({
306-
el: square,
307-
threshold: 0,
308-
gestureName: 'square-drag',
309-
onMove: ev => onMove(ev),
310-
onEnd: ev => onEnd(ev)
311-
})
312-
313-
gesture.enable(true);
314-
315-
const onMove = (ev): {
316-
if (!started) {
317-
animation.progressStart();
318-
started = true;
319-
}
320-
321-
animation.progressStep(getStep(ev));
322-
}
323-
324-
const onEnd = (ev): {
325-
if (!started) { return; }
326-
327-
gesture.enable(false);
328-
329-
const step = getStep(ev);
330-
const shouldComplete = step > 0.5;
331-
332-
animation
333-
.progressEnd((shouldComplete) ? 1 : 0, step)
334-
.onFinish((): { gesture.enable(true); });
335-
336-
initialStep = (shouldComplete) ? MAX_TRANSLATE : 0;
337-
started = false;
338-
}
339-
340-
const clamp = (min, n, max): {
341-
return Math.max(min, Math.min(n, max));
342-
};
343-
344-
const getStep = (ev): {
345-
const delta = initialStep + ev.deltaX;
346-
return clamp(0, delta / MAX_TRANSLATE, 1);
347-
}
348-
```
349-
</TabItem>
350-
<TabItem value="angular">
351-
352-
```tsx
353-
private animation?: Animation;
354-
private gesture?: Gesture;
355-
356-
private started: boolean = false;
357-
private initialStep: number = 0;
358-
private MAX_TRANSLATE: number = 400;
359-
360-
ngOnInit() {
361-
this.animation = this.animationCtrl.create()
362-
.addElement(this.square.nativeElement)
363-
.duration(1000)
364-
.fromTo('transform', 'translateX(0)', `translateX(${this.MAX_TRANSLATE}px)`);
365-
366-
this.gesture = this.gestureCtrl.create({
367-
el: this.square.nativeElement,
368-
threshold: 0,
369-
gestureName: 'square-drag',
370-
onMove: ev => this.onMove(ev),
371-
onEnd: ev => this.onEnd(ev)
372-
})
373-
374-
this.gesture.enable(true);
375-
}
376-
377-
private onMove(ev) {
378-
if (!started) {
379-
this.animation.progressStart();
380-
this.started = true;
381-
}
382-
383-
this.animation.progressStep(this.getStep(ev));
384-
}
385-
386-
private onEnd(ev) {
387-
if (!this.started) { return; }
388-
389-
this.gesture.enable(false);
390-
391-
const step = this.getStep(ev);
392-
const shouldComplete = step > 0.5;
393-
394-
this.animation
395-
.progressEnd((shouldComplete) ? 1 : 0, step)
396-
.onFinish((): { this.gesture.enable(true); });
397-
398-
this.initialStep = (shouldComplete) ? this.MAX_TRANSLATE : 0;
399-
this.started = false;
400-
}
401-
402-
private clamp(min, n, max) {
403-
return Math.max(min, Math.min(n, max));
404-
}
405-
406-
private getStep(ev) {
407-
const delta = this.initialStep + ev.deltaX;
408-
return this.clamp(0, delta / this.MAX_TRANSLATE, 1);
409-
}
410-
```
411-
</TabItem>
412-
<TabItem value="react">
413-
414-
```javascript
415-
import { createGesture, CreateAnimation, Gesture, GestureDetail } from '@ionic/react';
416-
import React from 'react';
417-
418-
const MAX_TRANSLATE = 400;
419-
420-
class MyComponent extends React.Component<{}, any> {
421-
private animation: React.RefObject<CreateAnimation> = React.createRef();
422-
private gesture?: Gesture;
423-
private started: boolean = false;
424-
private initialStep: number = 0;
425-
426-
constructor(props: any) {
427-
super(props);
428-
429-
this.state = {
430-
progressStart: undefined,
431-
progressStep: undefined,
432-
progressEnd: undefined,
433-
onFinish: undefined
434-
};
435-
}
436-
437-
componentDidMount() {
438-
const square = Array.from(this.animation.current!.nodes.values())[0];
439-
440-
this.gesture = createGesture({
441-
el: square,
442-
gestureName: 'square-drag',
443-
threshold: 0,
444-
onMove: ev => this.onMove(ev),
445-
onEnd: ev => this.onEnd(ev)
446-
});
447-
448-
this.gesture.enable(true);
449-
}
450-
451-
private onMove(ev: GestureDetail) {
452-
if (!this.started) {
453-
this.setState({
454-
...this.state,
455-
progressStart: { forceLinearEasing: true }
456-
});
457-
this.started = true;
458-
}
459-
460-
this.setState({
461-
...this.state,
462-
progressStep: { step: this.getStep(ev) }
463-
});
464-
}
465-
466-
private onEnd(ev: GestureDetail) {
467-
if (!this.started) { return; }
468-
469-
this.gesture!.enable(false);
470-
471-
const step = this.getStep(ev);
472-
const shouldComplete = step > 0.5;
473-
474-
this.setState({
475-
...this.state,
476-
progressEnd: { playTo: (shouldComplete) ? 1 : 0, step },
477-
onFinish: { callback: () => {
478-
this.gesture!.enable(true);
479-
this.setState({
480-
progressStart: undefined,
481-
progressStep: undefined,
482-
progressEnd: undefined
483-
})
484-
}, opts: { oneTimeCallback: true }}
485-
});
486-
487-
this.initialStep = (shouldComplete) ? MAX_TRANSLATE : 0;
488-
this.started = false;
489-
}
490-
491-
private getStep(ev: GestureDetail) {
492-
const delta = this.initialStep + ev.deltaX;
493-
return this.clamp(0, delta / MAX_TRANSLATE, 1);
494-
}
495-
496-
private clamp(min: number, n: number, max: number) {
497-
return Math.max(min, Math.min(n, max));
498-
}
499-
500-
render() {
501-
return (
502-
<>
503-
<div className="track">
504-
<CreateAnimation
505-
ref={this.animation}
506-
duration={1000}
507-
progressStart={this.state.progressStart}
508-
progressStep={this.state.progressStep}
509-
progressEnd={this.state.progressEnd}
510-
onFinish={this.state.onFinish}
511-
fromTo={{
512-
property: 'transform',
513-
fromValue: 'translateX(0)',
514-
toValue: `translateX(${MAX_TRANSLATE}px)`
515-
}}>
516-
<div className="square"></div>
517-
</CreateAnimation>
518-
</div>
519-
</>
520-
);
521-
}
522-
}
523-
```
524-
</TabItem>
525-
<TabItem value="vue">
526-
527-
```javascript
528-
import { createAnimation, createGesture } from '@ionic/vue';
529-
import { ref } from 'vue';
530-
531-
...
532-
533-
let initialStep = 0;
534-
let started = false;
535-
536-
const squareRef = ref();
537-
const MAX_TRANSLATE = 400;
538-
539-
const animation = createAnimation()
540-
.addElement(squareRef.value)
541-
.duration(1000)
542-
.fromTo('transform', 'translateX(0)', `translateX(${MAX_TRANSLATE}px)`);
543-
544-
const gesture = createGesture({
545-
el: squareRef.value,
546-
threshold: 0,
547-
gestureName: 'square-drag',
548-
onMove: ev => onMove(ev),
549-
onEnd: ev => onEnd(ev)
550-
})
551-
552-
gesture.enable(true);
553-
554-
const onMove = (ev): {
555-
if (!started) {
556-
animation.progressStart();
557-
started = true;
558-
}
559-
560-
animation.progressStep(getStep(ev));
561-
}
562-
563-
const onEnd = (ev): {
564-
if (!started) { return; }
565-
566-
gesture.enable(false);
567-
568-
const step = getStep(ev);
569-
const shouldComplete = step > 0.5;
570-
571-
animation
572-
.progressEnd((shouldComplete) ? 1 : 0, step)
573-
.onFinish((): { gesture.enable(true); });
574-
575-
initialStep = (shouldComplete) ? MAX_TRANSLATE : 0;
576-
started = false;
577-
}
578-
579-
const clamp = (min, n, max): {
580-
return Math.max(min, Math.min(n, max));
581-
};
582-
583-
const getStep = (ev): {
584-
const delta = initialStep + ev.deltaX;
585-
return clamp(0, delta / MAX_TRANSLATE, 1);
586-
}
587-
```
588-
</TabItem>
589-
</Tabs>
590-
````
278+
In the following example we are creating a track along which we can drag the card element. Our `animation` object will take care of moving the card element either left or right, and our `gesture` object will instruct the `animation` object which direction to move in.
591279

592-
In this example we are creating a track along which we can drag the `.square` element. Our `animation` object will take care of moving the `.square` element either left or right, and our `gesture` object will instruct the `animation` object which direction to move in.
280+
import Gesture from '@site/static/usage/v7/animations/gesture/index.md';
593281

594-
<Codepen user="ionic" slug="jONxzRL" />
282+
<Gesture />
595283

596284
## Preference-Based Animations
597285

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
```css
2+
.container {
3+
flex-direction: column;
4+
}
5+
6+
.track {
7+
width: 344px;
8+
background: var(--ion-color-medium);
9+
padding: 16px;
10+
}
11+
12+
ion-card {
13+
width: 100px;
14+
box-shadow: none;
15+
margin: 0px;
16+
}
17+
```
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
```html
2+
<div class="container">
3+
<div class="track">
4+
<ion-card id="card" button="true">
5+
<ion-card-content>Card</ion-card-content>
6+
</ion-card>
7+
</div>
8+
9+
<p>Drag the square along the track.</p>
10+
</div>
11+
```

0 commit comments

Comments
 (0)