Skip to content

Commit a0e326f

Browse files
stanleyqubitdexeonify
authored andcommitted
crop: Clamp cursor within video dimensions
...and display crop zone DAR Previously, the script would allow for the drawing of the crop zone to begin even if the crop cursor was placed outside video dimensions (e.g. the area into which the video is rendered). This would show inaccurate crop zone dimensions when drawing the text for the crop zone. This PR limits placing of the crop cursor within video dimensions area, and also adds a little quality-of-life feature that displays the aspect ratio of the crop zone before validation. Ref: occivink/mpv-scripts#67
1 parent 8b386f5 commit a0e326f

File tree

1 file changed

+24
-18
lines changed

1 file changed

+24
-18
lines changed

scripts/crop.lua

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ local rect_centered = false
4949
local rect_keepaspect = false
5050
local needs_drawing = false
5151
local crop_first_corner = nil -- in normalized video space
52-
local crop_cursor = {
52+
local cursor = {
5353
x = 0,
5454
y = 0
5555
}
@@ -82,6 +82,11 @@ function rect_from_two_points(p1, p2, centered, ratio)
8282
return { x = c1[1], y = c1[2] }, { x = c2[1], y = c2[2] }
8383
end
8484

85+
function round(num, num_decimal_places)
86+
local mult = 10^(num_decimal_places or 0)
87+
return math.floor(num * mult + 0.5) / mult
88+
end
89+
8590
function clamp(low, value, high)
8691
if value <= low then
8792
return low
@@ -92,10 +97,10 @@ function clamp(low, value, high)
9297
end
9398
end
9499

95-
function clamp_point(top_left, point, bottom_right)
100+
function clamp_point(point, dim)
96101
return {
97-
x = clamp(top_left.x, point.x, bottom_right.x),
98-
y = clamp(top_left.y, point.y, bottom_right.y)
102+
x = clamp(dim.ml, point.x, dim.w - dim.mr),
103+
y = clamp(dim.mt, point.y, dim.h - dim.mb)
99104
}
100105
end
101106

@@ -210,10 +215,7 @@ function draw_crop_zone()
210215
return
211216
end
212217

213-
local cursor = {
214-
x = crop_cursor.x,
215-
y = crop_cursor.y,
216-
}
218+
cursor = clamp_point(cursor, dim)
217219
local ass = assdraw.ass_new()
218220

219221
if crop_first_corner and (opts.draw_shade or opts.draw_frame) then
@@ -247,9 +249,13 @@ function draw_crop_zone()
247249
local cursor_norm = screen_to_video_norm(cursor, dim)
248250
local text = string.format("%d, %d", cursor_norm.x * vop.w, cursor_norm.y * vop.h)
249251
if crop_first_corner then
250-
text = string.format("%s (%dx%d)", text,
251-
math.abs((cursor_norm.x - crop_first_corner.x) * vop.w ),
252-
math.abs((cursor_norm.y - crop_first_corner.y) * vop.h )
252+
local crop_zone_w = math.abs((cursor_norm.x - crop_first_corner.x) * vop.w )
253+
local crop_zone_h = math.abs((cursor_norm.y - crop_first_corner.y) * vop.h )
254+
local crop_zone_aspect = round(crop_zone_w / crop_zone_h, 3)
255+
text = string.format("%s (%dx%d/%s)", text,
256+
crop_zone_w,
257+
crop_zone_h,
258+
crop_zone_aspect
253259
)
254260
end
255261
draw_position_text(ass, text, cursor, { w = dim.w, h = dim.h }, 6)
@@ -308,14 +314,14 @@ function update_crop_zone_state()
308314
cancel_crop()
309315
return
310316
end
311-
local corner = crop_cursor
317+
cursor = clamp_point(cursor, dim)
312318
if crop_first_corner == nil then
313-
crop_first_corner = screen_to_video_norm(crop_cursor, dim)
319+
crop_first_corner = screen_to_video_norm(cursor, dim)
314320
redraw()
315321
else
316322
local c1, c2 = rect_from_two_points(
317323
video_norm_to_screen(crop_first_corner, dim),
318-
crop_cursor,
324+
cursor,
319325
rect_centered,
320326
rect_keepaspect and dim.w/dim.h)
321327
local c1norm = screen_to_video_norm(c1, dim)
@@ -361,7 +367,7 @@ function start_crop(mode)
361367
active_mode = mode_maybe
362368

363369
if opts.mouse_support then
364-
crop_cursor.x, crop_cursor.y = mp.get_mouse_pos()
370+
cursor.x, cursor.y = mp.get_mouse_pos()
365371
end
366372
redraw()
367373
for key, func in pairs(bindings) do
@@ -405,7 +411,7 @@ end
405411

406412
-- bindings
407413
if opts.mouse_support then
408-
bindings["MOUSE_MOVE"] = function() crop_cursor.x, crop_cursor.y = mp.get_mouse_pos(); redraw() end
414+
bindings["MOUSE_MOVE"] = function() cursor.x, cursor.y = mp.get_mouse_pos(); redraw() end
409415
end
410416
for _, key in ipairs(opts.accept) do
411417
bindings[key] = update_crop_zone_state
@@ -415,8 +421,8 @@ for _, key in ipairs(opts.cancel) do
415421
end
416422
function movement_func(move_x, move_y)
417423
return function()
418-
crop_cursor.x = crop_cursor.x + move_x
419-
crop_cursor.y = crop_cursor.y + move_y
424+
cursor.x = cursor.x + move_x
425+
cursor.y = cursor.y + move_y
420426
redraw()
421427
end
422428
end

0 commit comments

Comments
 (0)