diff --git a/.eslintrc.json b/.eslintrc.json index 8f5e1d1..3d2cbbe 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,10 +8,11 @@ "prettier", "eslint:recommended", "plugin:prettier/recommended", - "plugin:@typescript-eslint/recommended" + "plugin:@typescript-eslint/recommended", + "plugin:solid/typescript" ], - "overrides": [], - "plugins": ["prettier", "@typescript-eslint"], + "parser": "@typescript-eslint/parser", + "plugins": ["prettier", "@typescript-eslint", "solid"], "parserOptions": { "ecmaVersion": "latest", "project": "./tsconfig.json", @@ -22,13 +23,12 @@ "arrow-body-style": "off", "prefer-arrow-callback": "off", "import/no-cycle": "error", - "@typescript-eslint/non-nullable-type-assertion-style": "off", "sort-imports": [ "error", { "ignoreCase": false, "ignoreDeclarationSort": true, - "ignoreMemberSort": false, + "ignoreMemberSort": true, "memberSyntaxSortOrder": ["none", "all", "multiple", "single"], "allowSeparatedGroups": true } @@ -37,7 +37,15 @@ "import/order": [ "error", { - "groups": ["builtin", "external", "internal", "parent", "sibling", "index"], + "groups": [ + "builtin", + "external", + "internal", + "parent", + "sibling", + "index", + "unknown" + ], "newlines-between": "always", "alphabetize": { "order": "asc", diff --git a/assets/scss/_core/_base.scss b/assets/scss/_core/_base.scss index d8e8a82..eb48cd7 100644 --- a/assets/scss/_core/_base.scss +++ b/assets/scss/_core/_base.scss @@ -17,7 +17,3 @@ a, button { cursor: pointer; } - -.hide { - display: none; -} diff --git a/assets/ts/container.ts b/assets/ts/container.ts deleted file mode 100644 index 01b80c2..0000000 --- a/assets/ts/container.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Watchable } from './globalUtils' - -export const scrollable = new Watchable(true) - -export let container: Container - -/** - * interfaces - */ - -export interface Container extends HTMLDivElement { - dataset: { - next: string - close: string - prev: string - loading: string - } -} - -export function initContainer(): void { - container = document.getElementsByClassName('container').item(0) as Container - scrollable.addWatcher((o) => { - if (o) { - container.classList.remove('disableScroll') - } else { - container.classList.add('disableScroll') - } - }) -} diff --git a/assets/ts/desktop/customCursor.ts b/assets/ts/desktop/customCursor.ts deleted file mode 100644 index 283de88..0000000 --- a/assets/ts/desktop/customCursor.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { container } from '../container' - -import { active } from './state' - -/** - * variables - */ - -const cursor = document.createElement('div') -const cursorInner = document.createElement('div') - -/** - * main functions - */ - -function onMouse(e: MouseEvent): void { - const x = e.clientX - const y = e.clientY - cursor.style.transform = `translate3d(${x}px, ${y}px, 0)` -} - -export function setCustomCursor(text: string): void { - cursorInner.innerText = text -} - -/** - * init - */ -export function initCustomCursor(): void { - // cursor class name - cursor.className = 'cursor' - // cursor inner class name - cursorInner.className = 'cursorInner' - // append cursor inner to cursor - cursor.append(cursorInner) - // append cursor to main - container.append(cursor) - // bind mousemove event to window - window.addEventListener('mousemove', onMouse, { passive: true }) - // add active callback - active.addWatcher((o) => { - if (o) { - cursor.classList.add('active') - } else { - cursor.classList.remove('active') - } - }) -} diff --git a/assets/ts/desktop/customCursor.tsx b/assets/ts/desktop/customCursor.tsx new file mode 100644 index 0000000..d131beb --- /dev/null +++ b/assets/ts/desktop/customCursor.tsx @@ -0,0 +1,52 @@ +import { createSignal, onCleanup, onMount, type Accessor, type JSX } from 'solid-js' + +export function CustomCursor(props: { + children?: JSX.Element + active: Accessor + cursorText: Accessor + isOpen: Accessor +}): JSX.Element { + // types + interface XY { + x: number + y: number + } + + // variables + let controller: AbortController | undefined + + // states + const [xy, setXy] = createSignal({ x: 0, y: 0 }) + + // helper functions + const onMouse: (e: MouseEvent) => void = (e) => { + const { clientX, clientY } = e + setXy({ x: clientX, y: clientY }) + } + + // effects + onMount(() => { + controller = new AbortController() + const abortSignal = controller.signal + window.addEventListener('mousemove', onMouse, { + passive: true, + signal: abortSignal + }) + }) + + onCleanup(() => { + controller?.abort() + }) + + return ( + <> +
+
{props.cursorText()}
+
+ + ) +} diff --git a/assets/ts/desktop/init.ts b/assets/ts/desktop/init.ts deleted file mode 100644 index 1ee7a64..0000000 --- a/assets/ts/desktop/init.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { type ImageJSON } from '../resources' - -import { initCustomCursor } from './customCursor' -import { initStage } from './stage' -import { initStageNav } from './stageNav' - -/** - * main functions - */ - -export function initDesktop(ijs: ImageJSON[]): void { - initCustomCursor() - initStage(ijs) - initStageNav() -} diff --git a/assets/ts/desktop/layout.tsx b/assets/ts/desktop/layout.tsx new file mode 100644 index 0000000..f74a3b7 --- /dev/null +++ b/assets/ts/desktop/layout.tsx @@ -0,0 +1,89 @@ +// eslint-disable-next-line sort-imports +import { Show, createMemo, createSignal, type JSX } from 'solid-js' + +import type { ImageJSON } from '../resources' +import type { Vector } from '../utils' + +import { CustomCursor } from './customCursor' +import { Nav } from './nav' +import { Stage } from './stage' +import { StageNav } from './stageNav' + +/** + * interfaces and types + */ + +export interface DesktopImage extends HTMLImageElement { + dataset: { + hiUrl: string + hiImgH: string + hiImgW: string + loUrl: string + loImgH: string + loImgW: string + } +} + +export interface HistoryItem { + i: number + x: number + y: number +} + +/** + * components + */ + +export default function Desktop(props: { + children?: JSX.Element + ijs: ImageJSON[] + prevText: string + closeText: string + nextText: string + loadingText: string +}): JSX.Element { + const [cordHist, setCordHist] = createSignal([]) + const [isLoading, setIsLoading] = createSignal(false) + const [isOpen, setIsOpen] = createSignal(false) + const [isAnimating, setIsAnimating] = createSignal(false) + const [hoverText, setHoverText] = createSignal('') + const [navVector, setNavVector] = createSignal('none') + + const active = createMemo(() => isOpen() && !isAnimating()) + const cursorText = createMemo(() => (isLoading() ? props.loadingText : hoverText())) + + return ( + <> +