PartsCircle

$lib/circle/Circle.svelte

<script lang="ts">
	import { onMount, setContext } from 'svelte';
	import { spring } from 'svelte/motion';
	import Dot from './Dot.svelte';

	let num = 10;
	let angle = (2 * Math.PI) / num;

	let multiplier = spring(100, {
		stiffness: 0.1,
		damping: 0.63
	});

	setContext('multiplier', multiplier);

	let scroll = 0;

	let parentDiv: HTMLDivElement;

	onMount(() => {
		window.addEventListener('wheel', (event) => {
			const delta = Math.sign(event.deltaY);
			// console.info(event.deltaY, delta);
			scroll += event.deltaY;
			// $multiplier = 1 + Math.abs(event.deltaY) / 200;
		});

		$multiplier = 1;
	});
</script>

<div bind:this={parentDiv} class="relative w-[350px] h-[350px]">
	{#each Array(num) as item, i}
		<Dot parent={parentDiv} index={i} {num} angle={angle * i + scroll * 0.003} />
	{/each}
</div>

<style>
</style>

$lib/circle/Dot.svelte

<script lang="ts">
	import { getContext, onMount } from 'svelte';
	import { spring } from 'svelte/motion';
	import { fade } from 'svelte/transition';
	// dot

	export let parent: HTMLDivElement;
	export let index = 0;
	export let angle: any = 0;
	export let num = 10;
	let x = 0;
	let y = 0;

	let multiplier: any = getContext('multiplier');

	$: boxSize = parent?.offsetWidth / 7;

	$: scale = parent?.offsetWidth / 2 - boxSize / 2;

	// $: console.log('parent', parent, parent?.offsetWidth);

	$: x = Math.cos(angle) * scale;
	$: y = Math.sin(angle) * scale;

	$: top = $multiplier * y + parent?.offsetWidth / 2 - boxSize / 2;
	$: left = $multiplier * x + parent?.offsetHeight / 2 - boxSize / 2;

	let url = '';

	onMount(() => {
		url = 'https://picsum.photos/seed/' + index + '/200/300';
	});

	function simulateClick() {
		$multiplier = 6;
		setTimeout(() => {
			$multiplier = 1;
		}, 1500);
	}
</script>

{#if parent}
	<a
		href="#"
		on:click={simulateClick}
		transition:fade|local
		class="dot"
		style="left: {left}px; top: {top}px; width:{boxSize}px; height:{boxSize}px;"
	>
		<img class="w-full h-full object-cover object-center" src={url} alt="" />
	</a>
{/if}

<style lang="postcss">
	:global(.dot) {
		height: 20px;
		width: 20px;
		/* border-radius: 50%; */
		@apply bg-neutral-400;
		position: absolute;
		text-align: center;
	}
</style>