roundabout,
created on Friday, 14 February 2025, 19:49:02 (1739562542),
received on Friday, 14 February 2025, 19:49:04 (1739562544)
Author identity: vlad <vlad.muntoiu@gmail.com>
77dfe671cfb18a5d8afb0c505ec7a5c7634382ec
static/picture-annotation.py
@@ -42,6 +42,8 @@ def make_shape_container():
shape = document.createElementNS("http://www.w3.org/2000/svg", "svg") shape.setAttribute("width", "100%") shape.setAttribute("height", "100%") shape.setAttribute("viewBox", "0 0 1 1") shape.setAttribute("preserveAspectRatio", "none")shape.classList.add("shape-container") return shape
@@ -79,10 +81,10 @@ def list_shapes():
if shape.tagName == "rect": shape_dict["type"] = "bbox" shape_dict["shape"] = { "x": float(shape.getAttribute("x")) / image.naturalWidth,"y": float(shape.getAttribute("y")) / image.naturalHeight,"w": float(shape.getAttribute("width")) / image.naturalWidth,"h": float(shape.getAttribute("height")) / image.naturalHeight"x": float(shape.getAttribute("x")[:-1]) / 100, "y": float(shape.getAttribute("y")[:-1]) / 100, "w": float(shape.getAttribute("width")[:-1]) / 100, "h": float(shape.getAttribute("height")[:-1]) / 100} elif shape.tagName == "polygon" or shape.tagName == "polyline": if shape.tagName == "polygon":
@@ -96,16 +98,16 @@ def list_shapes():
x, y = point.split(",") x, y = float(x), float(y) json_points.append({ "x": x / image.naturalWidth,"y": y / image.naturalHeight"x": x, "y": y}) shape_dict["shape"] = json_points elif shape.tagName == "circle" and shape.classList.contains("shape-point"): shape_dict["type"] = "point" shape_dict["shape"] = { "x": float(shape.getAttribute("cx")) / image.naturalWidth,"y": float(shape.getAttribute("cy")) / image.naturalHeight"x": float(shape.getAttribute("cx")), "y": float(shape.getAttribute("cy"))} else: continue
@@ -123,10 +125,10 @@ def put_shapes(json_shapes):
if shape["type"] == "bbox": rectangle = document.createElementNS("http://www.w3.org/2000/svg", "rect") rectangle.setAttribute("x", str(shape["shape"]["x"] * image.naturalWidth))rectangle.setAttribute("y", str(shape["shape"]["y"] * image.naturalHeight))rectangle.setAttribute("width", str(shape["shape"]["w"] * image.naturalWidth))rectangle.setAttribute("height", str(shape["shape"]["h"] * image.naturalHeight))rectangle.setAttribute("x", str(shape["shape"]["x"])) rectangle.setAttribute("y", str(shape["shape"]["y"])) rectangle.setAttribute("width", str(shape["shape"]["w"])) rectangle.setAttribute("height", str(shape["shape"]["h"]))rectangle.setAttribute("fill", "none") rectangle.setAttribute("data-object-type", shape["object"] or "") rectangle.classList.add("shape-bbox")
@@ -135,7 +137,7 @@ def put_shapes(json_shapes):
elif shape["type"] == "polygon" or shape["type"] == "polyline": polygon = document.createElementNS("http://www.w3.org/2000/svg", shape["type"]) points = " ".join( [f"{point['x'] * image.naturalWidth},{point['y'] * image.naturalHeight}" for point in shape["shape"]])[f"{point['x']},{point['y']}" for point in shape["shape"]])polygon.setAttribute("points", points) polygon.setAttribute("fill", "none") polygon.setAttribute("data-object-type", shape["object"] or "")
@@ -144,8 +146,8 @@ def put_shapes(json_shapes):
new_shape.appendChild(polygon) elif shape["type"] == "point": point = document.createElementNS("http://www.w3.org/2000/svg", "circle") point.setAttribute("cx", str(shape["shape"]["x"] * image.naturalWidth))point.setAttribute("cy", str(shape["shape"]["y"] * image.naturalHeight))point.setAttribute("cx", str(shape["shape"]["x"])) point.setAttribute("cy", str(shape["shape"]["y"]))point.setAttribute("r", "0") point.classList.add("shape-point") point.classList.add("shape")
@@ -278,24 +280,24 @@ async def focus_shape(shape):
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.left = str(get_centre(shape)[0] * 100) + "%" object_list.style.top = str(get_centre(shape)[1] * 100) + "%"object_list.style.right = "auto" object_list.style.bottom = "auto" object_list.style.maxHeight = str(image.height - get_centre(shape)[1] / image.naturalHeight * image.height) + "px"object_list.style.maxWidth = str(image.width - get_centre(shape)[0] / image.naturalWidth * image.width) + "px"object_list.style.maxHeight = str(image.height * (1 - get_centre(shape)[1])) + "px" object_list.style.maxWidth = str(image.width * (1 - get_centre(shape)[0])) + "px"transform_origin = ["top", "left"] if get_centre(shape)[0] / image.naturalWidth * image.width + object_list.offsetWidth > image.width:if get_centre(shape)[0] * image.width + object_list.offsetWidth > image.width:object_list.style.left = "auto" object_list.style.right = str((image.naturalWidth - get_centre(shape)[0]) / image.naturalWidth * 100) + "%"object_list.style.maxWidth = str(get_centre(shape)[0] / image.naturalWidth * image.width) + "px"object_list.style.right = str((image.width - get_centre(shape)[0]) * 100) + "%" object_list.style.maxWidth = str(get_centre(shape)[0] * image.width) + "px"transform_origin[1] = "right" if get_centre(shape)[1] / image.naturalHeight * image.height + object_list.offsetHeight > image.height:if get_centre(shape)[1] / image.height * image.height + object_list.offsetHeight > image.height:object_list.style.top = "auto" object_list.style.bottom = str((image.naturalHeight - get_centre(shape)[1]) / image.naturalHeight * 100) + "%"object_list.style.maxHeight = str(get_centre(shape)[1] / image.naturalHeight * image.height) + "px"object_list.style.bottom = str((image.height - get_centre(shape)[1]) * 100) + "%" object_list.style.maxHeight = str(get_centre(shape)[1] * image.height) + "px"transform_origin[0] = "bottom" object_list.style.transformOrigin = " ".join(transform_origin)
@@ -527,10 +529,10 @@ def make_bbox(event):
maxx = max(x0, x1) maxy = max(y0, y1) rectangle.setAttribute("x", str(minx * image.naturalWidth))rectangle.setAttribute("y", str(miny * image.naturalHeight))rectangle.setAttribute("width", str((maxx - minx) * image.naturalWidth))rectangle.setAttribute("height", str((maxy - miny) * image.naturalHeight))rectangle.setAttribute("x", str(minx)) rectangle.setAttribute("y", str(miny)) rectangle.setAttribute("width", str(maxx - minx)) rectangle.setAttribute("height", str(maxy - miny))rectangle.setAttribute("fill", "none") rectangle.setAttribute("data-object-type", "") rectangle.classList.add("shape-bbox")
@@ -557,7 +559,7 @@ def make_polygon(event):
# Update the polygon polygon.setAttribute("points", " ".join( [f"{point[0] * image.naturalWidth},{point[1] * image.naturalHeight}" for point in[f"{point[0]},{point[1]}" for point inpolygon_points]))
@@ -605,7 +607,7 @@ def backspace_polygon(event):
polygon_points.pop() polygon = new_shape.children[0] polygon.setAttribute("points", " ".join( [f"{point[0] * image.naturalWidth},{point[1] * image.naturalHeight}" for point in[f"{point[0] * 100}%,{point[1] * 100}%" for point inpolygon_points]))
@@ -672,8 +674,8 @@ def open_shape(event):
elif shape_type == "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("cx", str((event.clientX - zone_rect.left) / zone_rect.width)) point.setAttribute("cy", str((event.clientY - zone_rect.top) / zone_rect.height))point.setAttribute("r", "0") point.classList.add("shape-point") point.classList.add("shape")
@@ -721,9 +723,6 @@ def update_transform():
svg.style.transformOrigin = "0 0" svg.setAttribute("width", f"{100 * scale}%") svg.setAttribute("height", f"{100 * scale}%") for shape in svg.children:shape.setAttribute("transform", f"scale({scale})")shape.setAttribute("transform-origin", "0 0")zoom_indicator.innerText = f"{scale:.3f}x"
static/style.css
@@ -140,7 +140,8 @@ iconify-icon {
stroke-width: 2px; --shape-radius: 2px; fill-opacity: 1; r: 2;r: 0.001; vector-effect: non-scaling-stroke non-scaling-size;transition: r 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), stroke-width 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), filter 0.25s cubic-bezier(0.61, 1, 0.88, 1);
@@ -155,8 +156,8 @@ iconify-icon {
.shape-point.selected { fill-opacity: 1; r: 6;--shape-radius: 6px;r: 0.001; --shape-radius: 0.001;stroke-width: 6px; }
templates/gallery.html
@@ -1,10 +1,10 @@
{% extends "default.html" %} {% import "small-annotation-display.html" as annotation_display %}{% block nav_title %}{{ gallery.title }}{% endblock %} {% block title %}Gallery {{ gallery.title }} | {{ site_name }}{% endblock %} {% block content %} <div id="picture-view"> <x-frame id="picture-actions"> <ul class="action-list">
@@ -51,33 +51,7 @@
{% for picture in gallery.pictures %} <li> <a href="/picture/{{ picture.resource.id }}"> <div class="annotation-zone"><img src="/raw/picture/{{ picture.resource.id }}" alt="{{ picture.resource.title }}">{% for region in picture.resource.regions %}{% if region.json.type == "bbox" %}<svg class="shape-container" viewBox="0 0 {{ picture.resource.width }} {{ picture.resource.height }}"><rect x="{{ region.json.shape.x * picture.resource.width }}"y="{{ region.json.shape.y * picture.resource.height }}"width="{{ region.json.shape.w * picture.resource.width }}"height="{{ region.json.shape.h * picture.resource.height }}"fill="none" class="shape-bbox shape"></rect></svg>{% elif region.json.type == "polygon" %}<svg class="shape-container" viewBox="0 0 {{ picture.resource.width }} {{ picture.resource.height }}"><polygon points="{% for point in region.json.shape %}{{ point.x * picture.resource.width }},{{ point.y * picture.resource.height }} {% endfor %}" fill="none" class="shape-polygon shape"></polygon></svg>{% elif region.json.type == "polyline" %}<svg class="shape-container" viewBox="0 0 {{ picture.resource.width }} {{ picture.resource.height }}"><polyline points="{% for point in region.json.shape %}{{ point.x * picture.resource.width }},{{ point.y * picture.resource.height }} {% endfor %}" fill="none" class="shape-polyline shape"></polyline></svg>{% elif region.json.type == "point" %}<svg class="shape-container" viewBox="0 0 {{ picture.resource.width }} {{ picture.resource.height }}"><circle cx="{{ region.json.shape.x * picture.resource.width }}" cy="{{ region.json.shape.y * picture.resource.height }}" r="0" fill="none" class="shape-point shape"></circle></svg>{% endif %}{% endfor %}</div>{{ annotation_display.annotation_display(picture.resource) }}<div class="list-detail"> {{ picture.resource.title }} </div>
templates/graphical-query-pictures-results.html
@@ -1,4 +1,5 @@
{% extends "default.html" %} {% import "small-annotation-display.html" as annotation_display %}{% block nav_title %}Query results{% endblock %} {% block title %}Picture query results | {{ site_name }}{% endblock %}
@@ -17,33 +18,7 @@
{% for resource in resources %} <li> <a href="/picture/{{ resource.id }}"> <div class="annotation-zone"><img src="/raw/picture/{{ resource.id }}" alt="{{ resource.title }}">{% for region in resource.regions %}{% if region.json.type == "bbox" %}<svg class="shape-container" viewBox="0 0 {{ resource.width }} {{ resource.height }}"><rect x="{{ region.json.shape.x * resource.width }}"y="{{ region.json.shape.y * resource.height }}"width="{{ region.json.shape.w * resource.width }}"height="{{ region.json.shape.h * resource.height }}"fill="none" class="shape-bbox shape"></rect></svg>{% elif region.json.type == "polygon" %}<svg class="shape-container" viewBox="0 0 {{ resource.width }} {{ resource.height }}"><polygon points="{% for point in region.json.shape %}{{ point.x * resource.width }},{{ point.y * resource.height }} {% endfor %}" fill="none" class="shape-polygon shape"></polygon></svg>{% elif region.json.type == "polyline" %}<svg class="shape-container" viewBox="0 0 {{ resource.width }} {{ resource.height }}"><polyline points="{% for point in region.json.shape %}{{ point.x * resource.width }},{{ point.y * resource.height }} {% endfor %}" fill="none" class="shape-polyline shape"></polyline></svg>{% elif region.json.type == "point" %}<svg class="shape-container" viewBox="0 0 {{ resource.width }} {{ resource.height }}"><circle cx="{{ region.json.shape.x * resource.width }}" cy="{{ region.json.shape.y * resource.height }}" r="0" fill="none" class="shape-point shape"></circle></svg>{% endif %}{% endfor %}</div>{{ annotation_display.annotation_display(resource) }}<div class="list-detail"> {{ resource.title }} </div>
templates/home.html
@@ -1,4 +1,5 @@
{% extends "default.html" %} {% import "small-annotation-display.html" as annotation_display %}{% block nav_title %}Home{% endblock %} {% block title %}Home | {{ site_name }}{% endblock %}
@@ -19,33 +20,7 @@
{% for resource in resources %} <li> <a href="/picture/{{ resource.id }}"> <div class="annotation-zone"><img src="/raw/picture/{{ resource.id }}" alt="{{ resource.title }}">{% for region in resource.regions %}{% if region.json.type == "bbox" %}<svg class="shape-container" viewBox="0 0 {{ resource.width }} {{ resource.height }}"><rect x="{{ region.json.shape.x * resource.width }}"y="{{ region.json.shape.y * resource.height }}"width="{{ region.json.shape.w * resource.width }}"height="{{ region.json.shape.h * resource.height }}"fill="none" class="shape-bbox shape"></rect></svg>{% elif region.json.type == "polygon" %}<svg class="shape-container" viewBox="0 0 {{ resource.width }} {{ resource.height }}"><polygon points="{% for point in region.json.shape %}{{ point.x * resource.width }},{{ point.y * resource.height }} {% endfor %}" fill="none" class="shape-polygon shape"></polygon></svg>{% elif region.json.type == "polyline" %}<svg class="shape-container" viewBox="0 0 {{ resource.width }} {{ resource.height }}"><polyline points="{% for point in region.json.shape %}{{ point.x * resource.width }},{{ point.y * resource.height }} {% endfor %}" fill="none" class="shape-polyline shape"></polyline></svg>{% elif region.json.type == "point" %}<svg class="shape-container" viewBox="0 0 {{ resource.width }} {{ resource.height }}"><circle cx="{{ region.json.shape.x * resource.width }}" cy="{{ region.json.shape.y * resource.height }}" r="0" fill="none" class="shape-point shape"></circle></svg>{% endif %}{% endfor %}</div>{{ annotation_display.annotation_display(resource) }}<div class="list-detail"> {{ resource.title }} </div>
templates/object.html
@@ -1,4 +1,5 @@
{% extends "default.html" %} {% import "small-annotation-display.html" as annotation_display %}{% block nav_title %}{{ object.id }}{% endblock %} {% block title %}Object {{ object.id }} | {{ site_name }}{% endblock %}
@@ -34,33 +35,7 @@
{% for resource in resources %} <li> <a href="/picture/{{ resource.id }}"> <div class="annotation-zone"><img src="/raw/picture/{{ resource.id }}" alt="{{ resource.title }}">{% for i in PictureRegion.query.filter_by(resource=resource, object=object) %}{% if i.json.type == "bbox" %}<svg class="shape-container" viewBox="0 0 {{ resource.width }} {{ resource.height }}"><rect x="{{ i.json.shape.x * resource.width }}"y="{{ i.json.shape.y * resource.height }}"width="{{ i.json.shape.w * resource.width }}"height="{{ i.json.shape.h * resource.height }}"fill="none" class="shape-bbox shape"></rect></svg>{% elif i.json.type == "polygon" %}<svg class="shape-container" viewBox="0 0 {{ resource.width }} {{ resource.height }}"><polygon points="{% for point in i.json.shape %}{{ point.x * resource.width }},{{ point.y * resource.height }} {% endfor %}" fill="none" class="shape-polygon shape"></polygon></svg>{% elif i.json.type == "polyline" %}<svg class="shape-container" viewBox="0 0 {{ resource.width }} {{ resource.height }}"><polyline points="{% for point in i.json.shape %}{{ point.x * resource.width }},{{ point.y * resource.height }} {% endfor %}" fill="none" class="shape-polyline shape"></polyline></svg>{% elif i.json.type == "point" %}<svg class="shape-container" viewBox="0 0 {{ resource.width }} {{ resource.height }}"><circle cx="{{ i.json.shape.x * resource.width }}" cy="{{ i.json.shape.y * resource.height }}" r="0" fill="none" class="shape-point shape"></circle></svg>{% endif %}{% endfor %}</div>{{ annotation_display.annotation_display(resource) }}<div class="list-detail"> {{ resource.title }} </div>
templates/picture.html
@@ -1,4 +1,5 @@
{% extends "default.html" %} {% import "small-annotation-display.html" as annotation_display %}{% block nav_title %}{{ resource.title }}{% endblock %} {% block title %}Picture {{ resource.title }} | {{ site_name }}{% endblock %}
@@ -87,19 +88,19 @@
<img id="annotation-image" src="/raw/picture/{{ resource.id }}" alt="{{ resource.title }}"> {% for region in resource.regions %} {% if region.json.type == "bbox" %} <svg class="shape-container-viewonly" viewBox="0 0 {{ size[0] }} {{ size[1] }}"><rect x="{{ region.json.shape.x * size[0] }}"y="{{ region.json.shape.y * size[1] }}"width="{{ region.json.shape.w * size[0] }}"height="{{ region.json.shape.h * size[1] }}"<svg class="shape-container-viewonly" viewBox="0 0 1 1" preserveAspectRatio="none"> <rect x="{{ region.json.shape.x }}" y="{{ region.json.shape.y }}" width="{{ region.json.shape.w }}" height="{{ region.json.shape.h }}"fill="none" class="shape-bbox shape" ></rect> {% set centre_x = region.json.shape.x + region.json.shape.w / 2 %} {% set centre_y = region.json.shape.y + region.json.shape.h / 2 %} </svg> {% elif region.json.type == "polygon" %} <svg class="shape-container-viewonly" viewBox="0 0 {{ size[0] }} {{ size[1] }}"><polygon points="{% for point in region.json.shape %}{{ point.x * size[0] }},{{ point.y * size[1] }} {% endfor %}" fill="none" class="shape-polygon shape"></polygon><svg class="shape-container-viewonly" viewBox="0 0 1 1" preserveAspectRatio="none"> <polygon points="{% for point in region.json.shape %}{{ point.x }},{{ point.y }} {% endfor %}" fill="none" class="shape-polygon shape"></polygon>{% set top = region.json.shape | sort(attribute='y') | last %} {% set left = region.json.shape | sort(attribute='x') | first %} {% set bottom = region.json.shape | sort(attribute='y') | first %}
@@ -108,15 +109,17 @@
{% set centre_y = (top.y + bottom.y) / 2 %} </svg> {% elif region.json.type == "polyline" %} <svg class="shape-container-viewonly" viewBox="0 0 {{ size[0] }} {{ size[1] }}"><polyline points="{% for point in region.json.shape %}{{ point.x * size[0] }},{{ point.y * size[1] }} {% endfor %}" fill="none" class="shape-polyline shape"></polyline><svg class="shape-container-viewonly" viewBox="0 0 1 1" preserveAspectRatio="none"> <polyline points="{% for point in region.json.shape %}{{ point.x }},{{ point.y }} {% endfor %}" fill="none" class="shape-polyline shape"></polyline>{# Median point #} {% set centre_x = region.json.shape | map(attribute="x") | median %} {% set centre_y = region.json.shape | map(attribute="y") | median %} </svg> {% elif region.json.type == "point" %} <svg class="shape-container-viewonly" viewBox="0 0 {{ size[0] }} {{ size[1] }}"><circle cx="{{ region.json.shape.x * size[0] }}" cy="{{ region.json.shape.y * size[1] }}" r="0" fill="none" class="shape-point shape"></circle><svg class="shape-container-viewonly" viewBox="0 0 1 1" preserveAspectRatio="none"> <circle cx="{{ region.json.shape.x }}" cy="{{ region.json.shape.y }}" r="0" fill="none" class="shape-point shape"></circle> {% set centre_x = region.json.shape.x %} {% set centre_y = region.json.shape.y %}</svg> {% endif %} {{ shape_label(centre_x, centre_y, region.object_id) }}
@@ -261,34 +264,7 @@
{% for copy in resource.copies %} <li> <a href="/picture/{{ copy.id }}"> <div class="annotation-zone"><img src="/raw/picture/{{ copy.id }}" alt="{{ copy.title }}">{% for region in copy.regions %}{% if region.json.type == "bbox" %}<svg class="shape-container" viewBox="0 0 {{ copy.width }} {{ copy.height }}"><rect x="{{ region.json.shape.x * copy.width }}"y="{{ region.json.shape.y * copy.height }}"width="{{ region.json.shape.w * copy.width }}"height="{{ region.json.shape.h * copy.height }}"fill="none" class="shape-bbox shape"></rect></svg>{% elif region.json.type == "polygon" %}<svg class="shape-container" viewBox="0 0 {{ copy.width }} {{ copy.height }}"><polygon points="{% for point in region.json.shape %}{{ point.x * copy.width }},{{ point.y * copy.height }} {% endfor %}" fill="none" class="shape-polygon shape"></polygon></svg>{% elif region.json.type == "polyline" %}<svg class="shape-container" viewBox="0 0 {{ copy.width }} {{ copy.height }}"><polyline points="{% for point in region.json.shape %}{{ point.x * copy.width }},{{ point.y * copy.height }} {% endfor %}" fill="none" class="shape-polyline shape"></polyline></svg>{% elif region.json.type == "point" %}<svg class="shape-container" viewBox="0 0 {{ copy.width }} {{ copy.height }}"><circle cx="{{ region.json.shape.x * copy.width }}" cy="{{ region.json.shape.y * copy.height }}" r="0" fill="none" class="shape-point shape"></circle></svg>{% endif %}{% endfor %}</div>{{ annotation_display.annotation_display(copy) }}<div class="list-detail"> {{ copy.title }} </div>
templates/profile.html
@@ -1,4 +1,5 @@
{% extends "default.html" %} {% import "small-annotation-display.html" as annotation_display %}{% block nav_title %}{{ user.formatted_name }}{% endblock %} {% block title %}{{ user.formatted_name }}'s profile | {{ site_name }}{% endblock %}
@@ -12,33 +13,7 @@
{% for resource in user.pictures %} <li> <a href="/picture/{{ resource.id }}"> <div class="annotation-zone"><img src="/raw/picture/{{ resource.id }}" alt="{{ resource.title }}">{% for region in resource.regions %}{% if region.json.type == "bbox" %}<svg class="shape-container" viewBox="0 0 {{ resource.width }} {{ resource.height }}"><rect x="{{ region.json.shape.x * resource.width }}"y="{{ region.json.shape.y * resource.height }}"width="{{ region.json.shape.w * resource.width }}"height="{{ region.json.shape.h * resource.height }}"fill="none" class="shape-bbox shape"></rect></svg>{% elif region.json.type == "polygon" %}<svg class="shape-container" viewBox="0 0 {{ resource.width }} {{ resource.height }}"><polygon points="{% for point in region.json.shape %}{{ point.x * resource.width }},{{ point.y * resource.height }} {% endfor %}" fill="none" class="shape-polygon shape"></polygon></svg>{% elif region.json.type == "polyline" %}<svg class="shape-container" viewBox="0 0 {{ resource.width }} {{ resource.height }}"><polyline points="{% for point in region.json.shape %}{{ point.x * resource.width }},{{ point.y * resource.height }} {% endfor %}" fill="none" class="shape-polyline shape"></polyline></svg>{% elif region.json.type == "point" %}<svg class="shape-container" viewBox="0 0 {{ resource.width }} {{ resource.height }}"><circle cx="{{ region.json.shape.x * resource.width }}" cy="{{ region.json.shape.y * resource.height }}" r="0" fill="none" class="shape-point shape"></circle></svg>{% endif %}{% endfor %}</div>{{ annotation_display.annotation_display(resource) }}<div class="list-detail"> {{ resource.title }} </div>
templates/small-annotation-display.html
@@ -0,0 +1,29 @@
{% macro annotation_display(resource) %} <div class="annotation-zone"> <img src="/raw/picture/{{ resource.id }}" alt="{{ resource.title }}"> {% for region in resource.regions %} {% if region.json.type == "bbox" %} <svg class="shape-container" viewBox="0 0 1 1" preserveAspectRatio="none"> <rect x="{{ region.json.shape.x }}" y="{{ region.json.shape.y }}" width="{{ region.json.shape.w }}" height="{{ region.json.shape.h }}" fill="none" class="shape-bbox shape" ></rect> </svg> {% elif region.json.type == "polygon" %} <svg class="shape-container" viewBox="0 0 1 1" preserveAspectRatio="none"> <polygon points="{% for point in region.json.shape %}{{ point.x }},{{ point.y }} {% endfor %}" fill="none" class="shape-polygon shape"></polygon> </svg> {% elif region.json.type == "polyline" %} <svg class="shape-container" viewBox="0 0 1 1" preserveAspectRatio="none"> <polyline points="{% for point in region.json.shape %}{{ point.x }},{{ point.y }} {% endfor %}" fill="none" class="shape-polyline shape"></polyline> </svg> {% elif region.json.type == "point" %} <svg class="shape-container" viewBox="0 0 1 1" preserveAspectRatio="none"> <circle cx="{{ region.json.shape.x }}" cy="{{ region.json.shape.y }}" r="0" fill="none" class="shape-point shape"></circle> </svg> {% endif %} {% endfor %} </div> {% endmacro %}