您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Enlarges thumbnails to take up the whole screen and adds Up/Down arrow key navigation to instantly go to the next thumbnail. No more tired eyes from constantly moving your eyes from thumbnail to thumbnail.
// ==UserScript== // @name Civitai Larger Thumbnails + Arrow Key Navigation // @namespace Violentmonkey Scripts // @match *://*.civitai.com/* // @grant GM_addStyle // @version 1.21 // @author rainlizard // @license MIT // @description Enlarges thumbnails to take up the whole screen and adds Up/Down arrow key navigation to instantly go to the next thumbnail. No more tired eyes from constantly moving your eyes from thumbnail to thumbnail. // ==/UserScript== (function() { 'use strict'; let currentIndex = 0; let thumbnails = []; let isInitialized = false; // Function to wait for elements to appear function waitForElement(selector, timeout = 10000) { return new Promise((resolve, reject) => { const element = document.querySelector(selector); if (element) { resolve(element); return; } const observer = new MutationObserver((mutations, obs) => { const element = document.querySelector(selector); if (element) { obs.disconnect(); resolve(element); } }); observer.observe(document, { childList: true, subtree: true }); setTimeout(() => { observer.disconnect(); reject(new Error(`Element ${selector} not found within ${timeout}ms`)); }, timeout); }); } // Function to calculate optimal thumbnail height function calculateThumbnailHeight() { const viewportHeight = window.innerHeight; // Check for header height const headerSelectors = [ 'header', '[role="banner"]', '.header', '.navbar', 'nav:first-of-type' ]; let headerHeight = 0; for (const selector of headerSelectors) { const header = document.querySelector(selector); if (header) { const rect = header.getBoundingClientRect(); if (rect.top >= -10 && rect.height > 0) { headerHeight = Math.max(headerHeight, rect.height); } } } // Use full viewport height minus header return viewportHeight - headerHeight; } // Function to find all thumbnail cards directly function findThumbnails() { // Look for thumbnails by their specific structure const thumbnailElements = document.querySelectorAll('.AspectRatioImageCard_content__IGj_A'); // Get the parent containers (the actual thumbnail divs) const thumbnailContainers = Array.from(thumbnailElements).map(content => { // The parent should be the thumbnail container let parent = content.parentElement; // Look for the container with the aspect-ratio style or class structure while (parent && !parent.style.aspectRatio && !parent.classList.contains('relative')) { parent = parent.parentElement; } return parent; }).filter(Boolean); console.log(`Found ${thumbnailContainers.length} thumbnail containers`); return thumbnailContainers; } // Update thumbnail list function updateThumbnailList() { thumbnails = findThumbnails(); if (currentIndex >= thumbnails.length && thumbnails.length > 0) { currentIndex = thumbnails.length - 1; } else if (thumbnails.length === 0) { currentIndex = 0; } } // Function to update all thumbnail heights function updateThumbnailHeights() { const newHeight = calculateThumbnailHeight(); const heightValue = `${newHeight}px`; // Update CSS custom property document.documentElement.style.setProperty('--civitai-thumbnail-height', heightValue); // Update existing thumbnails thumbnails.forEach(thumbnail => { if (thumbnail.classList.contains('civitai-large-thumbnail')) { thumbnail.style.height = heightValue; thumbnail.style.minHeight = heightValue; } }); } // Apply CSS for large thumbnails GM_addStyle(` html, body { scroll-behavior: smooth !important; } body { overflow-x: hidden !important; } /* Container for thumbnails */ .civitai-thumbnail-container { display: flex !important; flex-direction: column !important; align-items: center !important; width: 100% !important; gap: 0px !important; } /* Large thumbnail styling */ .civitai-large-thumbnail { width: 100vw !important; max-width: 100% !important; height: var(--civitai-thumbnail-height, 100vh) !important; min-height: var(--civitai-thumbnail-height, 100vh) !important; display: flex !important; flex-direction: column !important; justify-content: center !important; align-items: center !important; padding: 20px !important; box-sizing: border-box !important; background-color: #1A1B1E !important; position: relative !important; margin: 0 !important; aspect-ratio: auto !important; border-radius: 0 !important; } /* Style the content area */ .civitai-large-thumbnail .AspectRatioImageCard_content__IGj_A { width: 100% !important; height: 100% !important; display: flex !important; flex-direction: column !important; justify-content: center !important; align-items: center !important; } /* Style the link */ .civitai-large-thumbnail .AspectRatioImageCard_linkOrClick__d_K_4 { width: 90% !important; height: 80% !important; display: flex !important; justify-content: center !important; align-items: center !important; } /* Style images within large thumbnails */ .civitai-large-thumbnail .AspectRatioImageCard_image__1xNTQ { max-width: 100vw !important; max-height: 100vh !important; width: auto !important; height: auto !important; object-fit: contain !important; border-radius: 8px !important; } /* Style the footer with no background */ .civitai-large-thumbnail .AspectRatioImageCard_footer__FOU7a { position: absolute !important; bottom: 20px !important; left: 20px !important; right: 20px !important; background: rgba(0, 0, 0, 0) !important; padding: 20px !important; border-radius: 10px !important; color: white !important; } /* Style the header with no background */ .civitai-large-thumbnail .AspectRatioImageCard_header__Mmd__ { position: absolute !important; top: 20px !important; right: 20px !important; background: rgba(0, 0, 0, 0) !important; padding: 10px !important; border-radius: 10px !important; } /* Navigation indicator */ .civitai-nav-indicator { position: fixed !important; bottom: 20px !important; right: 20px !important; background: rgba(0, 0, 0, 0.8) !important; color: white !important; padding: 10px 15px !important; border-radius: 5px !important; font-size: 14px !important; z-index: 1000 !important; font-family: Arial, sans-serif !important; opacity: 0.8 !important; } `); // Scroll to specific thumbnail function scrollToThumbnail(index) { updateThumbnailList(); if (index >= 0 && index < thumbnails.length) { currentIndex = index; const targetThumbnail = thumbnails[currentIndex]; if (targetThumbnail) { targetThumbnail.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' }); // Update navigation indicator const indicator = document.querySelector('.civitai-nav-indicator'); if (indicator) { indicator.textContent = `${currentIndex + 1} / ${thumbnails.length} - ↑↓ Navigate`; } } } } // Keyboard navigation document.addEventListener('keydown', function(e) { updateThumbnailList(); if (thumbnails.length === 0) return; if (e.key === 'ArrowDown') { e.preventDefault(); if (currentIndex < thumbnails.length - 1) { scrollToThumbnail(currentIndex + 1); } } else if (e.key === 'ArrowUp') { e.preventDefault(); if (currentIndex > 0) { scrollToThumbnail(currentIndex - 1); } } }); // Apply large thumbnail styling to all thumbnails function applyLargeThumbnailStyling() { updateThumbnailList(); if (thumbnails.length === 0) return; // Find the parent container and modify its layout const firstThumbnail = thumbnails[0]; const parentContainer = firstThumbnail.parentElement; if (parentContainer) { parentContainer.classList.add('civitai-thumbnail-container'); } // Apply styling to each thumbnail thumbnails.forEach(thumbnail => { thumbnail.classList.add('civitai-large-thumbnail'); }); // Update heights updateThumbnailHeights(); console.log(`Applied large styling to ${thumbnails.length} thumbnails`); } // Function to periodically check for new content function checkForUpdates() { const newThumbnails = findThumbnails(); if (newThumbnails.length !== thumbnails.length) { console.log(`Updated: Now have ${newThumbnails.length} thumbnails`); // Apply styling to new thumbnails newThumbnails.forEach(thumbnail => { if (!thumbnail.classList.contains('civitai-large-thumbnail')) { thumbnail.classList.add('civitai-large-thumbnail'); } }); thumbnails = newThumbnails; updateThumbnailHeights(); } } // Function to observe viewport changes function observeViewportChanges() { // Listen for window resize window.addEventListener('resize', () => { updateThumbnailHeights(); }); // Listen for scroll to detect header changes let scrollTimeout; window.addEventListener('scroll', () => { clearTimeout(scrollTimeout); scrollTimeout = setTimeout(() => { updateThumbnailHeights(); }, 100); }); } // Initialize the script function init() { console.log('Civitai Larger Thumbnails script loaded'); // Calculate initial height const initialHeight = calculateThumbnailHeight(); document.documentElement.style.setProperty('--civitai-thumbnail-height', `${initialHeight}px`); // Wait for the main content area to load waitForElement('#main') .then(() => { setTimeout(() => { applyLargeThumbnailStyling(); if (thumbnails.length > 0) { console.log(`Applied large styling to ${thumbnails.length} thumbnails`); // Add navigation indicator const indicator = document.createElement('div'); indicator.className = 'civitai-nav-indicator'; indicator.textContent = `1 / ${thumbnails.length} - ↑↓ Navigate`; document.body.appendChild(indicator); // Set up viewport observation observeViewportChanges(); isInitialized = true; } // Set up periodic checks for new content setInterval(checkForUpdates, 2000); }, 2000); }) .catch(error => { console.error('Civitai script: Failed to find main content area', error); }); } // Start initialization after a delay to ensure page is ready setTimeout(init, 1000); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址