roundabout,
created on Saturday, 4 January 2025, 14:50:36 (1736002236),
received on Saturday, 4 January 2025, 14:50:39 (1736002239)
Author identity: vlad <vlad.muntoiu@gmail.com>
ed037dea7615e96b44dec3193b24bef095cf7fe9
static/picture-annotation.py
@@ -221,9 +221,9 @@ async def focus_shape(shape):
objects = await get_all_objects()
delete_button.style.display = "block"
next_button.style.display = "block"
previous_button.style.display = "block"
delete_button.style.display = "flex"
next_button.style.display = "flex"
previous_button.style.display = "flex"
document.addEventListener("keydown", delete_shape_key_proxy)
document.addEventListener("keydown", next_shape_key_proxy)
document.addEventListener("keydown", previous_shape_key_proxy)
@@ -233,6 +233,7 @@ async def focus_shape(shape):
new_radio = document.createElement("input")
new_radio.setAttribute("type", "radio")
new_radio.setAttribute("name", "object-type")
new_radio.setAttribute("tabindex", "1") # Focus first
new_radio.setAttribute("value", "")
new_label = document.createElement("label")
new_label.appendChild(new_radio)
@@ -585,7 +586,7 @@ def open_shape(event):
cancel_button.addEventListener("click", cancel_bbox_proxy)
document.addEventListener("keydown", cancel_bbox_proxy)
cancel_button.style.display = "block"
cancel_button.style.display = "flex"
bbox_pos = None
zone.addEventListener("click", make_bbox_proxy)
vertical_ruler.style.display = "block"
@@ -611,11 +612,11 @@ def open_shape(event):
document.addEventListener("keydown", cancel_polygon_proxy)
document.addEventListener("keydown", backspace_polygon_proxy)
cancel_button.addEventListener("click", cancel_polygon_proxy)
cancel_button.style.display = "block"
cancel_button.style.display = "flex"
confirm_button.addEventListener("click", close_polygon_proxy)
confirm_button.style.display = "block"
confirm_button.style.display = "flex"
backspace_button.addEventListener("click", backspace_polygon_proxy)
backspace_button.style.display = "block"
backspace_button.style.display = "flex"
if shape_type == "shape-polygon":
polygon = document.createElementNS("http://www.w3.org/2000/svg", "polygon")
polygon.classList.add("shape-polygon")
static/style.css
@@ -63,10 +63,6 @@ iconify-icon {
font-size: 1.5em;
}
:is(#shape-selector, #shape-options) > button > iconify-icon {
font-size: 2rem;
}
#annotation-zone, .annotation-zone {
position: relative;
user-select: none;
@@ -780,7 +776,10 @@ nav .button-flat .ripple-pad {
#object-types {
z-index: 3;
background: var(--color-card);
background: var(--color-callout);
color: var(--color-callout-text);
--color-background-text: var(--color-callout-text);
--color-label-text: var(--color-callout-text);
box-shadow: var(--shadow-card);
padding: 1rem;
border-radius: var(--radius-card);
@@ -788,3 +787,28 @@ nav .button-flat .ripple-pad {
display: none;
overflow: auto;
}
#annotation-controls {
display: flex;
justify-content: space-between;
gap: 1rem;
padding: 0.5rem;
align-items: stretch;
}
#annotation-controls > x-buttonbox {
align-items: center;
}
#annotation-controls > x-buttonbox > button:has(iconify-icon) {
aspect-ratio: 1;
}
#annotation-controls > x-buttonbox > button > iconify-icon {
font-size: 1.5rem;
}
#annotation-helper-message {
padding: 1rem;
text-align: center;
}
templates/picture-annotation.html
@@ -13,27 +13,50 @@
</style>
<script type="module" src="https://pyscript.net/releases/2024.8.2/core.js"></script>
<x-frame style="--width: 768px">
<p id="annotation-helper-message">Please wait for Python to load...</p>
</x-frame>
<x-frame id="main-area">
<x-buttonbox id="shape-selector">
<button class="button-flat" title="selection" id="select">
<iconify-icon icon="mdi:cursor-default"></iconify-icon>
</button>
<button class="button-flat" title="rectangle" id="shape-bbox">
<iconify-icon icon="mdi:square"></iconify-icon>
</button>
<button class="button-flat" title="polygon" id="shape-polygon">
<iconify-icon icon="mdi:pentagon"></iconify-icon>
</button>
<button class="button-flat" title="polyline" id="shape-polyline">
<iconify-icon icon="mdi:graph-line-variant"></iconify-icon>
</button>
<button class="button-flat" title="point" id="shape-point">
<iconify-icon icon="mdi:crosshairs-gps"></iconify-icon>
</button>
</x-buttonbox>
<x-hbox id="annotation-controls">
<x-buttonbox id="shape-selector">
<button class="button-flat" title="selection" id="select">
<iconify-icon icon="mdi:cursor-default"></iconify-icon>
</button>
<button class="button-flat" title="rectangle" id="shape-bbox">
<iconify-icon icon="mdi:square"></iconify-icon>
</button>
<button class="button-flat" title="polygon" id="shape-polygon">
<iconify-icon icon="mdi:pentagon"></iconify-icon>
</button>
<button class="button-flat" title="polyline" id="shape-polyline">
<iconify-icon icon="mdi:graph-line-variant"></iconify-icon>
</button>
<button class="button-flat" title="point" id="shape-point">
<iconify-icon icon="mdi:crosshairs-gps"></iconify-icon>
</button>
</x-buttonbox>
<x-buttonbox style="display: none;" id="shape-options">
<button class="button-flat" title="cancel" id="annotation-cancel">
<iconify-icon icon="mdi:close"></iconify-icon>
</button>
<button class="button-flat" title="apply" id="annotation-confirm">
<iconify-icon icon="mdi:check"></iconify-icon>
</button>
<button class="button-flat" title="remove last point" id="annotation-backspace">
<iconify-icon icon="mdi:backspace"></iconify-icon>
</button>
<button class="button-flat" title="delete shape" id="annotation-delete">
<iconify-icon icon="mdi:delete"></iconify-icon>
</button>
<button class="button-flat" title="select previous shape" id="annotation-previous">
<iconify-icon icon="mdi:chevron-left"></iconify-icon>
</button>
<button class="button-flat" title="select next shape" id="annotation-next">
<iconify-icon icon="mdi:chevron-right"></iconify-icon>
</button>
<div class="flexible-space"></div>
<button id="annotation-save">
Save
</button>
</x-buttonbox>
</x-hbox>
<div id="annotation-zone">
<x-vbox id="object-types" style="--gap-box: 0.25rem; --padding-box: 1rem;"></x-vbox>
<img id="annotation-image" src="/raw/picture/{{ resource.id }}" alt="">
@@ -42,30 +65,7 @@
<div id="annotation-ruler-vertical-secondary" class="annotation-ruler"></div>
<div id="annotation-ruler-horizontal-secondary" class="annotation-ruler"></div>
</div>
<x-buttonbox style="display: none;" id="shape-options">
<button class="button-flat" title="cancel" id="annotation-cancel">
<iconify-icon icon="mdi:close"></iconify-icon>
</button>
<button class="button-flat" title="apply" id="annotation-confirm">
<iconify-icon icon="mdi:check"></iconify-icon>
</button>
<button class="button-flat" title="remove last point" id="annotation-backspace">
<iconify-icon icon="mdi:backspace"></iconify-icon>
</button>
<button class="button-flat" title="delete shape" id="annotation-delete">
<iconify-icon icon="mdi:delete"></iconify-icon>
</button>
<button class="button-flat" title="select previous shape" id="annotation-previous">
<iconify-icon icon="mdi:chevron-left"></iconify-icon>
</button>
<button class="button-flat" title="select next shape" id="annotation-next">
<iconify-icon icon="mdi:chevron-right"></iconify-icon>
</button>
<div class="flexible-space"></div>
<button id="annotation-save">
Save
</button>
</x-buttonbox>
<p id="annotation-helper-message">Please wait for Python to load...</p>
</x-frame>
<input type="hidden" id="resource-id" name="resource-id" value="{{ resource.id }}">
<script type="mpy" src="/static/picture-annotation.py"></script>