diff options
| author | Fuwn <[email protected]> | 2024-04-18 18:38:14 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2024-04-18 18:38:14 -0700 |
| commit | 15f52f55955d56989b7b6039c04c0df427ff1bde (patch) | |
| tree | 60f1d27556628e2d552e090e190088be8197a85f /src/lib | |
| parent | feat(badges): auto-collapse awc when owner (diff) | |
| download | due.moe-15f52f55955d56989b7b6039c04c0df427ff1bde.tar.xz due.moe-15f52f55955d56989b7b6039c04c0df427ff1bde.zip | |
feat(badges): badge preview pane
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/BadgeWall/BadgePreview.svelte | 129 | ||||
| -rw-r--r-- | src/lib/FallbackBadge.svelte | 12 |
2 files changed, 140 insertions, 1 deletions
diff --git a/src/lib/BadgeWall/BadgePreview.svelte b/src/lib/BadgeWall/BadgePreview.svelte new file mode 100644 index 00000000..0cf7bb9c --- /dev/null +++ b/src/lib/BadgeWall/BadgePreview.svelte @@ -0,0 +1,129 @@ +<script lang="ts"> + import type { Badge } from '$lib/Database/userBadges'; + import cdn from '$lib/Utility/cdn'; + import { databaseTimeToDate } from '$lib/Utility/time'; + import locale from '$stores/locale'; + import { cubicOut } from 'svelte/easing'; + import { tweened } from 'svelte/motion'; + + export let badge: Badge | undefined; + + let badgeReference: HTMLImageElement; + const mouse = tweened( + { x: 0, y: 0 }, + { + duration: 200 * 1.75, + easing: cubicOut + } + ); + + const handleMouseMove = (event: MouseEvent) => { + const boundingRectangle = badgeReference.getBoundingClientRect(); + const factor = 1.25; + + 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; + }; + + const handleMouseLeave = () => { + $mouse = { x: 0, y: 0 }; + }; +</script> + +{#if badge} + <div class="badge-preview"> + {#if badge.image} + <div + on:mousemove={handleMouseMove} + on:mouseleave={handleMouseLeave} + role="img" + class="badge-container" + > + <img + src={cdn(badge.image)} + bind:this={badgeReference} + style="transform: perspective(1000px) rotateX({$mouse.y / 10}deg) rotateY({-$mouse.x / + 10}deg);" + alt={badge.description} + /> + </div> + + <p /> + {/if} + + {#if badge.time} + {$locale().dateFormatter(databaseTimeToDate(badge.time))} + + {#if (badge.designer || badge.source || badge.post) && !badge.description} + <p /> + {:else if badge.description} + <br /> + {/if} + {/if} + + {#if badge.description} + {badge.description} + + {#if badge.designer || badge.source || badge.post} + <p /> + {/if} + {/if} + + {#if badge.designer} + <b>Designer:</b> + + {#if badge.designer.startsWith('http')} + <a href={badge.designer} target="_blank"> + {badge.designer} + </a> + {:else if badge.designer.startsWith('@')} + <a href="https://anilist.co/user/{badge.designer.replace('@', '')}" target="_blank"> + {badge.designer} + </a> + {:else} + {badge.designer} + {/if} + + <br /> + {/if} + + {#if badge.post} + <b>{badge.post.includes('forum') ? 'Forum' : 'Activity'}:</b> + + <a href={badge.post} target="_blank"> + {badge.post} + </a> + + <br /> + {/if} + + {#if badge.source} + <b>Source:</b> + + {#if badge.source.startsWith('http')} + <a href={badge.source} target="_blank"> + {badge.source} + </a> + {:else} + {badge.source} + {/if} + {/if} + </div> +{/if} + +<style> + .badge-preview img { + border-radius: 8px; + max-width: 25vh; + } + + .badge-container { + display: flex; + justify-content: center; + align-items: center; + } +</style> diff --git a/src/lib/FallbackBadge.svelte b/src/lib/FallbackBadge.svelte index 323ea791..c4604263 100644 --- a/src/lib/FallbackBadge.svelte +++ b/src/lib/FallbackBadge.svelte @@ -13,6 +13,7 @@ export let hideOnError = false; export let badge: Badge; export let style = ''; + export let selectedBadge: Badge | null = null; let replaceCount = 0; let badgeReference: HTMLImageElement; @@ -56,7 +57,16 @@ pin={`badge-${badge.id}`} pinPosition="top" > - <a href={badge.post} target="_blank" class="badge-container badge"> + <a + href={'#'} + target="_blank" + class="badge-container badge" + on:click={(e) => { + e.preventDefault(); + + selectedBadge = badge; + }} + > <img src={source} alt={alternative} |