From c3698263aeb0f6fd85f3d1d2d728ed442f5f713f Mon Sep 17 00:00:00 2001
From: Fuwn <contact@fuwn.me>
Date: Sat, 20 Apr 2024 22:12:38 -0700
Subject: feat(user): user parallax image

---
 src/lib/ParallaxImage.svelte | 45 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 src/lib/ParallaxImage.svelte

(limited to 'src/lib/ParallaxImage.svelte')

diff --git a/src/lib/ParallaxImage.svelte b/src/lib/ParallaxImage.svelte
new file mode 100644
index 00000000..cebbfa2b
--- /dev/null
+++ b/src/lib/ParallaxImage.svelte
@@ -0,0 +1,45 @@
+<script lang="ts">
+	import { cubicOut } from 'svelte/easing';
+	import { tweened } from 'svelte/motion';
+
+	export let source: string;
+	export let duration = 300 * 1.75;
+	export let easing = cubicOut;
+	export let alternativeText: string;
+	export let classes = '';
+	export let style = '';
+	export const factor = 1.25;
+	const limit = 300 * 1.75;
+
+	let badgeReference: HTMLImageElement;
+	const mouse = tweened({ x: 0, y: 0 }, { duration, easing });
+
+	const handleMouseMove = (event: MouseEvent) => {
+		const boundingRectangle = badgeReference.getBoundingClientRect();
+
+		if ($mouse.x === 0 && $mouse.y === 0) $mouse = { x: event.clientX, y: event.clientY };
+
+		$mouse.x +=
+			(-(event.clientX - boundingRectangle.left - boundingRectangle.width / 2) - $mouse.x) * factor;
+		$mouse.y +=
+			(-(event.clientY - boundingRectangle.top - boundingRectangle.height / 2) - $mouse.y) * factor;
+		$mouse.x = Math.max(Math.min($mouse.x, limit), -limit);
+		$mouse.y = Math.max(Math.min($mouse.y, limit), -limit);
+	};
+
+	const handleMouseLeave = () => {
+		$mouse = { x: 0, y: 0 };
+	};
+</script>
+
+<img
+	src={source}
+	bind:this={badgeReference}
+	style={`transform: perspective(1000px) rotateX(${$mouse.y / 10}deg) rotateY(${
+		-$mouse.x / 10
+	}deg); ${style}`}
+	alt={alternativeText}
+	on:mousemove={handleMouseMove}
+	on:mouseleave={handleMouseLeave}
+	class={classes}
+/>
-- 
cgit v1.2.3

