全局直角(保留圆形高性能版V2026)
2025-6-5
乱云飞
代码
// ==UserScript==
// @name 全局直角(修复内部图片圆形)000
// @namespace http://tampermonkey.net/
// @version 3.7
// @description 强制所有非圆形元素变为直角,保留圆形容器及其内部图片
// @author You
// @match http://*/*
// @match https://*/*
// @grant none
// @run-at document-start
// ==/UserScript==
(function() {
'use strict';
// 圆形元素选择器白名单
const CIRCULAR_SELECTORS = [
// 头像类
'[class*="avatar"]', '[class*="user-avatar"]', '[class*="profile-pic"]',
'.avatar', '.user-avatar', '.MuiAvatar-root', '.ant-avatar',
'img[class*="avatar"]', 'img[src*="avatar"]', 'img[src*="profile"]',
// 圆形装饰/图标类
'[class*="circle"]', '[class*="round"]', '.rounded-full', '.rounded-circle',
// 音乐播放器的唱片/CD封面容器(重点)
'.vg-disc-container', '.disc-container', '.cd-cover', '.album-cover',
'[class*="disc"]', '[class*="cd"]', '[class*="cover-art"]',
'.song-cover', '.music-cover', '.playlist-cover', '.vg-cover-container',
// 特定播放器
'.aplayer-pic', '.aplayer-cover', '.ncm-cover',
'.sakana-widget',
];
// 检查元素是否匹配圆形选择器白名单
function matchesCircularSelector(el) {
if (!el) return false;
for (const selector of CIRCULAR_SELECTORS) {
if (el.matches(selector)) return true;
}
// 模糊匹配类名中的关键词
const className = (el.className || '').toLowerCase();
if (className.includes('avatar') || className.includes('circle') ||
className.includes('round') || className.includes('disc') ||
className.includes('cover') || className.includes('album')) {
const rect = el.getBoundingClientRect();
if (rect.width > 0 && rect.height > 0) {
const style = window.getComputedStyle(el);
if (Math.abs(rect.width - rect.height) < 5 &&
(style.borderRadius === '50%' || style.borderRadius.includes('50%') ||
parseFloat(style.borderRadius) >= Math.min(rect.width, rect.height) / 2)) {
return true;
}
}
}
return false;
}
// 检查元素是否位于圆形容器内部(关键修复)
function isInsideCircularContainer(el) {
let parent = el.parentElement;
let level = 0;
// 向上查找最多5层,找到圆形容器
while (parent && level < 5) {
// 检查父元素是否匹配圆形选择器
if (matchesCircularSelector(parent)) return true;
// 检查父元素是否有圆形圆角样式
const style = window.getComputedStyle(parent);
const borderRadius = style.borderRadius;
if (borderRadius !== '0px' && borderRadius !== '0%' && borderRadius !== '') {
const rect = parent.getBoundingClientRect();
if (rect.width > 0 && rect.height > 0 && Math.abs(rect.width - rect.height) < 5) {
// 父元素是正方形且圆角足够大,判定为圆形容器
let radiusPx = 0;
if (borderRadius.includes('%')) {
radiusPx = Math.min(rect.width, rect.height) * (parseFloat(borderRadius) / 100);
} else if (borderRadius.includes('px')) {
radiusPx = parseFloat(borderRadius);
}
if (radiusPx >= Math.min(rect.width, rect.height) / 2 - 1) {
return true;
}
}
}
parent = parent.parentElement;
level++;
}
return false;
}
// 判断元素是否为图片且应该保持圆形
function isImageShouldKeepCircle(el) {
if (el.tagName !== 'IMG') return false;
// 如果图片在圆形容器内,应该保持圆形
if (isInsideCircularContainer(el)) return true;
// 如果图片本身匹配圆形选择器
if (matchesCircularSelector(el)) return true;
return false;
}
// 几何判断:是否为真圆形
function isPerfectCircle(el) {
const rect = el.getBoundingClientRect();
const width = rect.width;
const height = rect.height;
if (width === 0 || height === 0) return false;
if (Math.abs(width - height) > 2) return false;
const style = window.getComputedStyle(el);
const borderRadius = style.borderRadius;
if (borderRadius === '0px' || borderRadius === '0%') return false;
let radiusPx = 0;
if (borderRadius.includes('%')) {
radiusPx = Math.min(width, height) * (parseFloat(borderRadius) / 100);
} else if (borderRadius.includes('px')) {
radiusPx = parseFloat(borderRadius);
} else {
radiusPx = parseFloat(borderRadius);
}
return radiusPx >= Math.min(width, height) / 2 - 1;
}
// 判断是否应保留圆角(主函数)
function shouldKeepRadius(el) {
// 1. 白名单直接保留
if (matchesCircularSelector(el)) return true;
// 2. 圆形容器内部的图片,保留圆形
if (isImageShouldKeepCircle(el)) return true;
// 3. 几何正圆判断
if (isPerfectCircle(el)) return true;
return false;
}
// 强制非圆形元素变为直角
function makeSquareCorners() {
const allElements = document.querySelectorAll('*');
for (let i = 0; i < allElements.length; i++) {
const el = allElements[i];
if (el._radiusProcessed) continue;
const style = window.getComputedStyle(el);
const hasRadius = style.borderRadius !== '0px' && style.borderRadius !== '0%' && style.borderRadius !== '';
if (!hasRadius) {
el._radiusProcessed = true;
continue;
}
if (!shouldKeepRadius(el)) {
el.style.borderRadius = '0px';
el.style.setProperty('border-radius', '0px', 'important');
}
el._radiusProcessed = true;
}
}
// 初始化和动态监听
function init() {
makeSquareCorners();
let timer = null;
const observer = new MutationObserver(() => {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
const allEls = document.querySelectorAll('*');
for (let i = 0; i < allEls.length; i++) {
delete allEls[i]._radiusProcessed;
}
makeSquareCorners();
}, 150);
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();本文链接:
http://80c.cc/ez/869.html
发表评论: