roundabout,
created on Tuesday, 7 January 2025, 08:25:23 (1736238323),
received on Tuesday, 7 January 2025, 08:25:28 (1736238328)
Author identity: vlad <vlad.muntoiu@gmail.com>
e77acb55b4016a79c5f1fa8c8fb3ba248f315cbc
static/picture-annotation.py
@@ -693,7 +693,7 @@ translate_x = 0
translate_y = 0 def update_transform(): zone.style.transform = f"scale({scale}) translate({translate_x}px, {translate_y}px)"zone.style.transform = f"translate({translate_x}px, {translate_y}px) scale({scale}) "object_list.style.transform = f"scale({1/scale})" # neutralise the zoom vertical_ruler.style.transform = f"scale({1/scale})" horizontal_ruler.style.transform = f"scale({1/scale})"
@@ -713,6 +713,21 @@ scale_exponent = 0
zoom_offset = (0, 0) def compute_zoom_translation_around_point(element, x, y, sc, nsc): rect = element.getBoundingClientRect() # The difference in size between the new and old scales. size_difference_x = (nsc - sc) * image.width size_difference_y = (nsc - sc) * image.height width = rect.width / sc height = rect.height / sc # (size difference) * ((cursor position) / (image size) - (transform origin)) tx = size_difference_x * (x / width - 0.5) ty = size_difference_y * (y / height - 0.5) return tx, ty def on_wheel(event): global scale, scale_exponent, translate_x, translate_y if object_list.matches(":hover"):
@@ -720,9 +735,24 @@ def on_wheel(event):
event.preventDefault() rect = zone.getBoundingClientRect() # Position of the cursor in the unscaled image. mouse_x = (event.clientX - rect.left) / scale mouse_y = (event.clientY - rect.top) / scale # Adjust scale exponent and compute new scale. scale_exponent += (-1 if event.deltaY > 0 else 1) / 4 new_scale = 2 ** scale_exponent # Limit the scale to a reasonable range. new_scale = max(0.0625, min(64, new_scale)) # Compute the new translation. offset_x, offset_y = compute_zoom_translation_around_point(zone, mouse_x, mouse_y, scale, new_scale) translate_x -= offset_x translate_y -= offset_yscale = new_scale update_transform()
@@ -748,8 +778,8 @@ def on_mouse_move(event):
return if is_dragging: translate_x += event.movementX / scaletranslate_y += event.movementY / scaletranslate_x += event.movementX translate_y += event.movementYupdate_transform() def on_mouse_up(event):
@@ -758,8 +788,16 @@ def on_mouse_up(event):
return is_dragging = False last_touch_positions = None last_touch_distance = None def calculate_distance(touches): dx = touches[1].clientX - touches[0].clientX dy = touches[1].clientY - touches[0].clientY return (dx**2 + dy**2) ** 0.5 def on_touch_start(event): global last_touch_positionsglobal last_touch_positions, last_touch_distanceif event.touches.length == 2: event.preventDefault()
@@ -767,9 +805,10 @@ def on_touch_start(event):
(event.touches[0].clientX, event.touches[0].clientY), (event.touches[1].clientX, event.touches[1].clientY) ] last_touch_distance = calculate_distance(event.touches)def on_touch_move(event): global translate_x, translate_y, last_touch_positionsglobal translate_x, translate_y, scale, last_touch_positions, last_touch_distanceif event.touches.length == 2: event.preventDefault()
@@ -779,20 +818,38 @@ def on_touch_move(event):
(event.touches[1].clientX, event.touches[1].clientY) ] current_distance = calculate_distance(event.touches) zoom_factor = current_distance / last_touch_distance new_scale = max(0.0625, min(64, scale * zoom_factor)) scale_factor = new_scale / scale midpoint_x = (current_positions[0][0] + current_positions[1][0]) / 2 midpoint_y = (current_positions[0][1] + current_positions[1][1]) / 2 rect = zone.getBoundingClientRect() content_mid_x = (midpoint_x - rect.left - translate_x) / scale content_mid_y = (midpoint_y - rect.top - translate_y) / scale translate_x = midpoint_x - content_mid_x * new_scale translate_y = midpoint_y - content_mid_y * new_scale delta_x = sum(p[0] - lp[0] for p, lp in zip(current_positions, last_touch_positions)) / 2 delta_y = sum(p[1] - lp[1] for p, lp in zip(current_positions, last_touch_positions)) / 2 translate_x += delta_x translate_y += delta_y scale = new_scale last_touch_positions = current_positions last_touch_distance = current_distanceupdate_transform() def on_touch_end(event): global last_touch_positionsif event.touches.length == 0:global last_touch_positions, last_touch_distance if event.touches.length < 2:last_touch_positions = None last_touch_distance = Nonezoom_container.addEventListener("wheel", on_wheel) zoom_container.addEventListener("mousedown", on_mouse_down)