// ==UserScript==
// @name 图像风格切换器
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 给移动端图片添加多种滤镜风格,用户通过菜单输入编号调整喜欢的效果
// @author You
// @match *://*/*
// @grant GM_addStyle
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @run-at document-end
// ==/UserScript==
/*
* 图像风格切换器 - 风格指南
*
* 通过Tampermonkey菜单,您可以为移动端图片选择以下风格:
*
* 1. **复古怀旧 (Sepia)**: 图片呈现旧照片般的棕黄色调,并带有圆角和阴影效果。鼠标悬停时效果更强烈,并有轻微旋转放大。
* 2. **整体模糊 (Blur)**: 图片整体变得模糊,鼠标悬停时模糊度略有降低。
* 3. **黑白经典 (Grayscale)**: 图片呈现纯黑白效果,鼠标悬停时恢复部分色彩。
* 4. **颜色反转 (Invert)**: 图片颜色完全反转,呈现负片效果,鼠标悬停时反转程度减半。
* 5. **饱和度调整 (Saturate)**: 图片颜色饱和度降低一半,鼠标悬停时颜色变得非常鲜艳。
* 6. **色相旋转 (Hue-Rotate)**: 图片色相旋转90度,呈现独特的色彩偏移,鼠标悬停时色相旋转180度。
* 7. **投影效果 (Drop-Shadow)**: 图片下方和右侧出现明显的阴影,鼠标悬停时阴影变得更小、更深。
* 8. **透明度调整 (Opacity)**: 图片变为半透明(70%不透明度),鼠标悬停时完全不透明。
* 9. **圆形裁剪 (Circular Crop)**: 图片被裁剪成圆形,鼠标悬停时轻微放大。
* 10. **镜像翻转 (Mirror Flip)**: 图片水平翻转,呈现镜像效果,鼠标悬停时恢复正常。
* 11. **动画旋转 (Animated Rotate)**: 图片持续缓慢旋转360度。
* 12. **复古胶片 (Vintage Film)**: 图片呈现复古色调,并模拟胶片颗粒效果(需有效图片数据支持)。鼠标悬停时复古效果更深。
* 13. **倾斜效果 (Skew)**: 图片以一定角度倾斜,鼠标悬停时恢复正常。
* 14. **亮度增强 (Brightness)**: 图片亮度显著提高,鼠标悬停时亮度略有降低。
* 15. **新拟物风格 (Neumorphism)**: 图片呈现凹凸感,模拟物理按钮的立体效果,鼠标悬停时凹凸感反转。
*/
(function () {
'use strict';
// 定义存储风格编号的键
const STYLE_INDEX_KEY = 'imageStyleIndex';
// 默认风格编号,如果用户未设置过
const DEFAULT_STYLE_INDEX = 1;
// 获取当前风格编号,如果未设置则使用默认值
let currentStyleIndex = GM_getValue(STYLE_INDEX_KEY, DEFAULT_STYLE_INDEX);
// 样式数组
const styles = [
`
/* 风格 1: 默认复古风格 */
img {
filter: sepia(60%) brightness(1.1) contrast(1.2) saturate(1.2);
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
transition: all 0.3s ease;
}
img:hover {
filter: sepia(80%) brightness(1.2) contrast(1.3);
transform: scale(1.05) rotate(-2deg);
}
`,
`
/* 风格 2: 模糊效果 */
img {
filter: blur(5px);
transition: filter 0.3s ease;
}
img:hover {
filter: blur(3px);
}
`,
`
/* 风格 3: 黑白效果 */
img {
filter: grayscale(100%);
transition: filter 0.3s ease;
}
img:hover {
filter: grayscale(50%);
}
`,
`
/* 风格 4: 反转颜色 */
img {
filter: invert(100%);
transition: filter 0.3s ease;
}
img:hover {
filter: invert(50%);
}
`,
`
/* 风格 5: 饱和度调整 */
img {
filter: saturate(50%);
transition: filter 0.3s ease;
}
img:hover {
filter: saturate(150%);
}
`,
`
/* 风格 6: 色相旋转 */
img {
filter: hue-rotate(90deg);
transition: filter 0.3s ease;
}
img:hover {
filter: hue-rotate(180deg);
}
`,
`
/* 风格 7: 阴影效果 */
img {
filter: drop-shadow(10px 10px 15px rgba(0, 0, 0, 0.5));
transition: all 0.3s ease;
}
img:hover {
filter: drop-shadow(5px 5px 10px rgba(0, 0, 0, 0.7));
}
`,
`
/* 风格 8: 透明度调整 */
img {
filter: opacity(0.7);
transition: filter 0.3s ease;
}
img:hover {
filter: opacity(1);
}
`,
`
/* 风格 9: 圆形裁剪 */
img {
border-radius: 50%;
transition: transform 0.3s ease;
}
img:hover {
transform: scale(1.1);
}
`,
`
/* 风格 10: 镜像翻转 */
img {
transform: scaleX(-1);
transition: transform 0.3s ease;
}
img:hover {
transform: scaleX(1);
}
`,
`
/* 风格 11: 动画旋转 */
img {
animation: rotate 3s infinite linear;
}
@keyframes rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
`,
`
/* 风格 12: 复古 + 胶片颗粒 */
img {
filter: sepia(50%) contrast(1.2) brightness(1.1);
/* 注意:这里的 base64 编码的图片数据需要是实际的图片,否则可能无效 */
/* 示例:background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAABgLZcDAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iV0FNcHBhcmFwZW5kZXJfaWRlYU5hcmNvZmFtZSI+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQ1IDc5LjE2MzQ5OSwgMjAxOC8wOC8xMy0xNjowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYmRz.com/xap/1.0/” xmpMM:OriginalDocumentID=”xmp.did:4dad5792-196b-3446-8ec1-c56cc69810b4” xmpMM:DocumentID=”BE35E693B92B0418BF082C9E948A9719″ xmpMM:InstanceID=”F2A50189711E6211FCDBC35C7F17F4173″> <stRef:documentID>xmp.did:4dad5792-196b-3446-8ec1-c56cc69810b4</stRef:documentID> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end=”w”?>O60AAAAaSURBVHjaYmBgYGBgYMDAwMDAAAEEAAsABxUABlYFwLgAAAAASUVORK5CYII=') repeat; */
mix-blend-mode: multiply;
transition: all 0.3s ease;
}
img:hover {
filter: sepia(70%) contrast(1.4) brightness(1.2);
}
`,
`
/* 风格 13: 倾斜效果 */
img {
transform: skew(10deg, 5deg);
transition: transform 0.3s ease;
}
img:hover {
transform: skew(0deg, 0deg);
}
`,
`
/* 风格 14: 亮度增强 */
img {
filter: brightness(1.5);
transition: filter 0.3s ease;
}
img:hover {
filter: brightness(1.2);
}
`,
`
/* 风格 15: 新拟物风格 */
img {
box-shadow: 10px 10px 20px rgba(0, 0, 0, 0.2),
-10px -10px 20px rgba(255, 255, 255, 0.5);
border-radius: 12px;
transition: box-shadow 0.3s ease;
}
img:hover {
box-shadow: inset 10px 10px 20px rgba(0, 0, 0, 0.2),
inset -10px -10px 20px rgba(255, 255, 255, 0.5);
}
`
];
// --- 功能函数 ---
// 应用选定的风格
function applyStyle(index) {
// 确保索引在有效范围内
if (index >= 1 && index <= styles.length) {
// 移除旧的样式(如果存在),以避免冲突
const existingStyle = document.getElementById('tampermonkey-image-style');
if (existingStyle) {
existingStyle.remove();
}
// 应用新的样式
const styleElement = GM_addStyle(styles[index - 1]);
styleElement.id = 'tampermonkey-image-style'; // 给样式元素一个ID方便移除
console.log(`图片风格已切换至: 风格 ${index}`);
} else {
console.warn(`无效的风格编号: ${index}。请选择 1 到 ${styles.length} 之间的编号。`);
}
}
// 注册油猴菜单命令
function registerStyleChanger() {
GM_registerMenuCommand(`当前图片风格: 风格 ${currentStyleIndex}`, () => {
let newStyle = prompt(`请输入您想应用的图片风格编号 (1 到 ${styles.length} 之间):`, currentStyleIndex);
if (newStyle !== null) { // 用户点击了确定
newStyle = parseInt(newStyle, 10);
if (!isNaN(newStyle) && newStyle >= 1 && newStyle <= styles.length) {
GM_setValue(STYLE_INDEX_KEY, newStyle); // 保存新值
currentStyleIndex = newStyle; // 更新当前值
applyStyle(currentStyleIndex); // 立即应用新风格
alert(`图片风格已成功更新为: 风格 ${currentStyleIndex}。`);
} else {
alert(`输入无效。请输入 1 到 ${styles.length} 之间的有效数字。`);
}
}
});
}
// --- 主执行逻辑 ---
// 判断是否是移动端设备
// 这里使用简单的屏幕宽度判断,如果需要更精确的移动端判断,可以考虑User-Agent等
if (window.innerWidth <= 800) {
applyStyle(currentStyleIndex); // 页面加载时应用保存的或默认的风格
registerStyleChanger(); // 注册菜单命令
}
})();