roundabout,
created on Tuesday, 7 January 2025, 13:03:32 (1736255012),
received on Tuesday, 7 January 2025, 13:23:33 (1736256213)
Author identity: vlad <vlad.muntoiu@gmail.com>
e2664aa732ca99b9332b6b7481e3cce1e0c5d96b
static/efficient-ui
@@ -1 +1 @@
Subproject commit 30b18afca348bd1168ee40ef9d11b1fb8fd502b9Subproject commit e4a04ff48c746340fe1568e6b2b8efc2040f30c3
static/picture-annotation.py
@@ -1,3 +1,5 @@
import pyscript import jsfrom pyscript import document, fetch as pyfetch from pyscript.ffi import create_proxy import asyncio
@@ -14,6 +16,10 @@ delete_button = document.getElementById("annotation-delete")
previous_button = document.getElementById("annotation-previous") next_button = document.getElementById("annotation-next") save_button = document.getElementById("annotation-save") zoom_slider = document.getElementById("zoom-slider") zoom_in_button = document.getElementById("zoom-in") zoom_out_button = document.getElementById("zoom-out") zoom_indicator = document.getElementById("zoom-indicator")object_list = document.getElementById("object-types") object_list_content = document.getElementById("object-types-content")
@@ -692,6 +698,8 @@ scale = 1
translate_x = 0 translate_y = 0 scale_exponent = 0 def update_transform(): zone.style.transform = f"translate({translate_x}px, {translate_y}px) scale({scale}) " object_list.style.transform = f"scale({1/scale})" # neutralise the zoom
@@ -709,9 +717,8 @@ def update_transform():
shape.setAttribute("transform", f"scale({scale})") shape.setAttribute("transform-origin", "0 0") scale_exponent = 0zoom_indicator.innerText = f"{scale:.3f}x"zoom_offset = (0, 0)def compute_zoom_translation_around_point(element, x, y, sc, nsc): rect = element.getBoundingClientRect()
@@ -754,6 +761,7 @@ def on_wheel(event):
translate_y -= offset_y scale = new_scale zoom_slider.value = scale_exponentupdate_transform()
@@ -844,6 +852,7 @@ def on_touch_move(event):
last_touch_positions = current_positions last_touch_distance = current_distance zoom_slider.value = scale_exponent update_transform()
@@ -853,6 +862,25 @@ def on_touch_end(event):
last_touch_positions = None last_touch_distance = None def zoom_slider_change(event): global scale, scale_exponent scale_exponent = float(event.currentTarget.value) scale = 2 ** scale_exponent update_transform() def zoom_in(event): zoom_slider.stepUp() zoom_slider.dispatchEvent(js.Event.new("input")) def zoom_out(event): zoom_slider.stepDown() zoom_slider.dispatchEvent(js.Event.new("input")) zoom_container.addEventListener("wheel", on_wheel) zoom_container.addEventListener("mousedown", on_mouse_down) document.addEventListener("mousemove", on_mouse_move)
@@ -860,7 +888,11 @@ document.addEventListener("mouseup", on_mouse_up)
zone.addEventListener("touchstart", on_touch_start) zone.addEventListener("touchmove", on_touch_move) zone.addEventListener("touchend", on_touch_end) zoom_slider.addEventListener("input", zoom_slider_change) zoom_in_button.addEventListener("click", zoom_in) zoom_out_button.addEventListener("click", zoom_out)# Load existing annotations, if any put_shapes(await load_shapes()) update_transform()print("Ready!")
static/style.css
@@ -801,11 +801,11 @@ nav .button-flat .ripple-pad {
align-items: center; } #annotation-controls > x-buttonbox > button:has(iconify-icon) {#annotation-controls > x-buttonbox button:has(iconify-icon) {aspect-ratio: 1; } #annotation-controls > x-buttonbox > button > iconify-icon {#annotation-controls > x-buttonbox button > iconify-icon {font-size: 1.5rem; }
@@ -859,3 +859,15 @@ body.fixed-content-area > main {
display: flex; flex-direction: column; } #annotation-zoom-controls { display: flex; gap: 0.5rem; justify-content: center; align-items: center; } #zoom-indicator { width: 7ch; text-align: right; }
templates/picture-annotation.html
@@ -32,6 +32,16 @@
<button class="button-flat" title="point" id="shape-point"> <iconify-icon icon="mdi:crosshairs-gps"></iconify-icon> </button> <x-hbox id="annotation-zoom-controls"> <span id="zoom-indicator">1.000x</span> <button class="button-flat" title="zoom out" id="zoom-out"> <iconify-icon icon="mdi:magnify-minus"></iconify-icon> </button> <input type="range" id="zoom-slider" min="-4" max="6" step="0.25" value="0" aria-label="Zoom"> <button class="button-flat" title="zoom in" id="zoom-in"> <iconify-icon icon="mdi:magnify-plus"></iconify-icon> </button> </x-hbox></x-buttonbox> <x-buttonbox style="display: none;" id="shape-options"> <button class="button-flat" title="cancel" id="annotation-cancel">