Created
October 24, 2018 21:23
-
-
Save dimensi/327b4ac17f8c237b90dd798c1d0608d3 to your computer and use it in GitHub Desktop.
List animations on animejs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <template> | |
| <div :class="c($style.AnimationList, { | |
| list: type | |
| })"> | |
| <div v-for="i in 9" :class="$style.item" :key="i"> | |
| <component ref="items" :is="icon.is" :class="[$style.icon, $style[type]]" :icon="icon.icon"/> | |
| </div> | |
| </div> | |
| </template> | |
| <script> | |
| import anime from 'animejs' | |
| import AppIcon from 'src/components/AppIcon' | |
| import ShieldSvg from 'src/components/ShieldSvg' | |
| import { standard } from 'src/utils/easings' | |
| const rubAnimation = (items, autoplay) => | |
| anime.timeline({ loop: true, autoplay, targets: items.map(el => el.$el) }) | |
| .add({ | |
| scale: [0.15, 1], | |
| opacity: { | |
| value: [0, 1], | |
| duration: 300, | |
| easing: standard, | |
| }, | |
| easing: [0.41, 0.14, 0.25, 1], | |
| duration: 400, | |
| translateX: ['-200px', '0px'], | |
| rotate: { | |
| value: ['30deg', '0deg'], | |
| duration: 300, | |
| }, | |
| delay (el, i) { | |
| return 100 * i | |
| }, | |
| }) | |
| .add({ | |
| opacity: { | |
| value: 0, | |
| easing: standard, | |
| }, | |
| translateX: 100, | |
| duration: 400, | |
| easing: [0.41, 0.14, 0.25, 1], | |
| delay (el, i) { | |
| return 1.2e3 + (50 * i) | |
| }, | |
| }) | |
| .add({ | |
| delay: 500, | |
| }) | |
| const truckAnimation = (items, autoplay) => { | |
| const trucks = [2, 5, 8, 1, 4, 7, 0, 3, 6].map(i => items[i]) | |
| return anime.timeline({ loop: true, autoplay, targets: trucks.map(el => el.$el) }) | |
| .add({ | |
| opacity: { | |
| value: [0, 1], | |
| duration: 500, | |
| easing: standard, | |
| }, | |
| easing: [0.3, 0.11, 0.27, 1], | |
| duration: 600, | |
| translateX: ['-100px', '0px'], | |
| delay (el, i) { | |
| return 100 * i | |
| }, | |
| }) | |
| .add({ | |
| opacity: { | |
| value: 0, | |
| easing: standard, | |
| }, | |
| translateX: 100, | |
| duration: 600, | |
| easing: [0.3, 0.11, 0.27, 1], | |
| delay (el, i) { | |
| return 1.2e3 + (100 * i) | |
| }, | |
| }) | |
| } | |
| const shieldAnimations = (items, autoplay) => { | |
| const positions = [2, 5, 8, 1, 4, 7, 0, 3, 6] | |
| const icons = positions.map(i => items[i].$el) | |
| const ok = positions.map(i => items[i].$refs.ok) | |
| const showAnimationIcon = (icons) => ({ | |
| targets: icons, | |
| opacity: { | |
| value: [0, 1], | |
| duration: 300, | |
| }, | |
| easing: standard, | |
| scale: { | |
| value: [0.7, 1], | |
| duration: 600, | |
| }, | |
| translateX: { | |
| value: ['-100px', '0px'], | |
| duration: 400, | |
| }, | |
| delay (el, i) { | |
| return 200 * (Math.ceil((i + 1) / 3) - 1) | |
| }, | |
| }) | |
| const hideAnimation = (items) => ({ | |
| targets: items, | |
| opacity: { | |
| duration: 300, | |
| delay (el, i) { | |
| return 300 + (200 * (Math.ceil((i + 1) / 3) - 1)) | |
| }, | |
| value: [1, 0], | |
| }, | |
| easing: standard, | |
| duration: 600, | |
| translateX: ['0px', '100px'], | |
| scale: [1, 0.7], | |
| delay (el, i) { | |
| return 200 * (Math.ceil((i + 1) / 3) - 1) | |
| }, | |
| }) | |
| const okAnimation = anime({ | |
| targets: ok, | |
| opacity: [0, 1], | |
| scale: [0.7, 1], | |
| elasticity: 300, | |
| duration: 400, | |
| delay (el, i) { | |
| return 500 + (100 * i) | |
| }, | |
| autoplay: false, | |
| }) | |
| const iconTimeLine = anime({ | |
| autoplay, | |
| ...showAnimationIcon(icons), | |
| }) | |
| let hideTimeLine = null | |
| okAnimation.complete = () => { | |
| setTimeout(() => { | |
| if (!hideTimeLine) { | |
| const hideTimeLine = anime(hideAnimation(icons)) | |
| hideTimeLine.complete = () => { | |
| setTimeout(() => { | |
| iconTimeLine.restart() | |
| }, 800) | |
| } | |
| } else { | |
| hideTimeLine.restart() | |
| } | |
| }, 1e3) | |
| } | |
| iconTimeLine.begin = () => { | |
| okAnimation.restart() | |
| } | |
| return iconTimeLine | |
| } | |
| const typeMap = { | |
| provider: { | |
| icon: { | |
| is: 'AppIcon', | |
| icon: 'rubMark', | |
| }, | |
| animation: rubAnimation, | |
| }, | |
| customer: { | |
| icon: { | |
| is: 'AppIcon', | |
| icon: 'truck', | |
| }, | |
| animation: truckAnimation, | |
| }, | |
| factor: { | |
| icon: { | |
| is: 'ShieldSvg', | |
| }, | |
| animation: shieldAnimations, | |
| }, | |
| } | |
| export default { | |
| name: 'AnimationList', | |
| components: { | |
| AppIcon, | |
| ShieldSvg, | |
| }, | |
| props: { | |
| type: String, | |
| play: Boolean, | |
| }, | |
| computed: { | |
| icon () { | |
| return typeMap[this.type].icon | |
| }, | |
| }, | |
| watch: { | |
| play (bool) { | |
| if (bool) this.animation.restart() | |
| }, | |
| }, | |
| mounted () { | |
| const startAnimation = typeMap[this.type].animation | |
| this.animation = startAnimation(this.$refs.items, this.play) | |
| }, | |
| } | |
| </script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment