2024-02-21 08:32:04 +01:00
|
|
|
import type {
|
|
|
|
KeySymbol,
|
|
|
|
Layout,
|
|
|
|
LayoutMeasurements,
|
|
|
|
VisualKey,
|
|
|
|
VisualLayout,
|
|
|
|
} from "./types";
|
2023-10-22 16:10:53 +02:00
|
|
|
import * as V from "./vec2";
|
|
|
|
|
2024-02-21 05:01:46 +01:00
|
|
|
export function visualKey(
|
|
|
|
position: V.Vec2,
|
|
|
|
size: V.Vec2 = [1, 1],
|
|
|
|
angle: number = 0,
|
|
|
|
): VisualKey {
|
|
|
|
return { position, size, angle };
|
2023-10-22 16:10:53 +02:00
|
|
|
}
|
|
|
|
|
2024-02-21 05:01:46 +01:00
|
|
|
function offsetMany(keys: VisualLayout, offsets: V.Vec2[]): VisualLayout {
|
|
|
|
return keys.map((key, index) => {
|
|
|
|
const offset = offsets[index] || [0, 0];
|
|
|
|
key.position = V.add(key.position, offset);
|
|
|
|
return key;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function col(at: V.Vec2): VisualLayout {
|
2023-10-22 16:10:53 +02:00
|
|
|
return [
|
2024-02-21 05:01:46 +01:00
|
|
|
visualKey(at),
|
|
|
|
visualKey(V.add(at, [0, 1])),
|
|
|
|
visualKey(V.add(at, [0, 2])),
|
2023-10-22 16:10:53 +02:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
function radians(deg: number): number {
|
|
|
|
return (deg / 180) * Math.PI;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function thumbs(
|
|
|
|
at: V.Vec2,
|
|
|
|
reverse: boolean,
|
|
|
|
thumbRotation = reverse ? -15 : 15,
|
|
|
|
): VisualLayout {
|
|
|
|
const offset: V.Vec2 = [
|
2024-02-21 05:01:46 +01:00
|
|
|
Math.cos(radians(thumbRotation)),
|
|
|
|
Math.sin(radians(thumbRotation)),
|
2023-10-22 16:10:53 +02:00
|
|
|
];
|
|
|
|
|
|
|
|
const result = [
|
2024-02-21 05:01:46 +01:00
|
|
|
visualKey(at, undefined, thumbRotation),
|
2023-10-22 16:10:53 +02:00
|
|
|
visualKey(
|
|
|
|
V.add(at, reverse ? V.neg(offset) : offset),
|
2024-02-21 05:01:46 +01:00
|
|
|
undefined,
|
2023-10-22 16:10:53 +02:00
|
|
|
thumbRotation,
|
|
|
|
),
|
|
|
|
];
|
|
|
|
|
|
|
|
if (reverse) result.reverse();
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function cols(
|
|
|
|
at: V.Vec2,
|
|
|
|
cols: V.Vec2[],
|
2024-02-21 05:01:46 +01:00
|
|
|
offsets: V.Vec2[] = [],
|
2023-10-22 16:10:53 +02:00
|
|
|
): VisualLayout {
|
|
|
|
return cols.flatMap((self, index) =>
|
2024-02-21 05:01:46 +01:00
|
|
|
offsetMany(col(V.add(at, V.add(self, [index, 0]))), offsets),
|
2023-10-22 16:10:53 +02:00
|
|
|
);
|
|
|
|
}
|
2024-02-21 05:01:46 +01:00
|
|
|
|
|
|
|
export function scaleVisual(visual: VisualKey, amount: number): VisualKey {
|
|
|
|
return {
|
|
|
|
angle: visual.angle,
|
|
|
|
position: V.scale(visual.position, amount),
|
|
|
|
size: V.scale(visual.size, amount),
|
|
|
|
};
|
|
|
|
}
|
2024-02-21 08:32:04 +01:00
|
|
|
|
|
|
|
export function scaleMeasurements(
|
|
|
|
measurements: LayoutMeasurements,
|
|
|
|
amount: number,
|
|
|
|
): LayoutMeasurements {
|
|
|
|
return {
|
|
|
|
keySize: measurements.keySize * amount,
|
|
|
|
keyPadding: measurements.keyPadding * amount,
|
|
|
|
keyCornerRadius: measurements.keyCornerRadius * amount,
|
|
|
|
keyStrokeWidth: measurements.keyStrokeWidth * amount,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export function findKeyByLabel(
|
|
|
|
layout: Layout,
|
|
|
|
label: KeySymbol,
|
|
|
|
): VisualKey | null {
|
|
|
|
for (let i = 0; i < layout.keys.length; i++) {
|
|
|
|
if (layout.keys[i].main === label) return layout.visual[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|