Рабочий зум
This commit is contained in:
@@ -1,19 +1,22 @@
|
||||
const std = @import("std");
|
||||
const dvui = @import("dvui");
|
||||
const Size = dvui.Size;
|
||||
const Color = dvui.Color;
|
||||
|
||||
const Canvas = @This();
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
texture: ?dvui.Texture = null,
|
||||
width: u32 = 400,
|
||||
height: u32 = 300,
|
||||
size: Size = .{ .w = 800, .h = 600 },
|
||||
pos: dvui.Point = dvui.Point{ .x = 0, .y = 0 },
|
||||
scroll: dvui.ScrollInfo = .{
|
||||
.vertical = .given,
|
||||
.horizontal = .given,
|
||||
.virtual_size = .{ .w = 2000, .h = 2000 },
|
||||
.vertical = .auto,
|
||||
.horizontal = .auto,
|
||||
// .virtual_size = .{ .w = 2000, .h = 2000 },
|
||||
},
|
||||
zoom: f32 = 1,
|
||||
gradient_start: Color.PMA = .{ .r = 0, .g = 0, .b = 0, .a = 255 },
|
||||
gradient_end: Color.PMA = .{ .r = 255, .g = 255, .b = 255, .a = 255 },
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) Canvas {
|
||||
return .{ .allocator = allocator };
|
||||
@@ -27,26 +30,24 @@ pub fn deinit(self: *Canvas) void {
|
||||
}
|
||||
|
||||
/// Заполнить canvas градиентом
|
||||
pub fn fillRandomColor(self: *Canvas) !void {
|
||||
pub fn redrawGradient(self: *Canvas) !void {
|
||||
std.debug.print("Zoom: {any}\n", .{self.zoom});
|
||||
const width: u32 = @intFromFloat(self.size.w * self.zoom);
|
||||
const height: u32 = @intFromFloat(self.size.h * self.zoom);
|
||||
|
||||
// Выделить буфер пиксельных данных
|
||||
const pixels = try self.allocator.alloc(Color.PMA, @as(usize, self.width) * self.height);
|
||||
const pixels = try self.allocator.alloc(Color.PMA, @as(usize, width) * height);
|
||||
defer self.allocator.free(pixels);
|
||||
|
||||
// Сгенерировать случайные цвета градиента
|
||||
var prng = std.Random.DefaultPrng.init(@intCast(std.time.microTimestamp()));
|
||||
const random = prng.random();
|
||||
const start_color = Color.PMA{ .r = random.int(u8), .g = random.int(u8), .b = random.int(u8), .a = 255 };
|
||||
const end_color = Color.PMA{ .r = random.int(u8), .g = random.int(u8), .b = random.int(u8), .a = 255 };
|
||||
|
||||
var y: u32 = 0;
|
||||
while (y < self.height) : (y += 1) {
|
||||
while (y < height) : (y += 1) {
|
||||
var x: u32 = 0;
|
||||
while (x < self.width) : (x += 1) {
|
||||
const factor = @as(f32, @floatFromInt(x)) / @as(f32, @floatFromInt(self.width - 1));
|
||||
const r = @as(u8, @intFromFloat(@as(f32, @floatFromInt(start_color.r)) + factor * (@as(f32, @floatFromInt(end_color.r)) - @as(f32, @floatFromInt(start_color.r)))));
|
||||
const g = @as(u8, @intFromFloat(@as(f32, @floatFromInt(start_color.g)) + factor * (@as(f32, @floatFromInt(end_color.g)) - @as(f32, @floatFromInt(start_color.g)))));
|
||||
const b = @as(u8, @intFromFloat(@as(f32, @floatFromInt(start_color.b)) + factor * (@as(f32, @floatFromInt(end_color.b)) - @as(f32, @floatFromInt(start_color.b)))));
|
||||
pixels[y * self.width + x] = .{ .r = r, .g = g, .b = b, .a = 255 };
|
||||
while (x < width) : (x += 1) {
|
||||
const factor = (@as(f32, @floatFromInt(x)) / @as(f32, @floatFromInt(width - 1)) + @as(f32, @floatFromInt(y)) / @as(f32, @floatFromInt(height - 1))) / 2;
|
||||
const r = @as(u8, @intFromFloat(@as(f32, @floatFromInt(self.gradient_start.r)) + factor * (@as(f32, @floatFromInt(self.gradient_end.r)) - @as(f32, @floatFromInt(self.gradient_start.r)))));
|
||||
const g = @as(u8, @intFromFloat(@as(f32, @floatFromInt(self.gradient_start.g)) + factor * (@as(f32, @floatFromInt(self.gradient_end.g)) - @as(f32, @floatFromInt(self.gradient_start.g)))));
|
||||
const b = @as(u8, @intFromFloat(@as(f32, @floatFromInt(self.gradient_start.b)) + factor * (@as(f32, @floatFromInt(self.gradient_end.b)) - @as(f32, @floatFromInt(self.gradient_start.b)))));
|
||||
pixels[y * width + x] = .{ .r = r, .g = g, .b = b, .a = 255 };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,13 +57,23 @@ pub fn fillRandomColor(self: *Canvas) !void {
|
||||
}
|
||||
|
||||
// Создать новую текстуру из пиксельных данных
|
||||
self.texture = try dvui.textureCreate(pixels, self.width, self.height, .linear);
|
||||
self.texture = try dvui.textureCreate(pixels, width, height, .nearest);
|
||||
}
|
||||
|
||||
// Дать скроллам ощутимый диапазон сразу (минимум 2000x2000)
|
||||
self.scroll.virtual_size = .{
|
||||
.w = @max(2000, @as(f32, @floatFromInt(self.width))),
|
||||
.h = @max(2000, @as(f32, @floatFromInt(self.height))),
|
||||
};
|
||||
/// Заполнить canvas случайным градиентом
|
||||
pub fn fillRandomGradient(self: *Canvas) !void {
|
||||
// Сгенерировать случайные цвета градиента
|
||||
var prng = std.Random.DefaultPrng.init(@intCast(std.time.microTimestamp()));
|
||||
const random = prng.random();
|
||||
self.gradient_start = Color.PMA{ .r = random.int(u8), .g = random.int(u8), .b = random.int(u8), .a = 255 };
|
||||
self.gradient_end = Color.PMA{ .r = random.int(u8), .g = random.int(u8), .b = random.int(u8), .a = 255 };
|
||||
|
||||
try self.redrawGradient();
|
||||
}
|
||||
|
||||
pub fn addZoom(self: *Canvas, value: f32) void {
|
||||
self.zoom += value;
|
||||
self.zoom = @max(self.zoom, 0.01);
|
||||
}
|
||||
|
||||
/// Отобразить canvas в UI
|
||||
|
||||
Reference in New Issue
Block a user