您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds multiple prompt copy buttons in a compact, draggable floating menu with prompt management on Civitai's generate page
- // ==UserScript==
- // @name Civitai Multiple Prompt Copy Buttons (with Prompt Management)
- // @namespace http://tampermonkey.net/
- // @version 4.0
- // @description Adds multiple prompt copy buttons in a compact, draggable floating menu with prompt management on Civitai's generate page
- // @match https://civitai.com/generate
- // @grant GM_setClipboard
- // @grant GM_addStyle
- // @grant GM_setValue
- // @grant GM_getValue
- // @license MIT
- // ==/UserScript==
- (function() {
- 'use strict';
- let prompts = GM_getValue("savedPrompts", {
- 'Ryuko': "matoi ryuuko, kill la kill, 1girl, black hair, blue eyes, medium hair, multicolored hair, red hair, streaked hair, two-tone hair",
- 'Low angle': "from below, low angle, ground level",
- 'High angle': "from above, high angle",
- 'Kuroneko': "in the style of Kanzaki Hiro, 1girl, gokou ruri, black hair, blush, hairclip, hairband, hime cut, purple eyes, hair flower, hair ornament, hairclip, red eyes",
- 'Toki': "toki (blue archive), blue archive, 1girl, blonde hair, blue eyes, blue hairband, blue halo, hairband, halo, solo",
- 'Oily': "wet, wet skin, shiny, shiny skin, glossy, glossy skin, oil, oily, oily skin, sweat, sweaty, sweaty skin",
- 'Dark': "dark-skinned female, dark skin, tan, tanline",
- 'Blonde': "blonde hair, hime cut, long hair, straight hair, hairband"
- });
- const colors = ['#8B0000', '#00008B', '#8B008B', '#006400', '#008B8B', '#8B4500', '#8B8B00'];
- GM_addStyle(`
- #prompt-buttons-container {
- position: fixed;
- z-index: 9999;
- background-color: rgba(26,26,26,0.9);
- border-radius: 8px;
- box-shadow: 0 2px 10px rgba(0,0,0,0.3);
- font-family: Arial, sans-serif;
- width: 240px;
- display: flex;
- flex-direction: column;
- }
- #drag-handle {
- height: 24px;
- background-color: #2a2a2a;
- border-top-left-radius: 8px;
- border-top-right-radius: 8px;
- cursor: move;
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 0 8px;
- }
- #buttons-grid {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- gap: 4px;
- padding: 4px;
- max-height: 300px;
- overflow-y: auto;
- }
- .prompt-button, #show-hide-btn, #manage-btn {
- padding: 6px;
- color: white;
- border: none;
- cursor: pointer;
- font-size: 11px;
- font-weight: bold;
- transition: all 0.2s;
- text-align: center;
- border-radius: 4px;
- }
- .prompt-button:hover, #show-hide-btn:hover, #manage-btn:hover {
- filter: brightness(1.2);
- transform: translateY(-1px);
- }
- #show-hide-btn, #manage-btn {
- background-color: #4a4a4a;
- width: 50px;
- }
- #pin-btn {
- cursor: pointer;
- color: #fff;
- font-size: 14px;
- background: none;
- border: none;
- padding: 0;
- }
- #manage-panel {
- display: none;
- padding: 8px;
- background-color: #2a2a2a;
- }
- #manage-panel input, #manage-panel textarea {
- width: 100%;
- margin-bottom: 4px;
- padding: 4px;
- }
- #manage-panel button {
- margin-right: 4px;
- margin-bottom: 4px;
- }
- `);
- function createButton(name, prompt, color) {
- const button = document.createElement('button');
- button.className = 'prompt-button';
- button.textContent = name;
- button.style.backgroundColor = color;
- button.onclick = (e) => {
- e.stopPropagation();
- GM_setClipboard(prompt);
- const originalText = button.textContent;
- button.textContent = 'Copied!';
- setTimeout(() => button.textContent = originalText, 1000);
- };
- return button;
- }
- function makeDraggable(container, handle) {
- let isDragging = false;
- let startX, startY, startLeft, startTop;
- handle.addEventListener('mousedown', startDragging);
- document.addEventListener('mousemove', drag);
- document.addEventListener('mouseup', stopDragging);
- function startDragging(e) {
- isDragging = true;
- startX = e.clientX;
- startY = e.clientY;
- startLeft = parseInt(container.style.left) || 0;
- startTop = parseInt(container.style.top) || 0;
- e.preventDefault();
- }
- function drag(e) {
- if (!isDragging) return;
- if (container.dataset.pinned === 'true') return;
- const deltaX = e.clientX - startX;
- const deltaY = e.clientY - startY;
- container.style.left = `${startLeft + deltaX}px`;
- container.style.top = `${startTop + deltaY}px`;
- savePosition(startLeft + deltaX, startTop + deltaY);
- }
- function stopDragging() {
- isDragging = false;
- }
- }
- function savePosition(x, y) {
- GM_setValue("containerX", x);
- GM_setValue("containerY", y);
- }
- function loadPosition(container) {
- const x = GM_getValue("containerX", window.innerWidth - 260);
- const y = GM_getValue("containerY", window.innerHeight - 300);
- container.style.left = `${x}px`;
- container.style.top = `${y}px`;
- }
- function updateButtonsGrid() {
- const buttonGrid = document.getElementById('buttons-grid');
- buttonGrid.innerHTML = '';
- Object.entries(prompts).forEach(([name, prompt], index) => {
- const button = createButton(name, prompt, colors[index % colors.length]);
- buttonGrid.appendChild(button);
- });
- GM_setValue("savedPrompts", prompts);
- }
- function addPromptButtons() {
- const container = document.createElement('div');
- container.id = 'prompt-buttons-container';
- const dragHandle = document.createElement('div');
- dragHandle.id = 'drag-handle';
- const showHideBtn = document.createElement('button');
- showHideBtn.id = 'show-hide-btn';
- showHideBtn.textContent = 'Hide';
- showHideBtn.onclick = toggleButtons;
- const manageBtn = document.createElement('button');
- manageBtn.id = 'manage-btn';
- manageBtn.textContent = 'Manage';
- manageBtn.onclick = toggleManagePanel;
- const pinBtn = document.createElement('button');
- pinBtn.id = 'pin-btn';
- pinBtn.innerHTML = '📌';
- pinBtn.onclick = togglePin;
- dragHandle.appendChild(showHideBtn);
- dragHandle.appendChild(manageBtn);
- dragHandle.appendChild(pinBtn);
- const buttonGrid = document.createElement('div');
- buttonGrid.id = 'buttons-grid';
- const managePanel = createManagePanel();
- container.appendChild(dragHandle);
- container.appendChild(buttonGrid);
- container.appendChild(managePanel);
- document.body.appendChild(container);
- updateButtonsGrid();
- makeDraggable(container, dragHandle);
- loadPosition(container);
- }
- function toggleButtons() {
- const buttonGrid = document.getElementById('buttons-grid');
- const showHideBtn = document.getElementById('show-hide-btn');
- if (buttonGrid.style.display === 'none') {
- buttonGrid.style.display = 'grid';
- showHideBtn.textContent = 'Hide';
- } else {
- buttonGrid.style.display = 'none';
- showHideBtn.textContent = 'Show';
- }
- }
- function togglePin() {
- const container = document.getElementById('prompt-buttons-container');
- const pinBtn = document.getElementById('pin-btn');
- if (container.dataset.pinned === 'true') {
- delete container.dataset.pinned;
- pinBtn.style.opacity = '1';
- } else {
- container.dataset.pinned = 'true';
- pinBtn.style.opacity = '0.5';
- }
- }
- function toggleManagePanel() {
- const managePanel = document.getElementById('manage-panel');
- managePanel.style.display = managePanel.style.display === 'none' ? 'block' : 'none';
- }
- function createManagePanel() {
- const panel = document.createElement('div');
- panel.id = 'manage-panel';
- panel.style.display = 'none';
- const nameInput = document.createElement('input');
- nameInput.placeholder = 'Prompt Name';
- const promptInput = document.createElement('textarea');
- promptInput.placeholder = 'Prompt Text';
- const addButton = document.createElement('button');
- addButton.textContent = 'Add';
- addButton.onclick = () => {
- if (nameInput.value && promptInput.value) {
- prompts[nameInput.value] = promptInput.value;
- updateButtonsGrid();
- nameInput.value = '';
- promptInput.value = '';
- }
- };
- const editButton = document.createElement('button');
- editButton.textContent = 'Edit';
- editButton.onclick = () => {
- if (nameInput.value && promptInput.value && prompts.hasOwnProperty(nameInput.value)) {
- prompts[nameInput.value] = promptInput.value;
- updateButtonsGrid();
- }
- };
- const removeButton = document.createElement('button');
- removeButton.textContent = 'Remove';
- removeButton.onclick = () => {
- if (prompts.hasOwnProperty(nameInput.value)) {
- delete prompts[nameInput.value];
- updateButtonsGrid();
- nameInput.value = '';
- promptInput.value = '';
- }
- };
- panel.appendChild(nameInput);
- panel.appendChild(promptInput);
- panel.appendChild(addButton);
- panel.appendChild(editButton);
- panel.appendChild(removeButton);
- return panel;
- }
- if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', addPromptButtons);
- } else {
- addPromptButtons();
- }
- })();