PartsAnimated Nav

Click anywhere or hover here

lib/airport/AirportNav.svelte

<script lang="ts">
	import { onMount } from 'svelte';
	import { fly } from 'svelte/transition';

	export let items;

	export let textItems = [
		{ text: '' },
		{ text: 'Projects' },
		{ text: 'We need to demand a new way of life' },
		{ text: 'Short' },
		{ text: 'Longer title' },
		{ text: "I'm thinking this would be like a navbar / title of page type of module" },
		{ text: 'It can sit above the page and respond to events like link hover' },
		{ text: "J'love !!" }
	];

	let currentText = 0;

	let textBox: HTMLDivElement;

	$: content = textItems[currentText].text;
	$: fontSize = calculateTextSize(content);
	$: content, setSizes();

	function calculateTextSize(textContent: string) {
		// get character count of string
		let charCount = textContent.length;

		if (charCount === 0) return;
		if (charCount <= 5) {
			return '80';
		} else if (charCount <= 10) {
			return '50';
		} else if (charCount <= 15) {
			return '30';
		} else return '28';
	}

	function handleClick() {
		if (currentText <= textItems.length - 2) {
			currentText += 1;
		} else {
			currentText = 0;
		}
	}

	let containerWidth = 0;
	let containerHeight = 0;

	function setSizes() {
		// if (!textBox) return;
		setTimeout(() => {
			containerWidth = textBox?.offsetWidth;
			containerHeight = textBox?.offsetHeight < 60 ? 60 : textBox?.offsetHeight;
			// console.log(textItems[currentText], textBox, containerWidth, containerHeight);
		}, 200);
	}
</script>

<div class="w-fit relative flex z-20">
	<a
		href="/"
		class="w-[60px] min-h-[60px] bg-yellow-300 flex place-items-start justify-center p-4 group"
	>
		<!-- icon -->
		<svg
			class="arrow w-full max-w-[24px] rotate-45 group-hover:rotate-0"
			viewBox="0 0 24 24"
			stroke-width="3"
			fill="none"
			xmlns="http://www.w3.org/2000/svg"
			color="#000000"
			><path
				d="M21 12H3m0 0l8.5-8.5M3 12l8.5 8.5"
				stroke="#000000"
				stroke-width="3"
				stroke-linecap="round"
				stroke-linejoin="round"
			/></svg
		>
	</a>
	<div
		class="container bg-black p-0 text-white overflow-hidden"
		style="width:{containerWidth}px; height:{containerHeight}px;"
	>
		<div class="textbox w-fit" style="font-size: {fontSize}px; line-height:1.01;">
			<div class="text w-fit grid place-items-center" class:p-2={content.length}>
				{#key content}
					<div
						bind:this={textBox}
						class="absolute top-0 left-0"
						style="min-width: {content.length ? '200px' : '0'}; padding: {content.length
							? '10px'
							: '0'};"
						out:fly|local={{ y: 100, duration: 600 }}
						in:fly|local={{ y: -100, duration: 600 }}
					>
						{content}
					</div>
				{/key}
			</div>
		</div>
	</div>
</div>

<!-- svelte-ignore a11y-click-events-have-key-events -->
<div
	on:click={handleClick}
	class="fixed top-0 right-0 w-full h-full text-xs uppercase grid place-items-center cursor-default"
>
	<p
		on:mouseenter={() => (content = 'Hovering')}
		on:mouseleave={() => (content = textItems[currentText].text)}
		class="hover:opacity-50 p-2"
	>
		Click anywhere or hover here
	</p>
</div>

<style lang="postcss">
	.container {
		@apply transform-gpu;
		transition: all 0.5s cubic-bezier(0.16, 1, 0.3, 1);
	}
	.textbox {
		@apply transform-gpu;
		position: relative;
		transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
		max-width: 400px;
	}

	.arrow {
		transition: all 0.5s cubic-bezier(0.16, 1, 0.3, 1);
	}
</style>