Enlarge YouTube Chat Profile Pictures (HD Version with Caching)

Enlarges YouTube chat profile pictures on mouse over, shows HD version, Caches HD images for faster display using Tampermonkey caching.

安裝腳本?
作者推薦腳本

您可能也會喜歡 YouTubeTV Volume Control with Memory

安裝腳本
  1. // ==UserScript==
  2. // @name Enlarge YouTube Chat Profile Pictures (HD Version with Caching)
  3. // @namespace typpi.online
  4. // @version 2.1
  5. // @description Enlarges YouTube chat profile pictures on mouse over, shows HD version, Caches HD images for faster display using Tampermonkey caching.
  6. // @author Nick2bad4u
  7. // @match https://www.youtube.com/*
  8. // @grant GM_setValue
  9. // @grant GM_getValue
  10. // @grant GM_addStyle
  11. // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
  12. // @license UnLicense
  13. // @tag youtube
  14. // ==/UserScript==
  15.  
  16. (function () {
  17. 'use strict';
  18.  
  19. let debounceTimeout;
  20. const CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours in milliseconds
  21. const preloadedImages = new Map();
  22.  
  23. // Load cache from Tampermonkey storage
  24. function loadCache() {
  25. const cache = GM_getValue('profilePicCache', {});
  26. const now = Date.now();
  27. // Clear out expired cache entries
  28. Object.keys(cache).forEach((key) => {
  29. if (now - cache[key].timestamp > CACHE_TTL_MS) {
  30. delete cache[key]; // Remove expired entry
  31. }
  32. });
  33. GM_setValue('profilePicCache', cache); // Update cache after removing expired entries
  34. return cache;
  35. }
  36.  
  37. // Save cache to Tampermonkey storage
  38. function saveCache(cache) {
  39. GM_setValue('profilePicCache', cache);
  40. }
  41.  
  42. let cache = loadCache(); // Load the cache once when the script runs
  43.  
  44. // Preload HD image
  45. function preloadHDImage(src) {
  46. const hdSrc = src.replace(/=s32-c/, '=s800-c'); // Adjust as needed for HD
  47. if (!preloadedImages.has(hdSrc)) {
  48. if (cache[hdSrc]) {
  49. // If in persistent cache, load directly from cache
  50. preloadedImages.set(hdSrc, cache[hdSrc].url);
  51. } else {
  52. // Preload HD image and store in cache
  53. const img = new Image();
  54. img.src = hdSrc;
  55. preloadedImages.set(hdSrc, hdSrc); // Store in memory
  56. cache[hdSrc] = {
  57. url: hdSrc,
  58. timestamp: Date.now(),
  59. }; // Cache with timestamp
  60. saveCache(cache); // Save the updated cache
  61. }
  62. }
  63. }
  64.  
  65. // Function to enlarge profile pictures, show HD image, add black outline, and shift to the right
  66. function enlargeProfilePic(event) {
  67. clearTimeout(debounceTimeout);
  68. debounceTimeout = setTimeout(() => {
  69. const img = event.target;
  70. const originalSrc = img.src;
  71. const hdSrc = originalSrc.replace(/=s32-c/, '=s800-c'); // Increase the size to 800px
  72. img.dataset.originalSrc = originalSrc; // Store the original src
  73. // Swap in the HD version, check preloadedImages cache
  74. img.src = preloadedImages.get(hdSrc) || hdSrc;
  75. img.style.transform = 'scale(6) translateX(20px)';
  76. img.style.transition = 'transform 0.2s ease';
  77. img.style.border = '1px solid black';
  78. img.style.zIndex = '9999';
  79. img.style.position = 'relative';
  80. // Reset after 3 seconds
  81. setTimeout(() => {
  82. resetProfilePic(img);
  83. }, 3000);
  84. }, 100);
  85. }
  86.  
  87. // Function to reset profile pictures to original size and source
  88. function resetProfilePic(img) {
  89. img.src = img.dataset.originalSrc || img.src; // Restore the original src if it was replaced
  90. img.style.transform = 'scale(1) translateX(0)';
  91. img.style.border = 'none';
  92. img.style.zIndex = 'auto';
  93. img.style.position = 'static';
  94. }
  95.  
  96. // Add event listeners to profile pictures
  97. function addEventListeners() {
  98. const profilePics = document.querySelectorAll(
  99. '.h-5.w-5.inline.align-middle.rounded-full.flex-none',
  100. );
  101. profilePics.forEach((pic) => {
  102. preloadHDImage(pic.src); // Preload HD image
  103. pic.addEventListener('mouseover', enlargeProfilePic);
  104. });
  105. }
  106.  
  107. // Observe changes in the chat to dynamically add event listeners
  108. const observer = new MutationObserver(() => {
  109. addEventListeners();
  110. });
  111. observer.observe(document.body, {
  112. childList: true,
  113. subtree: true,
  114. });
  115.  
  116. // Initial call to add event listeners
  117. addEventListeners();
  118. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址