feat: tiltcard component
This commit is contained in:
parent
b7f951b9c7
commit
2e7009fef2
1 changed files with 74 additions and 0 deletions
74
src/routes/tiltcard.svelte
Normal file
74
src/routes/tiltcard.svelte
Normal file
|
@ -0,0 +1,74 @@
|
|||
<script lang="ts">
|
||||
export let imageSrc: string;
|
||||
export let imageAlt: string = 'Card image';
|
||||
export let width: string = '300px';
|
||||
export let height: string = '400px';
|
||||
|
||||
let cardElement: HTMLDivElement;
|
||||
let rotateX = 0;
|
||||
let rotateY = 0;
|
||||
let isHovered = false;
|
||||
|
||||
// Derived shadow offsets
|
||||
let shadowX = 0;
|
||||
let shadowY = 0;
|
||||
let shadowBlur = 20;
|
||||
|
||||
function handleMouseMove(event: MouseEvent) {
|
||||
if (!cardElement) return;
|
||||
|
||||
const rect = cardElement.getBoundingClientRect();
|
||||
const x = event.clientX - rect.left;
|
||||
const y = event.clientY - rect.top;
|
||||
|
||||
const centerX = rect.width / 2;
|
||||
const centerY = rect.height / 2;
|
||||
|
||||
// Calculate rotation based on cursor position (max tilt of 10 degrees)
|
||||
rotateY = ((x - centerX) / centerX) * 10 * 2;
|
||||
rotateX = ((centerY - y) / centerY) * 10 * 2;
|
||||
|
||||
// Make shadow move opposite to tilt for a realistic lighting effect
|
||||
shadowX = -rotateY * 0.7; // exaggerate slightly
|
||||
shadowY = rotateX * 0.7;
|
||||
}
|
||||
|
||||
function handleMouseEnter() {
|
||||
isHovered = true;
|
||||
}
|
||||
|
||||
function handleMouseLeave() {
|
||||
isHovered = false;
|
||||
rotateX = 0;
|
||||
rotateY = 0;
|
||||
shadowX = 0;
|
||||
shadowY = 0;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
bind:this={cardElement}
|
||||
class="cursor-pointer"
|
||||
class:scale-[1.03]={isHovered}
|
||||
style="
|
||||
width: {width};
|
||||
height: {height};
|
||||
perspective: 1000px;
|
||||
filter: drop-shadow({shadowX}px {shadowY}px 0px rgba(0, 0, 0, 0.5));
|
||||
"
|
||||
on:mousemove={handleMouseMove}
|
||||
on:mouseenter={handleMouseEnter}
|
||||
on:mouseleave={handleMouseLeave}
|
||||
role="img"
|
||||
aria-label={imageAlt}
|
||||
>
|
||||
<img
|
||||
src={imageSrc}
|
||||
alt={imageAlt}
|
||||
class="h-full w-full rounded-xl object-cover transition-transform duration-100 ease-out"
|
||||
style="
|
||||
transform: rotateX({rotateX}deg) rotateY({rotateY}deg);
|
||||
transform-style: preserve-3d;
|
||||
"
|
||||
/>
|
||||
</div>
|
Loading…
Add table
Reference in a new issue