-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathvite-plugin-layout.ts
More file actions
124 lines (111 loc) · 3.02 KB
/
vite-plugin-layout.ts
File metadata and controls
124 lines (111 loc) · 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import type { Plugin, Rollup } from "vite";
import type { CompiledLayout } from "./src/lib/assets/layouts/layout.d.ts";
import yaml from "js-yaml";
export interface VisualLayout {
name: string;
col: VisualLayoutRow[];
}
interface Positionable {
offset: [number, number];
rotate: number;
}
export interface VisualLayoutRow extends Positionable {
row: Array<VisualLayoutKey | VisualLayoutSwitch>;
}
export interface VisualLayoutKey extends Positionable {
key: number;
size?: [number, number];
}
export interface VisualLayoutSwitch extends Positionable {
switch: {
n: number;
e: number;
w: number;
s: number;
d: number;
};
rotationAnchor?: true;
}
const fileRegex = /\.(layout\.yml)$/;
export function layoutPlugin() {
return {
name: "charachorder-layout",
transform(code, id) {
if (fileRegex.test(id)) {
return {
code: `const data = ${JSON.stringify(compileLayout(yaml.load(code) as VisualLayout))};\nexport default data;`,
map: null,
} satisfies Rollup.TransformResult;
}
return null;
},
} satisfies Plugin;
}
export function compileLayout(layout: VisualLayout): CompiledLayout {
const compiled: CompiledLayout = {
name: layout.name,
size: [0, 0],
keys: [],
fixedKeys: [],
};
let y = 0;
for (const { row, offset } of layout.col) {
let x = offset?.[0] ?? 0;
y += offset?.[1] ?? 0;
let maxHeight = 0;
for (const info of row) {
const [ox, oy] = info.offset || [0, 0];
const rotate = info.rotate || 0;
if ("key" in info) {
const [width, height] = info.size ?? [1, 1];
compiled.keys.push({
id: info.key,
shape: "square",
size: [width, height],
pos: [x + ox, y + oy],
cornerRadius: 0.1,
rotate,
});
x += width + ox;
maxHeight = Math.max(maxHeight, height + oy);
} else if ("switch" in info) {
const cx = x + ox + 1;
const cy = y + oy + 1;
if (info.rotationAnchor) {
compiled.rotationAnchor = [cx, cy];
}
for (const [i, id] of [
info.switch.s,
info.switch.w,
info.switch.n,
info.switch.e,
].entries()) {
(info.rotationAnchor ? compiled.fixedKeys : compiled.keys).push({
id,
shape: "quarter-circle",
cornerRadius: 0,
size: [2, 0.6],
pos: [cx, cy],
rotate: 90 * i + 45,
});
}
if (info.switch.d !== undefined) {
(info.rotationAnchor ? compiled.fixedKeys : compiled.keys).push({
id: info.switch.d,
shape: "square",
cornerRadius: 0.5,
size: [0.8, 0.8],
pos: [x + 0.6 + ox, y + 0.6 + oy],
rotate: 0,
});
}
x += 2 + ox;
maxHeight = Math.max(maxHeight, 2 + oy);
}
}
y += maxHeight;
compiled.size[0] = Math.max(compiled.size[0], x);
}
compiled.size[1] = y;
return compiled;
}