Greasy Fork

Greasy Fork is available in English.

Bangumi 渐变生成器

在 Bangumi 文本框工具栏中添加渐变生成器

当前为 2024-11-01 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        Bangumi 渐变生成器
// @namespace    https://github.com/wakabayu
// @version      1.1
// @description  在 Bangumi 文本框工具栏中添加渐变生成器
// @include      /^https?:\/\/(bgm\.tv|chii\.in|bangumi\.tv)\/.*/
// @grant        none
// @license      wataame
// @author      wataame
// @homepage    https://bgm.tv/user/wataame
// ==/UserScript==

(function() {
    'use strict';

    // 添加渐变按钮到所有工具栏
    function addGradientButtonToAllToolbars() {
        document.querySelectorAll('.markItUpHeader').forEach(toolbar => {
            if (!toolbar.querySelector('.gradientButton')) {
                const gradientButton = document.createElement('a');
                gradientButton.href = 'javascript:void(0);';
                gradientButton.className = 'markItUpButton gradientButton';
                gradientButton.title = '生成渐变文字';
                gradientButton.innerHTML = '<span style="font-weight: bold; color: #0ebeff;">渐变</span>';
                toolbar.appendChild(gradientButton);

                const textarea = toolbar.closest('.markItUpContainer').querySelector('textarea');
                gradientButton.addEventListener('click', () => {
                    if (!textarea) return alert('找不到对应的文本区域');
                    const selectedText = textarea.value.substring(textarea.selectionStart, textarea.selectionEnd);
                    if (!selectedText) return alert('请先选中需要应用渐变的文字');
                    openColorPicker(selectedText, textarea);
                });
            }
        });
    }

    // 生成颜色选择器
    function openColorPicker(selectedText, textarea) {
        const colorPickerContainer = document.createElement('div');
        colorPickerContainer.style = "position:fixed;top:50%;left:50%;transform:translate(-50%, -50%);background:#fff;padding:20px;border:1px solid #ccc;z-index:9999;box-shadow:0 0 10px rgba(0,0,0,0.1)";

        colorPickerContainer.innerHTML = `
            <label>选择起始颜色:<input type="color" value="#0ebeff" id="startColor"></label><br>
            <label>选择结束颜色:<input type="color" value="#5e95e6" id="endColor"></label><br>
            <label>输入步数:<input type="number" min="1" value="${selectedText.length}" id="steps"></label><br>
            <button id="generate">生成</button> <button id="cancel">取消</button>
        `;
        document.body.appendChild(colorPickerContainer);

        document.querySelector('#generate').onclick = () => {
            const startColor = document.querySelector('#startColor').value;
            const endColor = document.querySelector('#endColor').value;
            const steps = parseInt(document.querySelector('#steps').value);
            if (isNaN(steps) || steps <= 0) return alert('请输入有效的步数');

            const gradientText = generateGradientText(selectedText, startColor, endColor, steps);
            const beforeText = textarea.value.substring(0, textarea.selectionStart);
            const afterText = textarea.value.substring(textarea.selectionEnd);
            textarea.value = beforeText + gradientText + afterText;
            document.body.removeChild(colorPickerContainer);
        };

        document.querySelector('#cancel').onclick = () => document.body.removeChild(colorPickerContainer);
    }

    // 生成渐变文字,按步数分段添加颜色
    function generateGradientText(text, startColor, endColor, steps) {
        const startRGB = hexToRgb(startColor), endRGB = hexToRgb(endColor);
        const segmentLength = Math.ceil(text.length / steps);
        let result = '';

        for (let i = 0; i < steps; i++) {
            const ratio = i / (steps - 1);
            const r = clamp(Math.round(startRGB.r + ratio * (endRGB.r - startRGB.r)));
            const g = clamp(Math.round(startRGB.g + ratio * (endRGB.g - startRGB.g)));
            const b = clamp(Math.round(startRGB.b + ratio * (endRGB.b - startRGB.b)));
            const color = `#${rgbToHex(r)}${rgbToHex(g)}${rgbToHex(b)}`;

            // 获取当前段的文本内容并应用颜色
            const segmentText = text.slice(i * segmentLength, (i + 1) * segmentLength);
            result += `[color=${color}]${segmentText}[/color]`;
        }
        return result;
    }

    // 将值限制在 0-255 范围内
    const clamp = value => Math.max(0, Math.min(255, value));

    // 十六进制转 RGB 和 RGB 转 十六进制
    const hexToRgb = hex => ({ r: parseInt(hex.slice(1, 3), 16), g: parseInt(hex.slice(3, 5), 16), b: parseInt(hex.slice(5, 7), 16) });
    const rgbToHex = value => value.toString(16).padStart(2, '0');

    // 使用 MutationObserver 确保所有工具栏加载后添加按钮
    new MutationObserver(() => addGradientButtonToAllToolbars()).observe(document.body, { childList: true, subtree: true });
})();