Merge pull request 'ui/3d-fonts: replace troika with 3d rendered default font' (#5091) from ui/password-input-reveal into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/5091
This commit is contained in:
@@ -91,6 +91,8 @@ mkShell {
|
||||
pushd "$CLAN_CORE_PATH/pkgs/clan-app/ui"
|
||||
export NODE_PATH="$(pwd)/node_modules"
|
||||
export PATH="$NODE_PATH/.bin:$(pwd)/bin:$PATH"
|
||||
|
||||
rm -rf .fonts || true
|
||||
cp -r ${self'.packages.fonts} .fonts
|
||||
chmod -R +w .fonts
|
||||
mkdir -p api
|
||||
|
||||
@@ -151,10 +151,12 @@ export const ServiceRoute = (props: {
|
||||
color="primary"
|
||||
inverted
|
||||
>
|
||||
{props.id}
|
||||
{props.label}
|
||||
</Typography>
|
||||
<Icon icon="Code" size="0.75rem" inverted color="tertiary" />
|
||||
</div>
|
||||
<div class="flex w-full flex-row items-center gap-1">
|
||||
{/* Same subtitle as Machine */}
|
||||
{/* <div class="flex w-full flex-row items-center gap-1">
|
||||
<Icon icon="Code" size="0.75rem" inverted color="tertiary" />
|
||||
<Typography
|
||||
hierarchy="label"
|
||||
@@ -165,7 +167,7 @@ export const ServiceRoute = (props: {
|
||||
>
|
||||
{props.instance.resolved.usage_ref.name}
|
||||
</Typography>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
</A>
|
||||
);
|
||||
@@ -181,8 +183,8 @@ const Services = () => {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Object.entries(ctx.serviceInstancesQuery.data).map(
|
||||
([id, instance]) => {
|
||||
return Object.entries(ctx.serviceInstancesQuery.data)
|
||||
.map(([id, instance]) => {
|
||||
const moduleName = instance.module.name;
|
||||
|
||||
const label = moduleName == id ? moduleName : `${moduleName} (${id})`;
|
||||
@@ -191,8 +193,8 @@ const Services = () => {
|
||||
label,
|
||||
instance: instance,
|
||||
};
|
||||
},
|
||||
);
|
||||
})
|
||||
.sort((a, b) => a.label.localeCompare(b.label));
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -18,8 +18,8 @@ export const SectionServices = () => {
|
||||
return [];
|
||||
}
|
||||
|
||||
return (ctx.machinesQuery.data[machineName].instance_refs ?? []).map(
|
||||
(id) => {
|
||||
return (ctx.machinesQuery.data[machineName].instance_refs ?? [])
|
||||
.map((id) => {
|
||||
const instance = ctx.serviceInstancesQuery.data?.[id];
|
||||
if (!instance) {
|
||||
throw new Error(`Service instance ${id} not found`);
|
||||
@@ -31,8 +31,8 @@ export const SectionServices = () => {
|
||||
instance,
|
||||
label: module.name == id ? module.name : `${module.name} (${id})`,
|
||||
};
|
||||
},
|
||||
);
|
||||
})
|
||||
.sort((a, b) => a.label.localeCompare(b.label));
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -2,9 +2,9 @@ import * as THREE from "three";
|
||||
import { ObjectRegistry } from "./ObjectRegistry";
|
||||
import { Accessor, createEffect, createRoot, on } from "solid-js";
|
||||
import { renderLoop } from "./RenderLoop";
|
||||
// @ts-expect-error: No types for troika-three-text
|
||||
import { Text } from "troika-three-text";
|
||||
import ttf from "../../.fonts/ArchivoSemiCondensed-Medium.ttf";
|
||||
import { TextGeometry } from "three/examples/jsm/geometries/TextGeometry.js";
|
||||
import { FontLoader } from "three/examples/jsm/Addons";
|
||||
import jsonfont from "three/examples/fonts/helvetiker_regular.typeface.json";
|
||||
|
||||
// Constants
|
||||
const BASE_SIZE = 0.9;
|
||||
@@ -201,26 +201,49 @@ export class MachineRepr {
|
||||
private createLabel(id: string) {
|
||||
const group = new THREE.Group();
|
||||
// 0x162324
|
||||
const text = new Text();
|
||||
text.text = id;
|
||||
text.font = ttf;
|
||||
text.fontSize = 0.1;
|
||||
text.color = 0xffffff;
|
||||
text.anchorX = "center";
|
||||
text.anchorY = "middle";
|
||||
text.position.set(0, 0, 0.01);
|
||||
text.outlineWidth = 0.005;
|
||||
text.outlineColor = 0x162324;
|
||||
// const text = new Text();
|
||||
// text.text = id;
|
||||
// text.font = ttf;
|
||||
// text.fontSize = 0.1;
|
||||
// text.color = 0xffffff;
|
||||
// text.anchorX = "center";
|
||||
// text.anchorY = "middle";
|
||||
// text.position.set(0, 0, 0.01);
|
||||
// text.outlineWidth = 0.005;
|
||||
// text.outlineColor = 0x162324;
|
||||
// text.sync(() => {
|
||||
// renderLoop.requestRender();
|
||||
// });
|
||||
|
||||
// Re-render on text changes
|
||||
text.sync(() => {
|
||||
renderLoop.requestRender();
|
||||
const textMaterial = new THREE.MeshPhongMaterial({
|
||||
color: 0xffffff,
|
||||
});
|
||||
const textGeo = new TextGeometry(id, {
|
||||
font: new FontLoader().parse(jsonfont),
|
||||
size: 0.09,
|
||||
depth: 0.001,
|
||||
curveSegments: 12,
|
||||
bevelEnabled: false,
|
||||
});
|
||||
|
||||
const text = new THREE.Mesh(textGeo, textMaterial);
|
||||
textGeo.computeBoundingBox();
|
||||
|
||||
const bbox = textGeo.boundingBox;
|
||||
if (bbox) {
|
||||
const xMid = -0.5 * (bbox.max.x - bbox.min.x);
|
||||
// const yMid = -0.5 * (bbox.max.y - bbox.min.y);
|
||||
// const zMid = -0.5 * (bbox.max.z - bbox.min.z);
|
||||
|
||||
// Translate geometry so center is at origin / baseline aligned with y=0
|
||||
textGeo.translate(xMid, -0.035, 0);
|
||||
}
|
||||
|
||||
// --- Background (rounded rect) ---
|
||||
const padding = 0.04;
|
||||
// TODO: compute from text.bounds after sync
|
||||
const bgWidth = text.text.length * 0.07 + padding;
|
||||
const textWidth = bbox ? bbox.max.x - bbox.min.x : 1;
|
||||
const bgWidth = textWidth + 10 * padding;
|
||||
// const bgWidth = text.text.length * 0.07 + padding;
|
||||
const bgHeight = 0.1 + 2 * padding;
|
||||
const radius = 0.02;
|
||||
|
||||
@@ -230,8 +253,6 @@ export class MachineRepr {
|
||||
const bg = new THREE.Mesh(bgGeom, bgMat);
|
||||
bg.position.set(0, 0, -0.01);
|
||||
|
||||
// bg.position.set(0, 0, -0.01); // slightly behind text
|
||||
|
||||
// --- Arrow (triangle pointing down) ---
|
||||
const arrowShape = new THREE.Shape();
|
||||
arrowShape.moveTo(-0.05, 0);
|
||||
|
||||
Reference in New Issue
Block a user