Created
September 6, 2019 03:46
-
-
Save nguyenvanduocit/b6f75d2bf27b4c9e54b023443192c332 to your computer and use it in GitHub Desktop.
SoundWave and AudioPlayer Animation
This file contains 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> | |
<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> |
This file contains 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="$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> |
This file contains 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> | |
<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