Add parallax effect to product card in desktop
This commit is contained in:
@@ -4,6 +4,14 @@
|
||||
import Tag from "~/components/global/Tag.vue";
|
||||
import Rate from "~/components/global/Rate.vue";
|
||||
import ColorCircle from "~/components/global/ColorCircle.vue";
|
||||
import { useRatio } from "~/composables/global/useRatio";
|
||||
|
||||
// state
|
||||
|
||||
const containerEl = ref<HTMLElement | null>(null);
|
||||
const { isOutside: isMouseOutsideContainer } = useMouseInElement(containerEl);
|
||||
const parallax = reactive(useParallax(containerEl));
|
||||
const { isMobile } = useRatio();
|
||||
|
||||
// types
|
||||
|
||||
@@ -29,50 +37,70 @@ const { id, colors } = toRefs(props);
|
||||
const limitedColors = computed(() => {
|
||||
return colors.value.slice(0, 3);
|
||||
});
|
||||
|
||||
const parallaxStyle = computed(() => {
|
||||
if (!isMobile.value && isMouseOutsideContainer.value) {
|
||||
return {
|
||||
transform: `rotateX(0deg) rotateY(0deg)`,
|
||||
transition: "0.3s ease-out all",
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
transform: `rotateX(${parallax.roll * 20}deg) rotateY(${parallax.tilt * 20}deg)`,
|
||||
transition: "0.3s ease-out all",
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li class="w-full">
|
||||
<NuxtLink :to="'/product/' + slug">
|
||||
<div class="@container group">
|
||||
<div
|
||||
class="group relative size-full aspect-square rounded-2xl bg-white brightness-[95%] overflow-hidden p-6"
|
||||
>
|
||||
<NuxtImg
|
||||
:id="`product-image-${id}`"
|
||||
:src="picture"
|
||||
class="group-hover:scale-105 transition-transform duration-200 size-full object-contain absolute inset-0"
|
||||
alt="product-background"
|
||||
/>
|
||||
<div
|
||||
class="@container group"
|
||||
ref="containerEl"
|
||||
>
|
||||
<div class="perspective-midrange">
|
||||
<div
|
||||
:style="parallaxStyle"
|
||||
class="group relative size-full aspect-square rounded-2xl bg-white brightness-[95%] overflow-hidden p-6"
|
||||
>
|
||||
<NuxtImg
|
||||
:id="`product-image-${id}`"
|
||||
:src="picture"
|
||||
class="group-hover:scale-105 transition-transform duration-200 size-full object-contain absolute inset-0"
|
||||
alt="product-background"
|
||||
/>
|
||||
|
||||
<!-- <div
|
||||
<!-- <div
|
||||
v-if="darkLayer"
|
||||
class="bg-linear-to-t inset-0 from-black/50 to-transparent to-55% absolute z-10 size-full"
|
||||
/> -->
|
||||
|
||||
<div
|
||||
class="flex justify-between items-center absolute px-4 @[280px]:px-6 pt-4 @[280px]:pt-6 top-0 w-full inset-x-0"
|
||||
>
|
||||
<Rate
|
||||
v-if="rate"
|
||||
:rate="rate"
|
||||
/>
|
||||
<Tag v-if="tag">
|
||||
{{ tag }}
|
||||
</Tag>
|
||||
</div>
|
||||
<div
|
||||
class="absolute opacity-0 group-hover:opacity-100 bg-gradient-to-t transition-all group-hover:from-black/30 to-transparent inset-x-0 bottom-0 pb-4 @[280px]:pb-6 px-4 @[280px]:px-6 flex flex-row-reverse justify-between items-end z-10"
|
||||
>
|
||||
<div
|
||||
class="items-center flex gap-2 @[280px]:mt-1 transition-all translate-y-1 group-hover:translate-y-0"
|
||||
class="flex justify-between items-center absolute px-4 @[280px]:px-6 pt-4 @[280px]:pt-6 top-0 w-full inset-x-0"
|
||||
>
|
||||
<ColorCircle
|
||||
v-for="color in limitedColors"
|
||||
:key="color"
|
||||
:style="{ backgroundColor: color }"
|
||||
class="!size-5 @[280px]:!size-6"
|
||||
<Rate
|
||||
v-if="rate"
|
||||
:rate="rate"
|
||||
/>
|
||||
<Tag v-if="tag">
|
||||
{{ tag }}
|
||||
</Tag>
|
||||
</div>
|
||||
<div
|
||||
class="absolute opacity-0 group-hover:opacity-100 bg-gradient-to-t transition-all group-hover:from-black/30 to-transparent inset-x-0 bottom-0 pb-4 @[280px]:pb-6 px-4 @[280px]:px-6 flex flex-row-reverse justify-between items-end z-10"
|
||||
>
|
||||
<div
|
||||
class="items-center flex gap-2 @[280px]:mt-1 transition-all translate-y-1 group-hover:translate-y-0"
|
||||
>
|
||||
<ColorCircle
|
||||
v-for="color in limitedColors"
|
||||
:key="color"
|
||||
:style="{ backgroundColor: color }"
|
||||
class="!size-5 @[280px]:!size-6"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user