Helpers for PixAI: Toggle between 4x1 and 2x2 layouts for the image grid, toggle the visibility of the right sidebar, and enable "Ctrl+Enter" for generating images.
当前为
// ==UserScript==
// @name PixAI UI Helpers
// @namespace http://yourname.tampermonkey.net/
// @version 1.3.3
// @description Helpers for PixAI: Toggle between 4x1 and 2x2 layouts for the image grid, toggle the visibility of the right sidebar, and enable "Ctrl+Enter" for generating images.
// @author Yada
// @match https://pixai.art/*
// @icon https://pixai.art/favicon.ico
// @grant none
// @license MIT
// @supportURL http://yoursupporturl.com/script.js
// ==/UserScript==
(function() {
'use strict';
let is2x2Layout = false;
let isRightBarCollapsed = false;
let buttonsAdded = false;
let isCtrlEnterEnabled = false;
let layoutInterval;
// Function to get the target element for grid layout
function getGridTargetElement() {
return document.querySelector('#workbench-layout main > div > div:nth-child(2) > div > div:nth-child(1)');
}
// Function to set the layout to 4x1
function setLayout4x1() {
const imageContainer = getGridTargetElement();
if (imageContainer) {
imageContainer.style.setProperty('--grid-cols', '4');
imageContainer.style.setProperty('--grid-rows', '1');
is2x2Layout = false;
}
}
// Function to set the layout to 2x2
function setLayout2x2() {
const imageContainer = getGridTargetElement();
if (imageContainer) {
imageContainer.style.setProperty('--grid-cols', '2');
imageContainer.style.setProperty('--grid-rows', '2');
is2x2Layout = true;
}
}
// Function to reapply the current layout
function reapplyLayout() {
if (is2x2Layout) {
setLayout2x2();
} else {
setLayout4x1();
}
}
// Function to toggle between layouts
function toggleLayout() {
is2x2Layout = !is2x2Layout;
reapplyLayout();
}
// Function to set right bar width to zero
function setRightBarWidthToZero() {
const workbenchLayout = document.querySelector('#workbench-layout');
if (workbenchLayout) {
workbenchLayout.style.gridTemplateColumns = 'min-content 1fr 0px';
isRightBarCollapsed = true;
}
}
// Function to restore the original width of the right bar
function restoreRightBarWidth() {
const workbenchLayout = document.querySelector('#workbench-layout');
if (workbenchLayout) {
workbenchLayout.style.gridTemplateColumns = 'min-content 1fr 380px';
isRightBarCollapsed = false;
}
}
// Function to toggle the right bar's visibility
function toggleRightBar() {
if (isRightBarCollapsed) {
restoreRightBarWidth();
} else {
setRightBarWidthToZero();
}
}
// Function to handle Ctrl+Enter key press for generating images
function handleCtrlEnter(event) {
if (event.ctrlKey && event.key === 'Enter') {
const generateButton = document.querySelector('[data-tutorial-target="generate-button"]');
if (generateButton) {
generateButton.click();
}
}
}
// Function to enable Ctrl+Enter for generating images
function enableCtrlEnter() {
if (!isCtrlEnterEnabled) {
document.addEventListener('keydown', handleCtrlEnter);
isCtrlEnterEnabled = true;
}
}
// Function to disable Ctrl+Enter for generating images
function disableCtrlEnter() {
if (isCtrlEnterEnabled) {
document.removeEventListener('keydown', handleCtrlEnter);
isCtrlEnterEnabled = false;
}
}
// Function to toggle Ctrl+Enter feature
function toggleCtrlEnter() {
if (isCtrlEnterEnabled) {
disableCtrlEnter();
} else {
enableCtrlEnter();
}
}
// Function to add the buttons
function addButtons() {
if (buttonsAdded) return;
// Create button container
const buttonContainer = document.createElement('div');
buttonContainer.id = 'pixai-ui-helpers-buttons';
buttonContainer.style.position = 'fixed';
buttonContainer.style.top = '10px';
buttonContainer.style.right = '10px';
buttonContainer.style.zIndex = '1000';
buttonContainer.style.display = 'flex';
buttonContainer.style.flexDirection = 'row';
buttonContainer.style.gap = '5px';
// Button styles
const buttonStyle = {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'transparent',
color: 'white',
fontFamily: 'Inter, sans-serif',
fontSize: '0.75rem',
fontWeight: '500',
textShadow: '0 1px 2px rgba(0, 0, 0, 0.5)',
padding: '0.25rem 0.5rem',
border: 'none',
borderRadius: '0.25rem',
cursor: 'pointer',
transition: 'background-color 0.3s',
};
// Create toggle layout button
const toggleLayoutButton = document.createElement('button');
toggleLayoutButton.textContent = 'Toggle Layout';
Object.assign(toggleLayoutButton.style, buttonStyle);
toggleLayoutButton.onclick = toggleLayout;
// Create toggle right bar button
const toggleRightBarButton = document.createElement('button');
toggleRightBarButton.textContent = 'Toggle Right Bar';
Object.assign(toggleRightBarButton.style, buttonStyle);
toggleRightBarButton.onclick = toggleRightBar;
// Create toggle Ctrl+Enter button
const toggleCtrlEnterButton = document.createElement('button');
toggleCtrlEnterButton.textContent = 'Enable Ctrl+Enter';
Object.assign(toggleCtrlEnterButton.style, buttonStyle);
toggleCtrlEnterButton.onclick = function() {
toggleCtrlEnter();
toggleCtrlEnterButton.textContent = isCtrlEnterEnabled ? 'Disable Ctrl+Enter' : 'Enable Ctrl+Enter';
};
// Append buttons to container
buttonContainer.appendChild(toggleCtrlEnterButton);
buttonContainer.appendChild(toggleLayoutButton);
buttonContainer.appendChild(toggleRightBarButton);
// Append button container to body
document.body.appendChild(buttonContainer);
buttonsAdded = true;
// Start interval to reapply layout every 0.1 seconds
layoutInterval = setInterval(reapplyLayout, 100);
}
// Function to remove the buttons and clear the interval
function removeButtons() {
const buttonContainer = document.querySelector('#pixai-ui-helpers-buttons');
if (buttonContainer) {
buttonContainer.remove();
buttonsAdded = false;
}
if (layoutInterval) {
clearInterval(layoutInterval);
layoutInterval = null;
}
}
// Function to monitor URL changes and add/remove buttons accordingly
function monitorURLChanges() {
const currentURL = window.location.href;
if (currentURL.includes('/generator/')) {
addButtons();
} else {
removeButtons();
disableCtrlEnter(); // Ensure Ctrl+Enter is disabled when leaving the page
}
}
// Monitor for history changes (when navigating between pages using internal links)
window.addEventListener('popstate', monitorURLChanges);
// Monitor for pushState changes (when navigating between pages using internal links)
const originalPushState = history.pushState;
history.pushState = function() {
originalPushState.apply(this, arguments);
monitorURLChanges();
};
// Initial check to add/remove buttons based on the current page
monitorURLChanges();
})();