mock: バリアントのバッジをノードより後に描き、キーの下に隠れないようにする
バッジは NodeSvg の再帰の中で各バリアントグループの <g> に描いていたため、 後から描かれる兄弟のキーに隠れていた。選択の描画層の後に PhyBadgeLayer を置き、 位置は純粋関数 variantBadges でワールド座標に直して正立で描く。 フォーカス中、フォーカス外のバッジは薄く描き、クリックを受けない。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NznQtmVPoQAnietqwr1auL
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import type { Node } from "../../domain/phy";
|
||||
import type { Affine } from "../../domain/geometry";
|
||||
import { variantBadges } from "./logic";
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
nodes: Node[];
|
||||
variants: Record<string, string>;
|
||||
zoom: number;
|
||||
dim?: boolean;
|
||||
parent?: Affine;
|
||||
}>(),
|
||||
{ dim: false, parent: () => ({ a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 }) },
|
||||
);
|
||||
const emit = defineEmits<{ badge: [g: Node, e: MouseEvent] }>();
|
||||
// ノードより後に描き、隣のキーの下に隠れないようにする
|
||||
const badges = computed(() => variantBadges(props.nodes, props.variants, props.zoom, props.parent));
|
||||
/** バッジは名前を書かず、表示中のバリアント名はツールチップで示す。T-30。 */
|
||||
function badgeTitle(n: Extract<Node, { type: "variantGroup" }>) {
|
||||
const shown = props.variants[n.id] || n.default;
|
||||
const name = n.children.find((v) => v.id === shown)?.name ?? "";
|
||||
return `${n.name}: ${name}${shown === n.default ? "(既定)" : ""}`;
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<g class="badge-layer" :class="{ dim }">
|
||||
<g
|
||||
v-for="badge in badges"
|
||||
:key="badge.group.id"
|
||||
:data-badge-id="badge.group.id"
|
||||
class="badge"
|
||||
@click.stop="!dim && emit('badge', badge.group, $event)"
|
||||
><rect :x="badge.x" :y="badge.y" :width="badge.size" :height="badge.size" :rx="3 / zoom" /><text
|
||||
:x="badge.x + badge.size / 2"
|
||||
:y="badge.y + badge.size / 2"
|
||||
:style="{ fontSize: `${12 / zoom}px` }"
|
||||
>⇄</text
|
||||
><title>{{ badgeTitle(badge.group) }}</title></g
|
||||
>
|
||||
</g>
|
||||
</template>
|
||||
<style scoped>
|
||||
.badge {
|
||||
cursor: pointer;
|
||||
pointer-events: all;
|
||||
}
|
||||
.dim {
|
||||
opacity: 0.25;
|
||||
}
|
||||
.dim .badge {
|
||||
cursor: default;
|
||||
}
|
||||
.badge rect {
|
||||
fill: #fff3c2;
|
||||
stroke: #8a691b;
|
||||
stroke-width: 1px;
|
||||
vector-effect: non-scaling-stroke;
|
||||
}
|
||||
.badge text {
|
||||
fill: #302709;
|
||||
text-anchor: middle;
|
||||
dominant-baseline: central;
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user