您需要先安装一个扩展,例如 篡改猴、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(); } })();