roundabout,
created on Monday, 19 August 2024, 08:43:40 (1724057020),
received on Monday, 19 August 2024, 08:43:57 (1724057037)
Author identity: vlad <vlad.muntoiu@gmail.com>
4d06b95659ab76a41c25254296ea4e7eeec63d8d
static/picture-annotation.py
@@ -0,0 +1,53 @@
from pyscript import document from pyodide.ffi import create_proxy # Remove the loading message document.getElementById("python-loading").remove() document.getElementById("shape-options").style.display = "flex" image = document.getElementById("annotation-image") zone = document.getElementById("annotation-zone") shape_type = "" def switch_shape(event): global shape_type shape = event.currentTarget.id shape_type = shape print("Shape is now of type:", shape) def open_shape(event): print("Creating a new shape of type:", shape_type) new_shape = document.createElementNS("http://www.w3.org/2000/svg", "svg") new_shape.setAttribute("width", image.width) new_shape.setAttribute("height", image.height) if shape_type == "shape-bbox": rectangle = document.createElementNS("http://www.w3.org/2000/svg", "rect") rectangle.setAttribute("x", "10") rectangle.setAttribute("y", "10") rectangle.setAttribute("width", "100") rectangle.setAttribute("height", "100") rectangle.setAttribute("fill", "hotPink") new_shape.appendChild(rectangle) zone.appendChild(new_shape) for button in list(document.getElementById("shape-selector").children): button.addEventListener( "click", create_proxy(switch_shape) ) print("Shape", button.id, "is available") zone.addEventListener( "click", create_proxy(open_shape) )
static/style.css
@@ -3,4 +3,25 @@
:root { --gap-navbar: 1rem; --width-navbar-button: 0; }} iconify-icon { display: inline-block; width: 1em; height: 1em; } :is(#shape-selector, #shape-options) > button > iconify-icon { font-size: 2rem; } #annotation-zone { position: relative; } #annotation-zone > svg { z-index: 1; position: absolute; top: 0; left: 0; }
templates/default.html
@@ -7,6 +7,7 @@
<link rel="stylesheet" href="/static/style.css"> <script src="/static/efficient-ui/dialogs.js"></script> <script src="/static/efficient-ui/toasts.js"></script> <script src="https://cdn.jsdelivr.net/npm/iconify-icon@2.1.0/dist/iconify-icon.min.js"></script></head> <body> <header>
templates/picture-annotation.html
@@ -1,9 +1,59 @@
{% extends "default.html" %} {% block title %}Picture | gigadata{% endblock %} {% block content %} <style> py-script { display: none; } /* Full PyScript style is too much, but we still need to hide the Python code */ </style> <script type="module" src="https://pyscript.net/releases/2024.8.2/core.js"></script><x-frame style="--width: 768px"> <h1>Annotating: {{ resource.title }}</h1> <img src="/raw/picture/{{ resource.id }}" alt="{{ resource.title }}"><p id="python-loading">Please wait for Python to load...</p> </x-frame> <x-frame is="main-area"> <x-buttonbox id="shape-selector"> <button class="button-flat" title="rectangle" id="shape-bbox"> <iconify-icon icon="mdi:square"></iconify-icon> </button> <button class="button-flat" title="oriented rectangle" id="shape-o-bbox"> <iconify-icon icon="mdi:rhombus"></iconify-icon> </button> <button class="button-flat" title="ellipse" id="shape-ellipse"> <iconify-icon icon="mdi:circle"></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="freehand closed" id="shape-freehand-polygon"> <iconify-icon icon="mdi:lasso"></iconify-icon> </button> <button class="button-flat" title="line" id="shape-line"> <iconify-icon icon="mdi:graph-line-variant"></iconify-icon> </button> <button class="button-flat" title="freehand open" id="shape-freehand-line"> <iconify-icon icon="mdi:gesture"></iconify-icon> </button> <button class="button-flat" title="point" id="shape-point"> <iconify-icon icon="mdi:circle"></iconify-icon> </button> <button class="button-flat" title="whole picture" id="shape-all"> <iconify-icon icon="mdi:image"></iconify-icon> </button> </x-buttonbox> <div id="annotation-zone"> <img id="annotation-image" src="/raw/picture/{{ resource.id }}" alt=""> </div> <x-buttonbox style="display: none;" id="shape-options"> <button class="button-flat" title="cancel" disabled> <iconify-icon icon="mdi:close"></iconify-icon> </button> <button class="button-flat" title="apply" disabled> <iconify-icon icon="mdi:check"></iconify-icon> </button> </x-buttonbox></x-frame> <script type="py" src="/static/picture-annotation.py"></script>{% endblock %}