ipyevents icon indicating copy to clipboard operation
ipyevents copied to clipboard

How to obtain the coordinates of a click on the image when object_fit='contain'?

Open GuillaumeFavelier opened this issue 3 years ago • 1 comments

Hello maintainers and contributors of ipyevents :wave:


The context

I contribute to mne-python(opened issue) and I am working on integration into the Jupyter Notebook environment. The project has tight interactions between ipyevents, ipycanvas, ipyvtklink(opened issue) and ipywidgets, that's why I am not 100% sure it is the right place to open this issue but I will try to explain the unexpected behaviour I observe anyway.

Here is a demo of the final app in mne-python:

https://user-images.githubusercontent.com/18143289/153018183-dc8a8950-4eb0-4489-8022-e65b6e0813d1.mp4


The issue

Let's assume an image contained in an HBox called viewer and a VBox called right_dock containing multiple widgets in an Accordion folded by default. Both viewer and right_dock are in turn contained into an HBox called app which is finally displayed:

image

I would like to get the coordinates of the click in image when the layout is set to image.layout.object_fit = 'contain' (useful to preserve the aspect ratio).

image

Unfortunately, I think ipyevents is not aware of object_fit because the coordinates that I observe in my experiments are the same as if the image was 'stretched' to fit its container.

https://user-images.githubusercontent.com/18143289/154511832-dc41e328-37d4-47c0-93a2-5c74ae84c84b.mp4

Is there a way to obtain the real coordinates of a click on the image in this situation?


Minimum reproducible example

I share below a simplified example (inspired from the demo notebook):

from ipywidgets import Box, VBox, HBox, HTML, Image, Accordion
from ipyevents import Event

def gen_opts(n):
    return[HTML(f"option{i}") for i in range(n)]

with open('images/gaussian_600_x_300.png', 'rb') as f:
    value = f.read()

image = Image(value=value, format='png')
image.layout.object_fit = 'contain'
image.layout.border = '5px red solid'

right_dock = Accordion([VBox(gen_opts(15))])
right_dock.set_title(0, "Right dock")
right_dock.selected_index = None

im_events = Event()
im_events.source = image
im_events.watched_events = ['click']

viewer = HBox([image])
red_layout(image)

coordinates = HTML('<h3>Click an image to see the click coordinates here</h3>')
def update_coords(event):
    coordinates.value = '<h3>Clicked at ({}, {})</h3>'.format(event['dataX'], event['dataY'])
    
im_events.on_dom_event(update_coords)

row = HBox([viewer, right_dock])
app = VBox([row, coordinates])
app

cc @larsoner, @banesullivan

GuillaumeFavelier avatar Feb 17 '22 15:02 GuillaumeFavelier

Thanks for the report -- I'll try to track down the issue (I do think it is an ipyevents issue).

Also, awesome-looking tool you have developed 💯 !

mwcraig avatar Jun 20 '22 15:06 mwcraig