Skip to content

Commit fc3ea11

Browse files
committed
feat: new editor
1 parent 4630126 commit fc3ea11

21 files changed

+397
-479
lines changed

src/lib/Editor.svelte

Lines changed: 0 additions & 72 deletions
This file was deleted.

src/lib/MMSInterop.svelte.ts

Lines changed: 0 additions & 106 deletions
This file was deleted.

src/lib/MMSProject.svelte.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,14 @@ export class MMSProject {
8989

9090
return f;
9191
};
92+
93+
getFile = (path: string[]) => {
94+
return path.reduce<FileTreeLike | null>((fs: FileTreeLike | null, name: string) => {
95+
if (fs?.isDir) {
96+
return fs.children?.[name] ?? null;
97+
} else {
98+
return fs;
99+
}
100+
}, this.fs);
101+
};
92102
}

src/lib/assets/favicon.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 77 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,89 @@
11
<script lang="ts" module>
2-
export const SupportedPreviewKinds = ['WorldGen__Noise'];
2+
export const SupportedPreviewKinds = ['Noise'];
33
</script>
44

55
<script lang="ts">
6-
import type { LeafNode } from '../tree/types';
6+
import type { MmsSymbol } from '@minecraftmetascript/mms-wasm';
7+
78
import * as deepslate from 'deepslate';
9+
import { debounce } from 'es-toolkit';
10+
import type { Action } from 'svelte/action';
11+
12+
let { symbol }: { symbol: MmsSymbol } = $props();
13+
14+
const deepslatePreview: Action<HTMLCanvasElement, MmsSymbol> = (
15+
canvas: HTMLCanvasElement,
16+
s: MmsSymbol
17+
) => {
18+
let symbol = s;
19+
20+
const update = debounce(() => {
21+
const random = new deepslate.XoroshiroRandom([
22+
BigInt(Math.floor(performance.now())),
23+
BigInt(Math.floor(performance.timeOrigin))
24+
]);
825
9-
let { node }: { node: LeafNode } = $props();
10-
11-
const random = new deepslate.XoroshiroRandom([
12-
BigInt(Math.floor(performance.now())),
13-
BigInt(Math.floor(performance.timeOrigin))
14-
]);
15-
16-
$effect(() => {
17-
if (!canvas) {
18-
console.warn('No Canvas');
19-
return;
20-
}
21-
if (!node || !node.data) {
22-
console.warn('No Node or Data');
23-
return;
24-
}
25-
const ctx = canvas.getContext('2d');
26-
if (!ctx) {
27-
console.warn('No Canvas 2d Context');
28-
return;
29-
}
30-
const box = canvas.getBoundingClientRect();
31-
switch (node.data?.kind) {
32-
case 'WorldGen__Noise': {
33-
try {
34-
const normalNoise = new deepslate.NormalNoise(random, node.data.value);
35-
for (let pixelX = 0; pixelX < box.width; pixelX++) {
36-
for (let pixelY = 0; pixelY < box.height; pixelY++) {
37-
ctx.fillStyle = `hsl(${normalNoise.sample(pixelX, pixelY, 0) * 360}, 50%, 50%)`;
38-
ctx.fillRect(pixelX, pixelY, 1, 1);
26+
if (!canvas) {
27+
console.warn('No Canvas');
28+
return;
29+
}
30+
if (!symbol || !symbol.value) {
31+
console.warn('No Symbol or Value');
32+
return;
33+
}
34+
const ctx = canvas.getContext('2d');
35+
if (!ctx) {
36+
console.warn('No Canvas 2d Context');
37+
return;
38+
}
39+
// TypeScript
40+
const dpr = window.devicePixelRatio || 1;
41+
const rect = canvas.getBoundingClientRect();
42+
43+
// Set intrinsic size to match CSS size * DPR
44+
canvas.width = Math.floor(rect.width * dpr);
45+
canvas.height = Math.floor(rect.height * dpr);
46+
47+
// Scale the context so 1 unit = 1 CSS pixel
48+
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
49+
ctx.scale(3, 3);
50+
51+
switch (symbol.type) {
52+
case 'Noise': {
53+
requestAnimationFrame(() => {
54+
try {
55+
console.log(symbol.value);
56+
const normalNoise = new deepslate.NormalNoise(random, symbol.value as any);
57+
for (let pixelX = 0; pixelX < rect.width; pixelX += 1) {
58+
for (let pixelY = 0; pixelY < rect.height; pixelY += 1) {
59+
const val = normalNoise.sample(pixelX, pixelY, 0);
60+
const color = `hsl(0, ${val * 50 + 50}%, ${val * 20 + 40}%)`;
61+
ctx.fillStyle = color;
62+
ctx.fillRect(pixelX, pixelY, 1, 1);
63+
}
64+
}
65+
} catch (e) {
66+
console.warn(e);
3967
}
40-
}
41-
} catch (e) {
42-
console.warn(e);
68+
});
4369
}
4470
}
45-
}
46-
});
71+
}, 250);
4772
48-
let canvas = $state<HTMLCanvasElement | null>();
73+
update();
74+
75+
window.addEventListener('resize', update);
76+
77+
return {
78+
update(next: MmsSymbol) {
79+
symbol = next;
80+
update();
81+
},
82+
destroy() {
83+
window.removeEventListener('resize', update);
84+
}
85+
};
86+
};
4987
</script>
5088

51-
<canvas class="aspect-square h-full max-h-full w-full max-w-full" bind:this={canvas}></canvas>
89+
<canvas class="h-full w-full" use:deepslatePreview={symbol}></canvas>

0 commit comments

Comments
 (0)