roundabout,
created on Saturday, 4 January 2025, 15:07:03 (1736003223),
received on Saturday, 4 January 2025, 15:07:12 (1736003232)
Author identity: vlad <vlad.muntoiu@gmail.com>
86b9b9ddf3075a0f97339b1196f4ffcc7e31ab3d
static/picture-annotation.py
@@ -16,6 +16,8 @@ next_button = document.getElementById("annotation-next")
save_button = document.getElementById("annotation-save")
object_list = document.getElementById("object-types")
object_list_content = document.getElementById("object-types-content")
object_list_filter = document.getElementById("filter-object-types")
confirm_button.style.display = "none"
cancel_button.style.display = "none"
@@ -207,6 +209,15 @@ def get_centre(shape):
return x, y
async def update_object_list_filter(event):
filter_text = event.currentTarget.value
for label in object_list_content.children:
if label.innerText.lower().find(filter_text.lower()) == -1:
label.style.display = "none"
else:
label.style.display = "flex"
async def focus_shape(shape):
global selected_shape
@@ -228,8 +239,7 @@ async def focus_shape(shape):
document.addEventListener("keydown", next_shape_key_proxy)
document.addEventListener("keydown", previous_shape_key_proxy)
object_list.innerHTML = ""
object_list_content.innerHTML = ""
new_radio = document.createElement("input")
new_radio.setAttribute("type", "radio")
new_radio.setAttribute("name", "object-type")
@@ -238,7 +248,7 @@ async def focus_shape(shape):
new_label = document.createElement("label")
new_label.appendChild(new_radio)
new_label.append("Undefined")
object_list.appendChild(new_label)
object_list_content.appendChild(new_label)
new_radio.addEventListener("change", change_object_type_proxy)
selected_object = selected_shape.getAttribute("data-object-type")
@@ -255,10 +265,12 @@ async def focus_shape(shape):
new_label = document.createElement("label")
new_label.appendChild(new_radio)
new_label.append(object)
object_list.appendChild(new_label)
object_list_content.appendChild(new_label)
new_radio.addEventListener("change", change_object_type_proxy)
object_list.style.display = "flex"
object_list_filter.focus()
object_list_filter.addEventListener("input", update_object_list_filter)
object_list.style.left = str(get_centre(shape)[0] / image.naturalWidth * 100) + "%"
object_list.style.top = str(get_centre(shape)[1] / image.naturalHeight * 100) + "%"
object_list.style.right = "auto"
@@ -342,7 +354,7 @@ def unselect_shape(event):
selected_shape.classList.remove("selected")
selected_shape = None
object_list.innerHTML = ""
object_list_content.innerHTML = ""
object_list.style.display = "none"
delete_button.style.display = "none"
next_button.style.display = "none"
@@ -359,7 +371,7 @@ def delete_shape(event):
# Shape is SVG shape inside SVG so we need to remove the parent SVG
selected_shape.parentNode.remove()
selected_shape = None
object_list.innerHTML = ""
object_list_content.innerHTML = ""
object_list.style.display = "none"
delete_button.style.display = "none"
next_button.style.display = "none"
@@ -388,7 +400,7 @@ follow_cursor_proxy = create_proxy(follow_cursor)
def switch_shape(event):
global shape_type
object_list.innerHTML = ""
object_list_content.innerHTML = ""
unselect_shape(None)
shape = event.currentTarget.id
shape_type = shape
templates/picture-annotation.html
@@ -58,7 +58,10 @@
</x-buttonbox>
</x-hbox>
<div id="annotation-zone">
<x-vbox id="object-types" style="--gap-box: 0.25rem; --padding-box: 1rem;"></x-vbox>
<x-vbox id="object-types" style="--gap-box: 0.25rem; --padding-box: 1rem;">
<input type="text" id="filter-object-types" placeholder="Search" aria-label="Search object types">
<x-vbox id="object-types-content"></x-vbox>
</x-vbox>
<img id="annotation-image" src="/raw/picture/{{ resource.id }}" alt="">
<div id="annotation-ruler-vertical" class="annotation-ruler"></div>
<div id="annotation-ruler-horizontal" class="annotation-ruler"></div>