roundabout,
created on Wednesday, 4 September 2024, 10:53:33 (1725447213),
received on Wednesday, 4 September 2024, 11:10:54 (1725448254)
Author identity: vlad <vlad.muntoiu@gmail.com>
66ae17b1d3b7491058aa977c410528a56b9d20a3
static/picture-annotation.py
@@ -221,6 +221,8 @@ def switch_shape(event):
cancel_bbox(None)
case "shape-polygon":
cancel_polygon(None)
case "shape-polyline":
cancel_polygon(None)
else:
# Remove event listeners for selection
for shape in document.getElementsByClassName("shape"):
@@ -392,30 +394,72 @@ def open_shape(event):
return
print("Creating a new shape of type:", shape_type)
if shape_type == "shape-bbox":
helper_message.innerText = ("Define the first point at the intersection of the lines "
"by clicking on the image, or click the cross to cancel")
cancel_button.addEventListener("click", cancel_bbox_proxy)
document.addEventListener("keydown", cancel_bbox_proxy)
cancel_button.style.display = "block"
bbox_pos = None
zone.addEventListener("click", make_bbox_proxy)
vertical_ruler.style.display = "block"
horizontal_ruler.style.display = "block"
zone.style.cursor = "crosshair"
elif shape_type == "shape-polygon" or shape_type == "shape-polyline":
match shape_type:
case "shape-polygon":
helper_message.innerText = ("Click on the image to define the points of the polygon, "
"press escape to cancel, enter to close, or backspace to "
"remove the last point")
case "shape-polyline":
helper_message.innerText = ("Click on the image to define the points of the polyline, "
"press escape to cancel, enter to finish, or backspace to "
"remove the last point")
match shape_type:
case "shape-bbox":
helper_message.innerText = ("Define the first point at the intersection of the lines "
"by clicking on the image, or click the cross to cancel")
cancel_button.addEventListener("click", cancel_bbox_proxy)
document.addEventListener("keydown", cancel_bbox_proxy)
cancel_button.style.display = "block"
bbox_pos = None
zone.addEventListener("click", make_bbox_proxy)
vertical_ruler.style.display = "block"
horizontal_ruler.style.display = "block"
zone.style.cursor = "crosshair"
case "shape-polygon" | "shape-polyline":
match shape_type:
case "shape-polygon":
helper_message.innerText = ("Click on the image to define the points of the polygon, "
"press escape to cancel, enter to close, or backspace to "
"remove the last point")
case "shape-polyline":
helper_message.innerText = ("Click on the image to define the points of the polyline, "
"press escape to cancel, enter to finish, or backspace to "
"remove the last point")
if not polygon_points and not new_shape:
new_shape = document.createElementNS("http://www.w3.org/2000/svg", "svg")
new_shape.setAttribute("width", "100%")
new_shape.setAttribute("height", "100%")
zone_rect = zone.getBoundingClientRect()
new_shape.setAttribute("viewBox", f"0 0 {image.naturalWidth} {image.naturalHeight}")
new_shape.classList.add("shape-container")
if not polygon_points and int(len(new_shape.children)) == 0:
zone.addEventListener("click", make_polygon_proxy)
document.addEventListener("keydown", close_polygon_proxy)
document.addEventListener("keydown", cancel_polygon_proxy)
document.addEventListener("keydown", backspace_polygon_proxy)
cancel_button.addEventListener("click", cancel_polygon_proxy)
cancel_button.style.display = "block"
confirm_button.addEventListener("click", close_polygon_proxy)
confirm_button.style.display = "block"
backspace_button.addEventListener("click", backspace_polygon_proxy)
backspace_button.style.display = "block"
match shape_type:
case "shape-polygon":
polygon = document.createElementNS("http://www.w3.org/2000/svg", "polygon")
polygon.classList.add("shape-polygon")
case "shape-polyline":
polygon = document.createElementNS("http://www.w3.org/2000/svg", "polyline")
polygon.classList.add("shape-polyline")
polygon.setAttribute("fill", "none")
polygon.setAttribute("data-object-type", "")
polygon.classList.add("shape")
new_shape.appendChild(polygon)
zone.appendChild(new_shape)
zone.style.cursor = "crosshair"
case "shape-point":
point = document.createElementNS("http://www.w3.org/2000/svg", "circle")
zone_rect = zone.getBoundingClientRect()
point.setAttribute("cx", str((event.clientX - zone_rect.left) / zone_rect.width * image.naturalWidth))
point.setAttribute("cy", str((event.clientY - zone_rect.top) / zone_rect.height * image.naturalHeight))
point.setAttribute("r", "0")
point.classList.add("shape-point")
point.classList.add("shape")
point.setAttribute("data-object-type", "")
if not polygon_points and not new_shape:
new_shape = document.createElementNS("http://www.w3.org/2000/svg", "svg")
new_shape.setAttribute("width", "100%")
new_shape.setAttribute("height", "100%")
@@ -423,30 +467,11 @@ def open_shape(event):
new_shape.setAttribute("viewBox", f"0 0 {image.naturalWidth} {image.naturalHeight}")
new_shape.classList.add("shape-container")
if not polygon_points and int(len(new_shape.children)) == 0:
zone.addEventListener("click", make_polygon_proxy)
document.addEventListener("keydown", close_polygon_proxy)
document.addEventListener("keydown", cancel_polygon_proxy)
document.addEventListener("keydown", backspace_polygon_proxy)
cancel_button.addEventListener("click", cancel_polygon_proxy)
cancel_button.style.display = "block"
confirm_button.addEventListener("click", close_polygon_proxy)
confirm_button.style.display = "block"
backspace_button.addEventListener("click", backspace_polygon_proxy)
backspace_button.style.display = "block"
match shape_type:
case "shape-polygon":
polygon = document.createElementNS("http://www.w3.org/2000/svg", "polygon")
polygon.classList.add("shape-polygon")
case "shape-polyline":
polygon = document.createElementNS("http://www.w3.org/2000/svg", "polyline")
polygon.classList.add("shape-polyline")
polygon.setAttribute("fill", "none")
polygon.setAttribute("data-object-type", "")
polygon.classList.add("shape")
new_shape.appendChild(polygon)
new_shape.appendChild(point)
zone.appendChild(new_shape)
zone.style.cursor = "crosshair"
new_shape = None
for button in list(document.getElementById("shape-selector").children):
static/style.css
@@ -24,6 +24,12 @@ iconify-icon {
#annotation-zone {
position: relative;
user-select: none;
}
#annotation-image {
user-drag: none;
-webkit-user-drag: none;
}
#annotation-zone > svg {
@@ -67,9 +73,21 @@ iconify-icon {
fill: none;
}
.shape-point {
stroke: var(--color-accent);
stroke-width: 32px;
r: 0.1;
}
.shape.selected {
fill-opacity: 0.2;
stroke-width: 4px;
filter: drop-shadow(0 0 2px var(--text-soft));
}
.shape-point.selected {
fill-opacity: 1;
r: 4px;
}
.shape-container {