Greasy Fork

Greasy Fork is available in English.

ArtStation项目图片4K加载

将ArtStation项目中的图片强制替换为4K版本

// ==UserScript==
// @name        ArtStation项目图片4K加载
// @namespace   artstation-project-4k
// @match       https://www.artstation.com/*
// @description 将ArtStation项目中的图片强制替换为4K版本
// @version     1.4
// @grant       none
// @run-at      document-end
// @license     MIT
// ==/UserScript==

(function() {
    'use strict';

    // 构建4K图片URL(移除查询参数)
    function build4kUrl(originalUrl) {
        // 移除查询参数
        const baseUrl = originalUrl.split('?')[0];

        // 替换尺寸为4k
        return baseUrl.replace(/\/(large|medium|small)\//, '/4k/');
    }

    // 升级单个图片元素
    function upgradeProjectImage(imgElement) {
        const originalSrc = imgElement.src || imgElement.getAttribute('data-src') || '';

        // 只处理artstation的CDN图片
        if (!originalSrc.includes('artstation.com/p/assets/images/images/')) {
            return;
        }

        const newSrc = build4kUrl(originalSrc);

        // 更新属性
        if (imgElement.hasAttribute('data-src')) {
            imgElement.setAttribute('data-src', newSrc);
        }
        imgElement.src = newSrc;

        // 错误处理(保留原始图片)
        imgElement.onerror = function() {
            console.warn('4K加载失败,恢复原图:', originalSrc);
            imgElement.src = originalSrc;
            imgElement.onerror = null;
        };

        console.log('升级为4K:', newSrc);
    }

    // 主处理函数
    function processProjectAssets() {
        // 精确查找<project-asset>下的<picture>中的<img>
        document.querySelectorAll('project-asset picture img').forEach(upgradeProjectImage);
    }

    // 初始执行
    processProjectAssets();

    // 使用MutationObserver监听DOM变化
    const observer = new MutationObserver(function(mutations) {
        let needsUpdate = false;
        mutations.forEach(function(mutation) {
            if (mutation.addedNodes.length) {
                mutation.addedNodes.forEach(function(node) {
                    if (node.nodeType === 1 &&
                        (node.matches('project-asset') ||
                         node.querySelector('project-asset'))) {
                        needsUpdate = true;
                    }
                });
            }
        });

        if (needsUpdate) {
            setTimeout(processProjectAssets, 300);
        }
    });

    // 开始观察
    observer.observe(document, {
        childList: true,
        subtree: true
    });

    // 添加样式优化
    const style = document.createElement('style');
    style.textContent = `
        project-asset picture img {
            max-width: none !important;
            max-height: none !important;
            cursor: zoom-in;
            transition: transform 0.2s ease;
        }
        project-asset picture img:hover {
            transform: scale(1.01);
            z-index: 100;
        }
        /* 移除ArtStation的遮罩层 */
        project-asset .image-mask {
            display: none !important;
        }
    `;
    document.head.appendChild(style);

    // 监听SPA路由变化
    let lastUrl = location.href;
    const checkPageChange = function() {
        if (location.href !== lastUrl) {
            lastUrl = location.href;
            setTimeout(processProjectAssets, 1000);
        }
    };

    setInterval(checkPageChange, 500);
    window.addEventListener('popstate', checkPageChange);
    window.addEventListener('pushState', checkPageChange);
    window.addEventListener('replaceState', checkPageChange);
})();