<template><divclass="relative"><inputtype="checkbox" @mousedown="active = true" @mouseup="active = false" @mouseout="active = false"v-model="value"class="absolute top-0 left-0 z-20 w-full h-full opacity-0 cursor-pointer"/><divclass="relative z-10 flex items-center"><divclass="relative flex items-center justify-center w-10 h-10 p-1 border-4 rounded-xl visible-box" :style="{ transform:`scale(${outlineSpring.scale})`, }"><divclass="z-10 w-full h-full bg-pink-500 rounded-lg" :style="{ transform:`scale(${filledSpring.scale})`, opacity:`${filledSpring.scale}`, }" /></div></div></div></template><script>import {useSound }from'@vueuse/sound'import {computed,reactive,ref,watch }from'vue'import {spring }from'vue3-spring'importpopDownfrom'../assets/sounds/pop-down.mp3'importpopUpOnfrom'../assets/sounds/pop-up-on.mp3'importpopUpOfffrom'../assets/sounds/pop-up-off.mp3'exportdefault {model: {prop:'checked',event:'change', },emits: ['update:checked'],props: {checked: {type:Boolean,required:false,default:false, }, },computed: {value: {get() {returnthis.checked },set(value) {if (this.value) {this.filledSpring.scale=1.0this.onSound.play() }else {this.filledSpring.scale=0this.offSound.play() }this.$emit('update:checked',value) }, }, },setup({checked }) {// SoundsconstactiveSound=useSound(popDown, {volume:0.25 })constonSound=useSound(popUpOn, {volume:0.25 })constoffSound=useSound(popUpOff, {volume:0.25 })// Refsconstactive=ref(false)// SpringsconstspringConfig= {stiffness:400,damping:22, }constfilledSpring=spring({scale:1.0 },springConfig)constoutlineSpring=spring( {scale:1.0, },springConfig, )// Watcherswatch([active], ()=> {if (active.value) {activeSound.play()outlineSpring.scale=0.8 }else {outlineSpring.scale=1 } })return {active,activeSound,onSound,offSound,filledSpring,outlineSpring, } },}</script>
<template><divclass="flex justify-center"><Button @mouseover="play" @mouseleave="stop"label="Trumpet"> 🎺</Button></div></template><script>import {useSound }from'@vueuse/sound'importtrumpetSfxfrom'../assets/sounds/fanfare.mp3'importButtonfrom'./Button.vue'exportdefault {components: {Button },setup() {const {play,stop }=useSound(trumpetSfx)return {play,stop, } },}</script>
<template><divclass="flex justify-center"><Button @click="handleClick"label="Person with lines from mouth">🗣</Button></div></template><script>import {ref }from'vue'import {useSound }from'@vueuse/sound'importglugSfxfrom'../assets/sounds/glug.mp3'importButtonfrom'./Button.vue'exportdefault {components: {Button },setup() {constplaybackRate=ref(0.75)const {play }=useSound(glugSfx, {playbackRate,interrupt:true, })consthandleClick= ()=> {playbackRate.value=playbackRate.value+0.1play() }return {handleClick } },}</script>
<template><divclass="flex items-center justify-center gap-4"><Button @click="play({ id: 'kick' })"label="Kick">🥁</Button><Button @click="play({ id: 'hihat' })"label="Hi-hat">🎩</Button><Button @click="play({ id: 'snare' })"label="Snare">🍗</Button><Button @click="play({ id: 'cowbell' })"label="Cowbell">🔔</Button></div></template><script>import {onMounted,onUnmounted }from'vue'import {useSound }from'@vueuse/sound'importdrumSfxfrom'../assets/sounds/909-drums.mp3'importButtonfrom'./Button.vue'constuseKeyboardBindings= (map)=> {consthandlePress= (ev)=> {consthandler=map[ev.key]if (typeofhandler==='function') {handler() } }onMounted(()=> {window.addEventListener('keydown',handlePress) })onUnmounted(()=> {window.removeEventListener('keydown',handlePress) })}exportdefault {components: {Button },setup() {const {play }=useSound(drumSfx, {sprite: {kick: [0,350],hihat: [374,160],snare: [666,290],cowbell: [968,200], }, })useKeyboardBindings({1: ()=>play({id:'kick' }),2: ()=>play({id:'hihat' }),3: ()=>play({id:'snare' }),4: ()=>play({id:'cowbell' }), })return {play, } },}</script>
<template><divclass="flex flex-col justify-center"><divclass="flex justify-center mb-6"><Button @click="handleClick"label="Control knobs">🎛️</Button></div></div></template><script>import {ref }from'vue'import {useSound }from'@vueuse/sound'importglugSfxfrom'../assets/sounds/glug.mp3'importButtonfrom'./Button.vue'exportdefault {components: {Button },setup() {constvolume=ref(0.1)const {play }=useSound(glugSfx, {volume,interrupt:true, })consthandleClick= ()=> {volume.value=parseFloat(Math.random().toFixed(2))play() }return {handleClick } },}</script>
Written byYaël Guilloux and inspired fromuse-sound byJosh W. Comeau.