Skip to content

Commit bfd9d1a

Browse files
committed
chore: stage 8a
1 parent e1dc2e3 commit bfd9d1a

56 files changed

Lines changed: 1494 additions & 508 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.oxlintrc.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@
44
"browser": true,
55
"es2023": true
66
},
7+
"plugins": [
8+
"import"
9+
],
710
"ignorePatterns": ["dist"]
811
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"build": "tsc && vite build",
99
"preview": "vite preview",
1010
"lint": "oxlint --deny-warnings .",
11+
"lint:fix": "oxlint --fix",
1112
"prepare": "lefthook install"
1213
},
1314
"devDependencies": {

src/App.tsx

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,53 @@
11
import { Route, HashRouter, useLocation } from '@solidjs/router';
22
import type { Component, ParentComponent } from 'solid-js';
3-
import { createSignal, createEffect } from 'solid-js';
3+
import { createSignal, createEffect, createMemo } from 'solid-js';
44
import { routes } from './routes';
55
import { Drawer } from './components/Drawer';
66
import { StageNavigation } from './components/StageNavigation';
7+
import { menuGroups, isMenuGroup } from './config/menu';
8+
import Welcome from './stages/Welcome';
9+
710

811
const Layout: ParentComponent = (props) => {
912
const location = useLocation();
1013
const [drawerOpen, setDrawerOpen] = createSignal(false);
1114

1215
createEffect(() => {
13-
location.pathname;
1416
setDrawerOpen(false);
1517
});
1618

19+
const getCurrentLevel = createMemo(() => {
20+
const currentPath = location.pathname;
21+
22+
for (const group of menuGroups) {
23+
console.log
24+
if (isMenuGroup(group)) {
25+
const foundLink = group.links.find(link => link.href === currentPath);
26+
if (foundLink) {
27+
return {
28+
title: group.title,
29+
label: foundLink.label,
30+
isLink: true
31+
};
32+
}
33+
} else {
34+
if (group.href === currentPath) {
35+
return {
36+
title: group.label,
37+
label: null,
38+
isLink: false
39+
};
40+
}
41+
}
42+
}
43+
44+
return null;
45+
});
46+
47+
const currentLevel = getCurrentLevel();
48+
49+
console.log('currentLevel', currentLevel)
50+
1751
return (
1852
<>
1953
<button
@@ -28,23 +62,33 @@ const Layout: ParentComponent = (props) => {
2862
</svg>
2963
</button>
3064

31-
{/* Основной контент с минимальной высотой 100vh */}
3265
<div class="min-h-screen bg-[#f8faff]">
3366
<div class="mx-auto w-full max-w-[1024px] px-4 py-6">
34-
{/* Отступ для кнопки меню на мобильных */}
3567
<div class="lg:hidden h-14" />
36-
37-
{/* Контент будет растягиваться */}
3868
<div class="min-h-[calc(100vh-3rem)] flex flex-col">
3969
<div class="flex-1">
70+
<h1 class="text-xl2 font-semibold text-[#1f2a44]">2.5D Render</h1>
71+
72+
{currentLevel && (
73+
<div class="mb-6 pb-3 border-b border-[#d8deea]">
74+
{currentLevel.isLink ? (
75+
<>
76+
<p class="text-sm text-[#6b7a8f] mb-1">{currentLevel.title}</p>
77+
<h2 class="text-xl font-semibold text-[#1f2a44]">{currentLevel.label}</h2>
78+
</>
79+
) : (
80+
<h2 class="text-xl font-semibold text-[#1f2a44]">{currentLevel.title}</h2>
81+
)}
82+
</div>
83+
)}
84+
4085
{props.children}
4186
</div>
4287
<StageNavigation />
4388
</div>
4489
</div>
4590
</div>
4691

47-
{/* Drawer компонент */}
4892
<Drawer isOpen={drawerOpen()} onClose={() => setDrawerOpen(false)} />
4993
</>
5094
);
@@ -53,6 +97,7 @@ const Layout: ParentComponent = (props) => {
5397
const App: Component = () => {
5498
return (
5599
<HashRouter root={Layout}>
100+
<Route path="/" component={() => <Welcome />} />
56101
{routes}
57102
<Route path="*" component={() => 'Not found'} />
58103
</HashRouter>

src/components/Canvas.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import {
55
createEffect,
66
} from "solid-js";
77

8-
9-
interface RendererProps {
8+
export interface RendererProps {
109
render: (ctx: CanvasRenderingContext2D, settings: Settings) => void;
1110
settings: Accessor<Settings>;
1211
width?: number;

src/components/Code.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ interface CodeBlockProps {
99
}
1010

1111
const CodeHighlight = (props: CodeBlockProps) => {
12-
let ref!: HTMLDivElement;
12+
let container: HTMLDivElement | null = null;
1313

1414
const [html] = createResource(async () => {
1515
return await codeToHtml(props.code, {
@@ -19,16 +19,16 @@ const CodeHighlight = (props: CodeBlockProps) => {
1919
});
2020

2121
onCleanup(() => {
22-
if (ref) ref.innerHTML = '';
22+
if (container) container.innerHTML = '';
2323
});
2424

2525
createEffect(() => {
26-
if (html() && ref) {
27-
ref.innerHTML = html()!;
26+
if (html() && container) {
27+
container.innerHTML = html()!;
2828
}
2929
});
3030

31-
return <div ref={ref} class={props.class} />;
31+
return <div ref={ref => { container = ref; }} class={props.class} />;
3232
};
3333

3434
export default function CodeBlock(props: CodeBlockProps) {

src/components/Drawer.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ export const DrawerContent: Component<{ onLinkClick?: () => void }> = (props) =>
4545
};
4646

4747
export const Drawer: Component<{ isOpen: boolean; onClose: () => void }> = (props) => {
48-
let drawerRef: HTMLDivElement | undefined;
49-
5048
createEffect(() => {
5149
if (props.isOpen) {
5250
document.body.style.overflow = 'hidden';
@@ -84,15 +82,13 @@ export const Drawer: Component<{ isOpen: boolean; onClose: () => void }> = (prop
8482
onClick={props.onClose}
8583
/>
8684

87-
{/* Drawer панель */}
8885
<aside
89-
ref={drawerRef}
9086
class={`absolute left-0 top-0 bottom-0 w-80 max-w-[85vw] transform bg-[#eef2fb] shadow-2xl transition-transform duration-300 ease-out ${
9187
props.isOpen ? 'translate-x-0' : '-translate-x-full'
9288
}`}
9389
>
9490
<div class="flex items-center justify-between border-b border-[#d8deea] px-4 py-4">
95-
<span class="text-lg font-bold text-[#1f2a44]">Naive 2.5 Render</span>
91+
<span class="text-lg font-bold text-[#1f2a44]">2.5D Renderer</span>
9692
<button
9793
aria-label="Закрыть меню"
9894
class="rounded p-1.5 text-[#1f2a44] transition-colors hover:bg-[#d8deea]"

src/components/Formula.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createEffect, onCleanup } from 'solid-js';
22
import katex from 'katex';
3-
import 'katex/dist/katex.min.css'; // Не забудьте импортировать стили!
3+
import 'katex/dist/katex.min.css';
44

55
interface FormulaProps {
66
latex: string;
@@ -10,7 +10,7 @@ interface FormulaProps {
1010
}
1111

1212
export const Formula = (props: FormulaProps) => {
13-
let containerRef!: HTMLDivElement;
13+
let containerRef: HTMLDivElement | null = null;
1414

1515
const renderFormula = () => {
1616
if (!containerRef) return;
@@ -39,5 +39,5 @@ export const Formula = (props: FormulaProps) => {
3939
}
4040
});
4141

42-
return <div ref={containerRef} class={props.class} />;
42+
return <div ref={ref => { containerRef = ref; }} class={props.class} />;
4343
};

src/components/Map2d/Canvas.tsx

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import {
2+
type Component,
3+
type Accessor,
4+
onMount,
5+
createEffect,
6+
} from "solid-js";
7+
8+
9+
type Render = (
10+
ctx: CanvasRenderingContext2D,
11+
settings: Settings,
12+
scale: number,
13+
offsetX: number,
14+
offsetY: number
15+
) => void;
16+
17+
export interface RendererProps {
18+
render: Render;
19+
settings: Accessor<Settings>;
20+
scale: Accessor<number>;
21+
offsetX: Accessor<number>;
22+
offsetY: Accessor<number>;
23+
width?: number;
24+
height?: number;
25+
class?: string;
26+
zoomFromCenter?: boolean;
27+
}
28+
29+
const Renderer: Component<RendererProps> = ({
30+
scale,
31+
width = 400,
32+
height = 320,
33+
render,
34+
settings,
35+
offsetX,
36+
offsetY,
37+
}) => {
38+
let refContainer: HTMLCanvasElement | undefined;
39+
40+
const tick = () => {
41+
const el = refContainer;
42+
if (!el) {
43+
return;
44+
}
45+
46+
const ctx = el.getContext("2d");
47+
if (!ctx) {
48+
return;
49+
}
50+
51+
ctx.save();
52+
ctx.clearRect(0, 0, el.width, el.height);
53+
ctx.translate(el.width / 2, el.height / 2);
54+
ctx.scale(scale(), scale());
55+
ctx.translate(-el.width / 2 + offsetX(), -el.height / 2 + offsetY());
56+
57+
render(
58+
ctx,
59+
settings(),
60+
scale(),
61+
offsetX(),
62+
offsetY(),
63+
);
64+
65+
ctx.restore();
66+
};
67+
68+
onMount(() => {
69+
tick();
70+
});
71+
72+
createEffect(() => {
73+
tick();
74+
});
75+
76+
return (
77+
<canvas
78+
ref={(canvas) => {
79+
refContainer = canvas;
80+
}}
81+
width={width}
82+
height={height}
83+
class="border border-gray-300"
84+
/>
85+
);
86+
};
87+
88+
export default Renderer;
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
interface KeyboardControlsProps {
1+
export interface KeyboardControlsProps {
22
withVertical?: boolean;
33
}
44

@@ -27,7 +27,7 @@ export default function KeyboardControls({ withVertical }: KeyboardControlsProps
2727

2828
return (
2929
<p class="font-normal text-gray-500 my-2 select-none">
30-
<span>Camera horizontal controls </span>
30+
<span>Перемещение камеры </span>
3131
<kbd
3232
class="p-1.5 py-1 text-sm font-semibold text-gray-800 bg-gray-100 border border-gray-400 rounded cursor-pointer hover:bg-gray-200 transition-colors select-none"
3333
onMouseDown={() => handleMouseDown('w')}
@@ -62,7 +62,7 @@ export default function KeyboardControls({ withVertical }: KeyboardControlsProps
6262
</kbd>{" "}
6363
{withVertical && (
6464
<>
65-
<span> and vertical </span>
65+
<span> и </span>
6666
<kbd
6767
class="p-1.5 py-1 text-sm font-semibold text-gray-800 bg-gray-100 border border-gray-400 rounded cursor-pointer hover:bg-gray-200 transition-colors select-none"
6868
onMouseDown={() => handleMouseDown('z')}
@@ -78,7 +78,7 @@ export default function KeyboardControls({ withVertical }: KeyboardControlsProps
7878
onContextMenu={(e) => e.preventDefault()}
7979
>
8080
X
81-
</kbd>{" "}
81+
</kbd>
8282
</>
8383
)}
8484
</p>

0 commit comments

Comments
 (0)