|
|
|
@@ -35,7 +35,10 @@
|
|
|
|
|
:class="{ 'fc-canvas__region--whole': !regionStyle }"
|
|
|
|
|
:style="regionStyle || {}"
|
|
|
|
|
>
|
|
|
|
|
<span class="fc-canvas__region-label">{{ regionLabel }}</span>
|
|
|
|
|
<span class="fc-canvas__region-label">
|
|
|
|
|
<span v-if="regionTag" class="fc-canvas__region-tag">{{ regionTag }}</span>
|
|
|
|
|
<span class="fc-canvas__region-origin">{{ regionOrigin }}</span>
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
@@ -48,10 +51,12 @@ import { usePanZoom } from '../../composables/usePanZoom.js'
|
|
|
|
|
const props = defineProps({
|
|
|
|
|
src: String,
|
|
|
|
|
alt: String,
|
|
|
|
|
// Hovered-suggestion grounding, or null when nothing is hovered:
|
|
|
|
|
// null → no overlay
|
|
|
|
|
// { g: {bbox,kind,detector} } → highlight that crop region
|
|
|
|
|
// { g: null } → whole-image frame (not localized)
|
|
|
|
|
// Hovered-suggestion state, or null when nothing is hovered:
|
|
|
|
|
// null → no overlay
|
|
|
|
|
// { g: {bbox,kind,detector}, tag } → highlight that crop, label with the tag
|
|
|
|
|
// { g: null, tag } → whole-image frame (not localized)
|
|
|
|
|
// `tag` is the hovered concept's name (primary label line); `g` is where the
|
|
|
|
|
// crop came from (secondary provenance line).
|
|
|
|
|
hover: { type: Object, default: null },
|
|
|
|
|
})
|
|
|
|
|
const emit = defineEmits(['close-request'])
|
|
|
|
@@ -86,7 +91,12 @@ const regionStyle = computed(() => {
|
|
|
|
|
width: `${rw * 100}%`, height: `${rh * 100}%`,
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
const regionLabel = computed(() => {
|
|
|
|
|
// The hovered tag/suggestion name — the PRIMARY label line (what you care about).
|
|
|
|
|
const regionTag = computed(() => props.hover?.tag || '')
|
|
|
|
|
// Where the winning crop came from (the region's detector_version, else kind) —
|
|
|
|
|
// shown small + dimmed beneath the tag as provenance, not the headline. "whole
|
|
|
|
|
// image" = null grounding (the global vector won, not a crop).
|
|
|
|
|
const regionOrigin = computed(() => {
|
|
|
|
|
const g = props.hover?.g
|
|
|
|
|
return g ? (g.detector || g.kind || 'region') : 'whole image'
|
|
|
|
|
})
|
|
|
|
@@ -176,15 +186,26 @@ function onCanvasClick(ev) {
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 0; left: 0;
|
|
|
|
|
transform: translateY(-100%);
|
|
|
|
|
font-size: 11px;
|
|
|
|
|
font-family: 'JetBrains Mono', monospace;
|
|
|
|
|
line-height: 1.4;
|
|
|
|
|
padding: 1px 6px;
|
|
|
|
|
display: flex; flex-direction: column;
|
|
|
|
|
line-height: 1.25;
|
|
|
|
|
padding: 2px 6px;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
background: rgb(var(--v-theme-accent));
|
|
|
|
|
color: rgb(var(--v-theme-on-surface));
|
|
|
|
|
border-radius: 3px 3px 0 0;
|
|
|
|
|
}
|
|
|
|
|
/* The hovered tag is the headline. */
|
|
|
|
|
.fc-canvas__region-tag {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
}
|
|
|
|
|
/* Crop origin is provenance, not the point — subordinate: smaller, dimmed, and
|
|
|
|
|
monospace (it's a detector token like booru:head, not prose). */
|
|
|
|
|
.fc-canvas__region-origin {
|
|
|
|
|
font-size: 10px;
|
|
|
|
|
font-family: 'JetBrains Mono', monospace;
|
|
|
|
|
color: rgb(var(--v-theme-on-surface), 0.72);
|
|
|
|
|
}
|
|
|
|
|
.fc-canvas__region--whole .fc-canvas__region-label {
|
|
|
|
|
background: rgb(var(--v-theme-on-surface-variant));
|
|
|
|
|
}
|
|
|
|
|