Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Canvas: Undo & Clear hotkey, brush scales by area, consistent max brush size #16668

Open
wants to merge 11 commits into
base: dev
Choose a base branch
from
51 changes: 41 additions & 10 deletions extensions-builtin/canvas-zoom-and-pan/javascript/zoom.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ onUiLoaded(async() => {
canvas_show_tooltip: true,
canvas_auto_expand: true,
canvas_blur_prompt: false,
canvas_hotkey_undo: "KeyZ",
canvas_hotkey_clear: "KeyC",
};

const functionMap = {
Expand All @@ -236,7 +238,9 @@ onUiLoaded(async() => {
"Moving canvas": "canvas_hotkey_move",
"Fullscreen": "canvas_hotkey_fullscreen",
"Reset Zoom": "canvas_hotkey_reset",
"Overlap": "canvas_hotkey_overlap"
"Overlap": "canvas_hotkey_overlap",
"Undo": "canvas_hotkey_undo",
"Clear": "canvas_hotkey_clear"
};

// Loading the configuration from opts
Expand Down Expand Up @@ -321,6 +325,8 @@ onUiLoaded(async() => {
action: "Adjust brush size",
keySuffix: " + wheel"
},
{configKey: "canvas_hotkey_undo", action: "Undo brush stroke"},
{configKey: "canvas_hotkey_clear", action: "Clear canvas"},
{configKey: "canvas_hotkey_reset", action: "Reset zoom"},
{
configKey: "canvas_hotkey_fullscreen",
Expand Down Expand Up @@ -464,22 +470,45 @@ onUiLoaded(async() => {
gradioApp().querySelector(
`${elemId} button[aria-label="Use brush"]`
);

if (input) {
input.click();
if (!withoutValue) {
const maxValue =
parseFloat(input.getAttribute("max")) || 100;
const changeAmount = maxValue * (percentage / 100);
const newValue =
parseFloat(input.value) +
(deltaY > 0 ? -changeAmount : changeAmount);
input.value = Math.min(Math.max(newValue, 0), maxValue);
const maxValue = parseFloat(input.getAttribute("max")) || 100;
const minValue = parseFloat(input.getAttribute("min")) || 1;
// allow brush size up to 1/2 diagonal of the image, beyond gradio's arbitrary limit
const canvasImg = gradioApp().querySelector(`${elemId} img`);
if (canvasImg) {
const maxDiameter = Math.sqrt(canvasImg.naturalWidth ** 2 + canvasImg.naturalHeight ** 2) / 2;
if (maxDiameter > maxValue) {
input.setAttribute("max", maxDiameter);
}
if (minValue > 1) {
input.setAttribute("min", '1');
}
}
const brush_factor = deltaY > 0 ? 1 - opts.canvas_hotkey_brush_factor : 1 + opts.canvas_hotkey_brush_factor;
const currentRadius = parseFloat(input.value);
let delta = Math.sqrt(currentRadius ** 2 * brush_factor) - currentRadius;
// minimum brush size step of 1
if (Math.abs(delta) < 1) {
delta = deltaY > 0 ? -1 : 1;
}
const newValue = currentRadius + delta;
input.value = Math.max(newValue, 1);
input.dispatchEvent(new Event("change"));
}
}
}

// Undo the last brush stroke by clicking the undo button
function undoBrushStroke() {
gradioApp().querySelector(`${elemId} button[aria-label='Undo']`).click();
}

function clearCanvas() {
gradioApp().querySelector(`${elemId} button[aria-label='Clear']`).click();
}

// Reset zoom when uploading a new image
const fileInput = gradioApp().querySelector(
`${elemId} input[type="file"][accept="image/*"].svelte-116rqfv`
Expand Down Expand Up @@ -699,7 +728,9 @@ onUiLoaded(async() => {
[hotkeysConfig.canvas_hotkey_overlap]: toggleOverlap,
[hotkeysConfig.canvas_hotkey_fullscreen]: fitToScreen,
[hotkeysConfig.canvas_hotkey_shrink_brush]: () => adjustBrushSize(elemId, 10),
[hotkeysConfig.canvas_hotkey_grow_brush]: () => adjustBrushSize(elemId, -10)
[hotkeysConfig.canvas_hotkey_grow_brush]: () => adjustBrushSize(elemId, -10),
[hotkeysConfig.canvas_hotkey_undo]: undoBrushStroke,
[hotkeysConfig.canvas_hotkey_clear]: clearCanvas
};

const action = hotkeyActions[event.code];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@
from modules import shared

shared.options_templates.update(shared.options_section(('canvas_hotkey', "Canvas Hotkeys"), {
"canvas_hotkey_zoom": shared.OptionInfo("Alt", "Zoom canvas", gr.Radio, {"choices": ["Shift","Ctrl", "Alt"]}).info("If you choose 'Shift' you cannot scroll horizontally, 'Alt' can cause a little trouble in firefox"),
"canvas_hotkey_adjust": shared.OptionInfo("Ctrl", "Adjust brush size", gr.Radio, {"choices": ["Shift","Ctrl", "Alt"]}).info("If you choose 'Shift' you cannot scroll horizontally, 'Alt' can cause a little trouble in firefox"),
"canvas_hotkey_zoom": shared.OptionInfo("Alt", "Zoom canvas", gr.Radio, {"choices": ["Shift", "Ctrl", "Alt"]}).info("If you choose 'Shift' you cannot scroll horizontally, 'Alt' can cause a little trouble in firefox"),
"canvas_hotkey_adjust": shared.OptionInfo("Ctrl", "Adjust brush size", gr.Radio, {"choices": ["Shift", "Ctrl", "Alt"]}).info("If you choose 'Shift' you cannot scroll horizontally, 'Alt' can cause a little trouble in firefox"),
"canvas_hotkey_shrink_brush": shared.OptionInfo("Q", "Shrink the brush size"),
"canvas_hotkey_grow_brush": shared.OptionInfo("W", "Enlarge the brush size"),
"canvas_hotkey_move": shared.OptionInfo("F", "Moving the canvas").info("To work correctly in firefox, turn off 'Automatically search the page text when typing' in the browser settings"),
"canvas_hotkey_undo": shared.OptionInfo("Z", "Undo brush stroke"),
"canvas_hotkey_clear": shared.OptionInfo("C", "Clear canvas"),
"canvas_hotkey_fullscreen": shared.OptionInfo("S", "Fullscreen Mode, maximizes the picture so that it fits into the screen and stretches it to its full width "),
"canvas_hotkey_reset": shared.OptionInfo("R", "Reset zoom and canvas position"),
"canvas_hotkey_overlap": shared.OptionInfo("O", "Toggle overlap").info("Technical button, needed for testing"),
"canvas_show_tooltip": shared.OptionInfo(True, "Enable tooltip on the canvas"),
"canvas_auto_expand": shared.OptionInfo(True, "Automatically expands an image that does not fit completely in the canvas area, similar to manually pressing the S and R buttons"),
"canvas_blur_prompt": shared.OptionInfo(False, "Take the focus off the prompt when working with a canvas"),
"canvas_disabled_functions": shared.OptionInfo(["Overlap"], "Disable function that you don't use", gr.CheckboxGroup, {"choices": ["Zoom","Adjust brush size","Hotkey enlarge brush","Hotkey shrink brush","Moving canvas","Fullscreen","Reset Zoom","Overlap"]}),
"canvas_disabled_functions": shared.OptionInfo(["Overlap"], "Disable function that you don't use", gr.CheckboxGroup, {"choices": ["Zoom", "Adjust brush size", "Hotkey enlarge brush", "Hotkey shrink brush", "Undo", "Clear", "Moving canvas", "Fullscreen", "Reset Zoom", "Overlap"]}),
"canvas_hotkey_brush_factor": shared.OptionInfo(0.1, "Brush size change rate", gr.Slider, {"minimum": 0, "maximum": 1, "step": 0.01}).info('controls how much the brush size is changed when using hotkeys or scroll wheel'),
}))