color hover animation
This commit is contained in:
parent
2464e7661c
commit
cb1d65e0b8
4 changed files with 51 additions and 6 deletions
|
|
@ -84,19 +84,19 @@ onMounted(() => {
|
||||||
clipPath: 'inset(0% 0% 0% 0%)',
|
clipPath: 'inset(0% 0% 0% 0%)',
|
||||||
...ANIMATION_SETTINGS,
|
...ANIMATION_SETTINGS,
|
||||||
},
|
},
|
||||||
'<+0.1',
|
0,
|
||||||
)
|
)
|
||||||
tl.value.fromTo(
|
tl.value.fromTo(
|
||||||
contentWindow.value,
|
contentWindow.value,
|
||||||
{ opacity: 0, clipPath: 'inset(0% 0% 100% 0%)' },
|
{ opacity: 0, clipPath: 'inset(0% 0% 100% 0%)' },
|
||||||
{ opacity: 1, clipPath: 'inset(0% 0% 0% 0%)', ...ANIMATION_SETTINGS },
|
{ opacity: 1, clipPath: 'inset(0% 0% 0% 0%)', ...ANIMATION_SETTINGS },
|
||||||
'<+0.1',
|
0,
|
||||||
)
|
)
|
||||||
tl.value.fromTo(
|
tl.value.fromTo(
|
||||||
closeWindow.value,
|
closeWindow.value,
|
||||||
{ opacity: 0 },
|
{ opacity: 0 },
|
||||||
{ opacity: 1, ...ANIMATION_SETTINGS },
|
{ opacity: 1, ...ANIMATION_SETTINGS },
|
||||||
'<+0.1',
|
0,
|
||||||
)
|
)
|
||||||
|
|
||||||
tl.value.pause(0)
|
tl.value.pause(0)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
>
|
>
|
||||||
<div class="mosaic-container">
|
<div class="mosaic-container">
|
||||||
<router-link
|
<router-link
|
||||||
v-for="cell in content.cells"
|
v-for="(cell, i) in content.cells"
|
||||||
:class="[
|
:class="[
|
||||||
'mosaic-cell',
|
'mosaic-cell',
|
||||||
`layout-${cell.width >= cell.height ? 'landscape' : 'portrait'}`,
|
`layout-${cell.width >= cell.height ? 'landscape' : 'portrait'}`,
|
||||||
|
|
@ -24,8 +24,10 @@
|
||||||
params: { id: cell.content.slug },
|
params: { id: cell.content.slug },
|
||||||
}"
|
}"
|
||||||
:key="`${viewport.index}-${cell.id}`"
|
:key="`${viewport.index}-${cell.id}`"
|
||||||
|
@mouseenter="onMouseEnter(i)"
|
||||||
ref="cells"
|
ref="cells"
|
||||||
>
|
>
|
||||||
|
<div class="hover-bg" :style="{ background: hoverColors[i] }" />
|
||||||
<strapi-media
|
<strapi-media
|
||||||
:image="cell.content.image"
|
:image="cell.content.image"
|
||||||
:aspect="100"
|
:aspect="100"
|
||||||
|
|
@ -40,6 +42,9 @@
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import gsap from 'gsap'
|
import gsap from 'gsap'
|
||||||
|
|
||||||
|
const THEME_S = 90
|
||||||
|
const THEME_L = 50
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
viewport: {
|
viewport: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|
@ -52,13 +57,23 @@ const props = defineProps({
|
||||||
})
|
})
|
||||||
|
|
||||||
const cells = ref([])
|
const cells = ref([])
|
||||||
|
const hoverColors = ref(
|
||||||
|
cells.value.map(
|
||||||
|
() => `hsl(${Math.random() * 360}deg ${THEME_S}% ${THEME_L}%)`,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
const onMouseEnter = (i) => {
|
||||||
|
hoverColors.value[i] =
|
||||||
|
`hsl(${Math.random() * 360}deg ${THEME_S}% ${THEME_L}%)`
|
||||||
|
}
|
||||||
|
|
||||||
const onIntersect = (isIntersecting) => {
|
const onIntersect = (isIntersecting) => {
|
||||||
if (isIntersecting) {
|
if (isIntersecting) {
|
||||||
if (!cells.value) return
|
if (!cells.value) return
|
||||||
|
|
||||||
const cellGifs = cells.value
|
const cellGifs = cells.value
|
||||||
.map((cell) => cell.$el?.children?.[0])
|
.map((cell) => cell.$el?.children?.[1])
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
|
|
||||||
gsap.to(cellGifs, { opacity: 1, duration: 0, stagger: 0.1 })
|
gsap.to(cellGifs, { opacity: 1, duration: 0, stagger: 0.1 })
|
||||||
|
|
@ -98,9 +113,25 @@ const onIntersect = (isIntersecting) => {
|
||||||
aspect-ratio: 1;
|
aspect-ratio: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.hover-bg {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
clip-path: circle(0% at 50% 50%);
|
||||||
|
transition: clip-path 0.3s ease-in-out;
|
||||||
|
}
|
||||||
.strapi-media {
|
.strapi-media {
|
||||||
mix-blend-mode: darken;
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
position: relative;
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.strapi-media {
|
||||||
|
@include bonk-animation(0s, 1s, 10deg);
|
||||||
|
}
|
||||||
|
.hover-bg {
|
||||||
|
clip-path: circle(100% at 50% 50%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -185,3 +185,8 @@ $mobile-height: get('viewports.mobile.height');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin bonk-animation($delay: 0s, $duration: 1s, $angle: 25deg) {
|
||||||
|
--bonk-angle: #{$angle};
|
||||||
|
animation: bonk $duration $delay infinite step-end;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,3 +59,12 @@ dt {
|
||||||
code {
|
code {
|
||||||
@include code;
|
@include code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes bonk {
|
||||||
|
0% {
|
||||||
|
transform: rotate(calc(var(--bonk-angle) * -1));
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: rotate(var(--bonk-angle));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue