summaryrefslogtreecommitdiff
path: root/src/routes/+layout.svelte
diff options
context:
space:
mode:
authornetop://ウィビ <paul@webb.page>2026-04-11 14:42:43 -0700
committernetop://ウィビ <paul@webb.page>2026-04-11 14:42:43 -0700
commitb052f741d935abd2f51423abf3fcda9157844b5c (patch)
treed01d9db0e4c4f4f9093662a049db366b8b2301af /src/routes/+layout.svelte
initial commitHEADprimary
Diffstat (limited to 'src/routes/+layout.svelte')
-rw-r--r--src/routes/+layout.svelte147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
new file mode 100644
index 0000000..be635e8
--- /dev/null
+++ b/src/routes/+layout.svelte
@@ -0,0 +1,147 @@
+<script lang="ts">
+ //// import
+ import { browser } from "$app/environment";
+ import { onMount } from "svelte";
+
+ //// util
+ import "./../../sass/global.scss";
+
+ //// var
+ const scrollControl = createScrollPreventer();
+
+ //// function
+ function horizontalScroll(event: WheelEvent): void {
+ const target = (event.target as HTMLElement).closest("section");
+
+ if (target && isVerticallyScrollable(target) && !isAtVerticalScrollLimit(target, event.deltaY) && isFullyInView(target))
+ return; /// ignore vertically scrollable elements
+
+ if (event.deltaY !== 0) {
+ event.preventDefault();
+ window.scrollBy({ left: event.deltaY });
+ }
+ }
+
+ function isAtVerticalScrollLimit(element: HTMLElement, deltaY: number) {
+ if (!element || !deltaY)
+ return false;
+
+ return (deltaY > 0 && Math.abs(element.scrollTop + element.clientHeight - element.scrollHeight) < 1) ||
+ (deltaY < 0 && element.scrollTop <= 0);
+ }
+
+ function isFullyInView(element: HTMLElement) {
+ if (!element)
+ return false;
+
+ const rect = element.getBoundingClientRect();
+
+ return (
+ rect.top >= 0 &&
+ rect.left >= 24 && // 0
+ rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
+ rect.right <= (window.innerWidth || document.documentElement.clientWidth)
+ );
+ }
+
+ function isVerticallyScrollable(element: HTMLElement) {
+ if (!element)
+ return false;
+
+ return element.scrollHeight > element.clientHeight;
+ }
+
+ function createScrollPreventer(): { prevent: () => void; allow: () => void } {
+ return {
+ prevent: () => {
+ window.removeEventListener("wheel", horizontalScroll);
+ },
+ allow: () => {
+ window.addEventListener("wheel", horizontalScroll, { passive: false });
+ }
+ };
+ }
+
+ /// ready
+ onMount(() => {
+ browser && scrollControl.allow();
+ });
+</script>
+
+<style lang="scss">
+ div {
+ width: fit-content; height: 100%;
+
+ display: flex;
+ white-space: nowrap;
+ }
+
+ aside {
+ width: 100%; height: calc(var(--line-height) * 2);
+ bottom: 0; left: 0;
+
+ align-items: center;
+ display: flex;
+ font-size: 0.8rem;
+ margin: 0;
+ padding-left: calc(var(--padding) * 3);
+ position: fixed;
+ text-transform: lowercase;
+
+ > * {
+ display: block;
+ margin-right: calc(var(--padding) * 2);
+ position: relative;
+ user-select: none;
+
+ &:not(:last-child) {
+ &::after {
+ content: "/";
+ font-weight: normal;
+ opacity: 0.15;
+ position: absolute;
+ right: calc(var(--padding) * -1.5);
+ }
+ }
+ }
+
+ em {
+ white-space: nowrap;
+ }
+
+ img {
+ image-rendering: pixelated;
+ }
+ }
+
+ :global(a) {
+ transition: none;
+
+ &:hover {
+ color: var(--uchu-yin-4);
+ text-decoration: underline var(--uchu-yin-2);
+ }
+ }
+</style>
+
+<div>
+ <slot></slot>
+</div>
+
+<aside>
+ <strong>Contact</strong>
+ <span>paul@webb.page</span>
+ <!-- <a href="https://netopwibby.socii.network" target="_blank">socii@netopwibby</a> -->
+ <a href="https://social.coop/@netopwibby" target="_blank">@netopwibby@social.coop</a>
+ <a href="https://blacksky.community/profile/webb.page" target="_blank">@webb.page</a>
+ <em>scroll vertically to scroll horizontally</em>
+ <img alt="" src="/88x31/a.gif"/>
+ <img alt="" src="/88x31/b.gif"/>
+ <img alt="" src="/88x31/c.gif"/>
+ <a class="banner-wrapper" href="https://www.webb.page">
+ <img alt="" src="/88x31/d.png"/>
+ </a>
+ <a class="banner-wrapper" href="https://ellesho.me/page/?ref=https://webb.page">
+ <img alt="" src="/88x31/elle.webp"/>
+ </a>
+</aside>