Skip to content

Instantly share code, notes, and snippets.

@nguyenvanduocit
Created September 6, 2019 03:46
Show Gist options
  • Save nguyenvanduocit/b6f75d2bf27b4c9e54b023443192c332 to your computer and use it in GitHub Desktop.
Save nguyenvanduocit/b6f75d2bf27b4c9e54b023443192c332 to your computer and use it in GitHub Desktop.
SoundWave and AudioPlayer Animation
<template>
<audio
ref="audio"
src="/audio/magical.mp3"
preload="auto"
loop
@canplaythrough="audioLoaded"
>
<p>If you are reading this, it is because your browser does not support the audio element.</p>
</audio>
</template>
<script>
import anime from 'animejs'
let fadeInAnimate = null
let fadeOutAnimate = null
export default {
name: 'AudioPlayer',
data () {
return {
willPlay: false,
canPlay: false
}
},
mounted () {
if (fadeInAnimate === null) {
fadeInAnimate = anime({
volume: [0, 1],
easing: 'linear',
duration: 2000,
autoplay: false,
begin: () => {
this.$refs.audio.play()
},
update: (anim) => {
this.$refs.audio.volume = anim.progress / 100
}
})
}
if (fadeOutAnimate === null) {
fadeOutAnimate = anime({
volume: [1, 0],
easing: 'linear',
duration: 2000,
autoplay: false,
update: (anim) => {
this.$refs.audio.volume = 1 - (anim.progress / 100)
},
complete: () => {
this.$refs.audio.pause()
}
})
}
},
methods: {
async fadeVolumeIn () {
fadeInAnimate.play()
},
async fadeVolumeOut () {
fadeOutAnimate.play()
},
async play () {
this.willPlay = true
if (this.canPlay) {
this.fadeVolumeIn()
}
},
async pause () {
this.willPlay = false
this.fadeVolumeOut()
},
audioLoaded () {
this.$refs.audio.volume = 0
this.canPlay = true
this.$emit('canplaythrough')
if (this.willPlay) {
this.fadeVolumeIn()
}
}
}
}
</script>
<style lang="stylus" module>
</style>
<template>
<div
:class="$style.container"
@click="onClick"
>
<sound-wave ref="soundWave" />
<audio-player ref="audioPlayer" />
<transition name="fade">
<span
v-if="showQuote"
:class="$style.quote"
>music brings emotion</span>
</transition>
</div>
</template>
<script>
import SoundWave from './SoundWave'
import AudioPlayer from './AudioPlayer'
export default {
name: 'MusicPlayer',
components: {
SoundWave,
AudioPlayer
},
data () {
return {
isPlaying: false
}
},
computed: {
showQuote () {
return this.$store.state.route.name === 'loading'
}
},
mounted () {
this.play()
},
methods: {
onClick () {
if (this.isPlaying) {
this.pause()
} else {
this.play()
}
},
play () {
this.isPlaying = true
this.$refs.soundWave.play()
this.$refs.audioPlayer.play()
},
pause () {
this.isPlaying = false
this.$refs.soundWave.pause()
this.$refs.audioPlayer.pause()
}
}
}
</script>
<style lang="stylus" module>
.container
line-height 0
display flex
align-items center
cursor pointer
.quote
margin-left 15px
font-size: 14px
letter-spacing: 0
</style>
<template>
<div>
<svg
width="21px"
height="21px"
viewBox="0 0 21 21"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g
stroke="none"
stroke-width="1"
fill="none"
fill-rule="evenodd"
stroke-linecap="square">
<path
class="wavePath"
d="M0.5,9.5 L0.5,11.5"
stroke="#5B5467"
stroke-width="1.5" />
<path
class="wavePath"
d="M4.5,6.5 L4.5,14.5"
stroke="#5B5467"
stroke-width="1.5" />
<path
class="wavePath"
d="M8.5,0.5 L8.5,18.5"
stroke="#5B5467"
stroke-width="1.5" />
<path
class="wavePath"
d="M12.5,2.5 L12.5,20.5"
stroke="#5B5467"
stroke-width="1.5" />
<path
class="wavePath"
d="M16.5,6.5 L16.5,14.5"
stroke="#5B5467"
stroke-width="1.5" />
<path
class="wavePath"
d="M20.5,9.5 L20.5,11.5"
stroke="#5B5467"
stroke-width="1.5" />
</g>
</svg>
</div>
</template>
<script>
import anime from 'animejs'
let waveAnimate = null
export default {
name: 'SoundWave',
data () {
return {
willPause: false
}
},
methods: {
async play () {
this.willPause = false
if (waveAnimate === null) {
waveAnimate = await anime({
targets: '.wavePath',
d: function (el, i) {
const x = 0.5 + (1 * i) * 4
const y1 = 5.5 + (i % 2) * 3
const y2 = 20.5 - (i % 2) * 3
return `M${x},${y1} L${x},${y2}`
},
easing: 'linear',
duration: 1000,
direction: 'alternate',
loop: true,
autoplay: false,
update: this.checkForPause
})
}
waveAnimate.play()
},
pause () {
this.willPause = true
},
checkForPause (anim) {
if (this.willPause && (anim.progress === 0)) {
waveAnimate.pause()
}
}
}
}
</script>
<style lang="stylus" module>
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment