простой зум

This commit is contained in:
2026-02-26 22:08:01 +03:00
parent 2ab6bcd408
commit 78d586ce3d

View File

@@ -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 => {},
}