Browse Source

Merge pull request #1635 from zauberzeug/interactive-image

Interactive image: Fix mousemove event registration
Rodja Trappe 1 year ago
parent
commit
c0ef1ee9c8
2 changed files with 39 additions and 11 deletions
  1. 21 11
      nicegui/elements/interactive_image.js
  2. 18 0
      tests/test_interactive_image.py

+ 21 - 11
nicegui/elements/interactive_image.js

@@ -1,7 +1,15 @@
 export default {
   template: `
     <div style="position:relative">
-      <img ref="img" :src="computed_src" style="width:100%; height:100%;" v-on="onEvents" draggable="false" />
+      <img
+        ref="img"
+        :src="computed_src"
+        style="width:100%; height:100%;"
+        @load="onImageLoaded"
+        v-on="onCrossEvents"
+        v-on="onUserEvents"
+        draggable="false"
+      />
       <svg style="position:absolute;top:0;left:0;pointer-events:none" :viewBox="viewBox">
         <g v-if="cross" :style="{ display: cssDisplay }">
           <line :x1="x" y1="0" :x2="x" y2="100%" stroke="black" />
@@ -74,18 +82,20 @@ export default {
     },
   },
   computed: {
-    onEvents() {
-      const allEvents = {};
+    onCrossEvents() {
+      if (!this.cross) return {};
+      return {
+        mouseenter: () => (this.cssDisplay = "block"),
+        mouseleave: () => (this.cssDisplay = "none"),
+        mousemove: (event) => this.updateCrossHair(event),
+      };
+    },
+    onUserEvents() {
+      const events = {};
       for (const type of this.events) {
-        allEvents[type] = (event) => this.onMouseEvent(type, event);
-      }
-      if (this.cross) {
-        allEvents["mouseenter"] = () => (this.cssDisplay = "block");
-        allEvents["mouseleave"] = () => (this.cssDisplay = "none");
-        allEvents["mousemove"] = (event) => this.updateCrossHair(event);
+        events[type] = (event) => this.onMouseEvent(type, event);
       }
-      allEvents["load"] = (event) => this.onImageLoaded(event);
-      return allEvents;
+      return events;
     },
   },
   props: {

+ 18 - 0
tests/test_interactive_image.py

@@ -1,4 +1,5 @@
 import pytest
+from selenium.webdriver.common.action_chains import ActionChains
 
 from nicegui import Client, ui
 
@@ -57,3 +58,20 @@ def test_replace_interactive_image(screen: Screen):
     screen.click('Replace')
     screen.wait(0.5)
     assert screen.find_by_tag('img').get_attribute('src').endswith('id/30/640/360')
+
+
+@pytest.mark.parametrize('cross', [True, False])
+def test_mousemove_event(screen: Screen, cross: bool):
+    counter = {'value': 0}
+    ii = ui.interactive_image('https://picsum.photos/id/29/640/360', cross=cross, events=['mousemove'],
+                              on_mouse=lambda: counter.update(value=counter['value'] + 1))
+
+    screen.open('/')
+    element = screen.find_element(ii)
+    ActionChains(screen.selenium) \
+        .move_to_element_with_offset(element, 0, 0) \
+        .pause(0.5) \
+        .move_by_offset(10, 10) \
+        .pause(0.5) \
+        .perform()
+    assert counter['value'] > 0