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>