diff --git a/src/ui/canvas_view.zig b/src/ui/canvas_view.zig index 8c15f25..6cf478e 100644 --- a/src/ui/canvas_view.zig +++ b/src/ui/canvas_view.zig @@ -186,30 +186,31 @@ fn handleCanvasZoom(canvas: *Canvas, scroll: anytype) void { switch (action) { .wheel_y => |y| { const viewport_pt = scroll.data().contentRectScale().pointFromPhysical(mouse.p); - const content_pt = dvui.Point{ + var content_pt = dvui.Point{ .x = viewport_pt.x + canvas.scroll.viewport.x, .y = viewport_pt.y + canvas.scroll.viewport.y, }; const doc_pt = canvas.contentPointToDocument(content_pt, natural_scale); - canvas.addZoom(y / 1000); - // canvas.multZoom(1 + y / 3000); + // canvas.addZoom(y / 1000); + canvas.multZoom(1 + y / 2000); canvas.requestRedraw(); - // Сдвигаем viewport так, чтобы точка под курсором (даже вне холста) не уезжала - const new_zoom = canvas.getZoom(); - const img = canvas.getZoomedImageSize(); - const new_content_x = (@as(f32, @floatFromInt(img.x)) + doc_pt.x * new_zoom) / natural_scale; - const new_content_y = (@as(f32, @floatFromInt(img.y)) + doc_pt.y * new_zoom) / natural_scale; - canvas.scroll.viewport.x = new_content_x - viewport_pt.x; - canvas.scroll.viewport.y = new_content_y - viewport_pt.y; - const viewport_rect = scroll.data().contentRect(); - const content_w = @as(f32, @floatFromInt(img.x + img.w)) / natural_scale; - const content_h = @as(f32, @floatFromInt(img.y + img.h)) / natural_scale; - const max_x = @max(0, content_w - viewport_rect.w + canvas.pos.x); - const max_y = @max(0, content_h - viewport_rect.h + canvas.pos.y); - canvas.scroll.viewport.x = std.math.clamp(canvas.scroll.viewport.x, 0, max_x); - canvas.scroll.viewport.y = std.math.clamp(canvas.scroll.viewport.y, 0, max_y); + const doc_pt_after = canvas.contentPointToDocument(content_pt, natural_scale); + + const zoom = canvas.getZoom(); + const dx = (doc_pt_after.x - doc_pt.x) * zoom; + const dy = (doc_pt_after.y - doc_pt.y) * zoom; + + canvas.scroll.viewport.x -= dx; + canvas.scroll.viewport.y -= dy; + content_pt = dvui.Point{ + .x = viewport_pt.x + canvas.scroll.viewport.x, + .y = viewport_pt.y + canvas.scroll.viewport.y, + }; + const fixed = canvas.contentPointToDocument(content_pt, natural_scale); + + std.debug.print("prev: {any}, after: {any}, fixed: {}\n", .{ doc_pt, doc_pt_after, fixed }); }, else => {}, }