mirror of
https://github.com/vkaelin/LeagueStats.git
synced 2026-03-25 12:57:28 +00:00
feat: add ripple effect when clicking on matches
This commit is contained in:
parent
5e19b2b0bf
commit
6819cbe188
2 changed files with 116 additions and 3 deletions
|
|
@ -1,7 +1,8 @@
|
|||
<template>
|
||||
<li class="ml-4 relative">
|
||||
<div
|
||||
@click="displayDetails"
|
||||
<Ripple
|
||||
@click.native="displayDetails"
|
||||
color="rgba(43, 108, 176, 0.7)"
|
||||
:class="[matchResultClass, showDetails ? 'rounded-t-lg' : 'rounded-lg']"
|
||||
class="match relative mt-4 bg-blue-800 text-white text-base cursor-pointer hover:shadow-xl"
|
||||
>
|
||||
|
|
@ -128,7 +129,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Ripple>
|
||||
<DetailedMatch :data="getMatchDetails(data.gameId) || {}" :details-open="showDetails" />
|
||||
</li>
|
||||
</template>
|
||||
|
|
@ -137,11 +138,13 @@
|
|||
import { mapActions, mapState, mapGetters } from 'vuex'
|
||||
import DetailedMatch from '@/components/Match/DetailedMatch'
|
||||
import MatchItems from '@/components/Match/MatchItems'
|
||||
import Ripple from '@/components/Ripple.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DetailedMatch,
|
||||
MatchItems,
|
||||
Ripple,
|
||||
},
|
||||
|
||||
props: {
|
||||
|
|
|
|||
110
client/src/components/Ripple.vue
Normal file
110
client/src/components/Ripple.vue
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
<template>
|
||||
<div
|
||||
ref="container"
|
||||
@mousedown="addRipple"
|
||||
class="relative overflow-hidden cursor-pointer"
|
||||
style="z-index: 1;"
|
||||
>
|
||||
<transition-group
|
||||
class="absolute top-0 left-0 w-full h-full pointer-events-none"
|
||||
style="z-index: -1;"
|
||||
name="grow"
|
||||
tag="div"
|
||||
>
|
||||
<div
|
||||
v-for="ripple in ripples"
|
||||
:key="ripple.id"
|
||||
class="absolute w-full h-full opacity-0 rounded-full pointer-events-none"
|
||||
:style="{
|
||||
top: ripple.top,
|
||||
left: ripple.left,
|
||||
width: ripple.width,
|
||||
height: ripple.height,
|
||||
background: color
|
||||
}"
|
||||
></div>
|
||||
</transition-group>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
color: {
|
||||
type: String,
|
||||
default: 'rgba(255, 255, 255, 0.3)'
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
ripples: [],
|
||||
rippleWidth: 0,
|
||||
halfRippleWidth: 0,
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
const width = this.$refs.container.offsetWidth
|
||||
const height = this.$refs.container.offsetHeight
|
||||
this.rippleWidth = width > height ? width : height
|
||||
this.halfRippleWidth = this.rippleWidth / 2
|
||||
|
||||
window.addEventListener('mouseup', this.purgeRipples)
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('mouseup', this.purgeRipples)
|
||||
},
|
||||
|
||||
methods: {
|
||||
addRipple(e) {
|
||||
const { left, top } = this.$refs.container.getBoundingClientRect()
|
||||
const rippleId = Date.now()
|
||||
this.ripples.push({
|
||||
width: `${this.rippleWidth}px`,
|
||||
height: `${this.rippleWidth}px`,
|
||||
left: `${e.clientX - left - this.halfRippleWidth}px`,
|
||||
top: `${e.clientY - top - this.halfRippleWidth}px`,
|
||||
id: rippleId
|
||||
})
|
||||
},
|
||||
purgeRipples() {
|
||||
this.ripples = []
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.grow-enter-active,
|
||||
.grow-enter-to-active {
|
||||
transition: all 1500ms ease-out;
|
||||
}
|
||||
|
||||
.grow-leave-active,
|
||||
.grow-leave-to-active {
|
||||
transition: all 700ms ease-out;
|
||||
}
|
||||
|
||||
.grow-enter {
|
||||
transform: scale(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.grow-enter-to {
|
||||
transform: scale(4);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.grow-leave {
|
||||
transform: scale(4);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.grow-leave-to {
|
||||
transform: scale(4);
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in a new issue