Quellcode durchsuchen

svg overlay with dynamic content; prepare crosshair feature

Falko Schindler vor 3 Jahren
Ursprung
Commit
789be62dcd
2 geänderte Dateien mit 30 neuen und 6 gelöschten Zeilen
  1. 17 2
      nicegui/elements/annotation_tool.js
  2. 13 4
      nicegui/elements/annotation_tool.py

+ 17 - 2
nicegui/elements/annotation_tool.js

@@ -1,7 +1,22 @@
 Vue.component("annotation_tool", {
-  template: `<img v-bind:id="jp_props.id" :src="jp_props.options.source"></div>`,
+  template: `
+    <div :id="jp_props.id" style="position:relative;display:inline-block">
+      <img style="max-width:100%">
+      <svg style="position:absolute;top:0;left:0;pointer-events:none" v-html="jp_props.options.svg_content"></svg>
+    </div>
+  `,
   mounted() {
-    const image = document.getElementById(this.$props.jp_props.id);
+    const image = document.getElementById(this.$props.jp_props.id).firstChild;
+    const svg = document.getElementById(this.$props.jp_props.id).lastChild;
+    image.ondragstart = () => false;
+    if (this.$props.jp_props.options.cross) {
+      image.style.cursor = "none";
+    }
+    image.onload = (e) => {
+      const viewBox = `0 0 ${image.naturalWidth} ${image.naturalHeight}`;
+      svg.setAttribute("viewBox", viewBox);
+    };
+    image.src = this.$props.jp_props.options.source;
     for (const type of this.$props.jp_props.options.events) {
       image.addEventListener(type, (e) => {
         const event = {

+ 13 - 4
nicegui/elements/annotation_tool.py

@@ -9,14 +9,14 @@ CustomView.use(__file__)
 
 class AnnotationToolView(CustomView):
 
-    def __init__(self, source: str, on_mouse: Callable, events: list[str]):
-        super().__init__('annotation_tool', source=source, events=events)
+    def __init__(self, source: str, on_mouse: Callable, events: list[str], cross: bool):
+        super().__init__('annotation_tool', source=source, events=events, cross=cross, svg_content='')
         self.allowed_events = ['onMouse']
         self.initialize(onMouse=on_mouse)
 
 class AnnotationTool(Element):
 
-    def __init__(self, source: str, on_mouse: Callable, events: list[str] = ['click']):
+    def __init__(self, source: str, on_mouse: Callable, *, events: list[str] = ['click'], cross: bool = False):
         """Annotation Tool
 
         Create a special image that handles mouse clicks and yields image coordinates.
@@ -24,9 +24,10 @@ class AnnotationTool(Element):
         :param source: the source of the image; can be an url or a base64 string
         :param on_mouse: callback for mouse events (yields `type`, `image_x` and `image_y`)
         :param events: list of JavaScript events to subscribe to
+        :param cross: whether to show crosshairs (default: `False`)
         """
         self.mouse_handler = on_mouse
-        super().__init__(AnnotationToolView(source, self.handle_mouse, events))
+        super().__init__(AnnotationToolView(source, self.handle_mouse, events, cross))
 
     def handle_mouse(self, msg):
         try:
@@ -40,3 +41,11 @@ class AnnotationTool(Element):
             handle_event(self.mouse_handler, arguments)
         except:
             traceback.print_exc()
+
+    @property
+    def svg_content(self) -> str:
+        return self.view.options.svg_content
+
+    @svg_content.setter
+    def svg_content(self, content: str):
+        self.view.options.svg_content = content