feat: 88x31 buttons page

This commit is contained in:
trafficlunar 2025-12-02 19:52:27 +00:00
parent c7b1565d48
commit 377e1c1db7
38 changed files with 189 additions and 2 deletions

100
src/components/88x31.svelte Normal file
View file

@ -0,0 +1,100 @@
<script lang="ts">
const coolSites = [
{ href: "https://melankorin.net/", src: "https://melankorin.net/assets/img/buttons/button-1.gif" },
{ href: "https://ellenthekat.nekoweb.org", src: "https://ellenthekat.nekoweb.org/Images/oc%20headshot%20style.png" },
{ href: "https://dimden.dev/", src: "https://dimden.dev/services/images/88x31.gif" },
{ href: "https://daudix.one", src: "/88x31/sites/daudix.gif" },
{ href: "https://reduxflakes.nekoweb.org/", src: "/88x31/sites/reduc_anim.gif" },
];
const miscButtons = [
{ href: "https://www.7-zip.org/", src: "/88x31/7zip.gif" },
{ href: "https://ec.crypton.co.jp/pages/prod/virtualsinger/cv01_us", src: "/88x31/miku.gif" },
{ href: "https://ublockorigin.com/", src: "/88x31/ublock.png" },
{ src: "/88x31/xp.gif" },
{ src: "/88x31/dream.gif" },
{ href: "https://astro.build/", src: "/88x31/astro.png" },
{ href: "https://jellyfin.org/", src: "/88x31/jellyfin.gif" },
{ href: "https://www.qbittorrent.org/", src: "/88x31/qbittorrent.png" },
{ src: "/88x31/responsive.png" },
{ src: "/88x31/any88x31.gif" },
{ src: "/88x31/aperture.jpg" },
{ href: "https://archive.org/", src: "/88x31/archive.gif" },
{ src: "/88x31/blends.gif" },
{ src: "/88x31/button-flexbox.gif" },
{ src: "/88x31/computer.jpg" },
{ href: "https://www.firefox.com/en-US/", src: "/88x31/firefox.png" },
{ src: "/88x31/got_html.gif" },
{ src: "/88x31/homer.gif" },
{ src: "/88x31/linux.gif" },
{ src: "/88x31/love_blahaj.gif" },
{ src: "/88x31/nyan.gif" },
{ src: "/88x31/righttorepair.gif" },
{ src: "/88x31/sourcemissing.gif" },
{ src: "/88x31/stardew-valley.gif" },
{ src: "/88x31/tom-scott.webp" },
{ href: "https://vscodium.com/", src: "/88x31/vscodium.gif" },
{ src: "/88x31/wii.gif" },
{ src: "/88x31/plasticlove.gif" },
];
const imgStyle = "image-rendering: crisp-edges;";
</script>
<div class="flex items-center gap-4 text-overlay2 text-sm font-medium my-4">
<hr class="grow border-surface0" />
<span>cool sites</span>
<hr class="grow border-surface0" />
</div>
<div class="button-container">
{#each coolSites as { href, src }}
<div>
{#if href}
<a target="_blank" {href}><img {src} width="88" height="31" alt="button" class="button-88x31" style={imgStyle} /></a>
{:else}
<img {src} width="88" height="31" alt="button" class="button-88x31" style={imgStyle} />
{/if}
</div>
{/each}
</div>
<div class="flex items-center gap-4 text-overlay2 text-sm font-medium my-4">
<hr class="grow border-surface0" />
<span>misc</span>
<hr class="grow border-surface0" />
</div>
<div class="button-container">
{#each miscButtons as { href, src }}
<div>
{#if href}
<a target="_blank" {href}><img {src} width="88" height="31" alt="button" class="button-88x31" style={imgStyle} /></a>
{:else}
<img {src} width="88" height="31" alt="button" class="button-88x31" style={imgStyle} />
{/if}
</div>
{/each}
</div>
<style lang="postcss">
.button-container {
@apply flex justify-center flex-wrap;
}
.button-container div {
@apply hover:z-10;
}
.button-container div:nth-child(odd) .button-88x31 {
@apply hover:-rotate-2!;
}
.button-88x31 {
@apply hover:scale-125 hover:rotate-2 transition duration-200;
}
.button-container:hover .button-88x31:not(:hover) {
@apply opacity-50 brightness-50;
}
</style>

View file

@ -0,0 +1,46 @@
<script lang="ts">
import { scale } from "svelte/transition";
let button: HTMLButtonElement;
let hasCopied = false;
function handleCopy() {
navigator.clipboard.writeText(
'<a href="https://trafficlunar.net/" target="_blank"><img src="https://trafficlunar.net/88x31.gif" alt="trafficlunar" /></a>'
);
hasCopied = true;
button.setAttribute("data-tooltip", "Copied!");
setTimeout(() => {
hasCopied = false;
button.setAttribute("data-tooltip", "Copy");
}, 1000);
}
</script>
<div class="absolute right-2">
<button aria-label="Copy Button Code" data-tooltip="Copy" onclick={handleCopy} bind:this={button} class="cursor-pointer size-5.5">
{#if hasCopied}
<svg in:scale out:scale xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" class="absolute top-0 left-0"
><path fill="currentColor" d="m9.55 18l-5.7-5.7l1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z" /></svg
>
{:else}
<svg in:scale out:scale xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" class="absolute inset-0"
><g fill="none"
><path
fill="currentColor"
fill-opacity="0.16"
d="M18.6 9h-7.2A2.4 2.4 0 0 0 9 11.4v7.2a2.4 2.4 0 0 0 2.4 2.4h7.2a2.4 2.4 0 0 0 2.4-2.4v-7.2A2.4 2.4 0 0 0 18.6 9"
/><path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-miterlimit="10"
stroke-width="1.5"
d="M6 15h-.6C4.07 15 3 13.93 3 12.6V5.4C3 4.07 4.07 3 5.4 3h7.2C13.93 3 15 4.07 15 5.4V6m-3.6 3h7.2a2.4 2.4 0 0 1 2.4 2.4v7.2a2.4 2.4 0 0 1-2.4 2.4h-7.2A2.4 2.4 0 0 1 9 18.6v-7.2A2.4 2.4 0 0 1 11.4 9"
/></g
></svg
>
{/if}
</button>
</div>

View file

@ -2,6 +2,7 @@
const links = [
{ name: "home", url: "/" },
{ name: "status", url: "/status/" },
{ name: "buttons", url: "/buttons/" },
];
let pathname = $state("/");
@ -25,11 +26,11 @@
</script>
<section class="p-1.5! mb-8 w-fit">
<div class="relative grid grid-cols-2 gap-1.5">
<div class="relative grid grid-cols-3 gap-1.5">
<!-- Animated background for active link -->
{#if activeIndex !== -1}
<div
class="absolute inset-0 bg-peach rounded w-[calc((100%/2)-0.25rem)] pointer-events-none z-10 transition-all duration-300 ease-out"
class="absolute inset-0 bg-peach rounded w-[calc((100%/3)-0.25rem)] pointer-events-none z-10 transition-all duration-300 ease-out"
style="transform: translateX(calc({activeIndex * 100}% + {activeIndex * 0.375}rem)) {isTransitioning ? 'scale(1.1)' : 'scale(1)'};"
></div>
{/if}