interactive_image_documentation.py 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. from nicegui import ui
  2. from . import doc
  3. @doc.demo(ui.interactive_image)
  4. def main_demo() -> None:
  5. from nicegui import events
  6. def mouse_handler(e: events.MouseEventArguments):
  7. color = 'SkyBlue' if e.type == 'mousedown' else 'SteelBlue'
  8. ii.content += f'<circle cx="{e.image_x}" cy="{e.image_y}" r="15" fill="none" stroke="{color}" stroke-width="4" />'
  9. ui.notify(f'{e.type} at ({e.image_x:.1f}, {e.image_y:.1f})')
  10. src = 'https://picsum.photos/id/565/640/360'
  11. ii = ui.interactive_image(src, on_mouse=mouse_handler, events=['mousedown', 'mouseup'], cross=True)
  12. @doc.demo('Nesting elements', '''
  13. You can nest elements inside an interactive image.
  14. Use Tailwind classes like "absolute top-0 left-0" to position the label absolutely with respect to the image.
  15. Of course this can be done with plain CSS as well.
  16. ''')
  17. def nesting_elements():
  18. with ui.interactive_image('https://picsum.photos/id/147/640/360'):
  19. ui.button(on_click=lambda: ui.notify('thumbs up'), icon='thumb_up') \
  20. .props('flat fab color=white') \
  21. .classes('absolute bottom-0 left-0 m-2')
  22. @doc.demo('Force reload', '''
  23. You can force an image to reload by calling the `force_reload` method.
  24. It will append a timestamp to the image URL, which will make the browser reload the image.
  25. ''')
  26. def force_reload():
  27. img = ui.interactive_image('https://picsum.photos/640/360').classes('w-64')
  28. ui.button('Force reload', on_click=img.force_reload)
  29. @doc.demo('Blank canvas', '''
  30. You can also create a blank canvas with a given size.
  31. This is useful if you want to draw something without loading a background image.
  32. ''')
  33. def blank_canvas():
  34. ui.interactive_image(
  35. size=(800, 600), cross=True,
  36. on_mouse=lambda e: e.sender.set_content(f'''
  37. <circle cx="{e.image_x}" cy="{e.image_y}" r="50" fill="orange" />
  38. '''),
  39. ).classes('w-64 bg-blue-50')
  40. @doc.demo('Loaded event', '''
  41. You can listen to the "loaded" event to know when the image has been loaded.
  42. ''')
  43. def loaded_event():
  44. import time
  45. ii = ui.interactive_image('https://picsum.photos/640/360')
  46. ii.on('loaded', lambda e: ui.notify(f'loaded {e.args}'))
  47. ui.button('Change Source', on_click=lambda: ii.set_source(f'https://picsum.photos/640/360?time={time.time()}'))
  48. @doc.demo('Crosshairs', '''
  49. You can show crosshairs by passing `cross=True`.
  50. You can also change the color of the crosshairs by passing a color string.
  51. ''')
  52. def crosshairs():
  53. ui.interactive_image('https://picsum.photos/id/565/640/360', cross='red')
  54. @doc.demo('SVG events', '''
  55. You can subscribe to events of the SVG elements by using the `on` method with an "svg:" prefix.
  56. Make sure to set `pointer-events="all"` for the SVG elements you want to receive events from.
  57. Currently the following SVG events are supported:
  58. - pointermove
  59. - pointerdown
  60. - pointerup
  61. - pointerover
  62. - pointerout
  63. - pointerenter
  64. - pointerleave
  65. - pointercancel
  66. ''')
  67. def svg_content():
  68. ui.interactive_image('https://picsum.photos/id/565/640/360', cross=True, content='''
  69. <rect id="A" x="85" y="70" width="80" height="60" fill="none" stroke="red" pointer-events="all" cursor="pointer" />
  70. <rect id="B" x="180" y="70" width="80" height="60" fill="none" stroke="red" pointer-events="all" cursor="pointer" />
  71. ''').on('svg:pointerdown', lambda e: ui.notify(f'SVG clicked: {e.args}'))
  72. doc.reference(ui.interactive_image)