🏠 返回首頁 

Greasy Fork is available in English.

Twitch Edge Light Effect with Gradient

Эффект подсветки краёв экрана на Twitch с корректной ориентацией градиента

  1. // ==UserScript==
  2. // @name Twitch Edge Light Effect with Gradient
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.7
  5. // @description Эффект подсветки краёв экрана на Twitch с корректной ориентацией градиента
  6. // @author Kislyy404
  7. // @match *://www.twitch.tv/*
  8. // @grant none
  9. // @icon https://i.pinimg.com/736x/9b/ca/9b/9bca9beab731e58a8b08854f2c41c8bc.jpg
  10. // @license CC BY-NC 4.0
  11. // ==/UserScript==
  12. // Creative Commons Attribution-NonCommercial 4.0 International License
  13. //
  14. // You are free to:
  15. // - Share — copy and redistribute the material in any medium or format
  16. // - Adapt — remix, transform, and build upon the material
  17. //
  18. // Under the following terms:
  19. // - Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
  20. // - NonCommercial — You may not use the material for commercial purposes.
  21. //
  22. // No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
  23. (function() {
  24. 'use strict';
  25. // Настройки
  26. const settings = {
  27. edgeWidth: 70, // Ширина края для анализа (в пикселях) Width of the edge to analyze (in pixels)
  28. brightnessFactor: 1, // Множитель яркости // Brightness multiplier
  29. updateInterval: 10, // Интервал обновления эффекта (в миллисекундах) // Effect refresh interval (in milliseconds)
  30. blurStrength: 16, // Сила размытия (в пикселях) // Basic opacity of the effect // Blur strength (in pixels)
  31. baseOpacity: 0.8, // Базовая непрозрачность эффекта // Basic effect opacity
  32. };
  33. function addStyles() {
  34. const style = document.createElement('style');
  35. style.type = 'text/css';
  36. style.innerHTML = `
  37. .video-player__container {
  38. position: relative;
  39. overflow: hidden;
  40. border: none !important;
  41. }
  42. .dynamic-light-effect {
  43. position: absolute;
  44. left: 0;
  45. right: 0;
  46. pointer-events: none;
  47. z-index: 1;
  48. filter: blur(${settings.blurStrength}px);
  49. opacity: ${settings.baseOpacity};
  50. transition: opacity 0.5s ease, background 0.5s ease;
  51. }
  52. .dynamic-light-effect.top {
  53. top: 0;
  54. height: ${settings.edgeWidth * 2}px;
  55. background-size: 100% ${settings.edgeWidth * 2}px;
  56. }
  57. .dynamic-light-effect.bottom {
  58. bottom: 0;
  59. height: ${settings.edgeWidth * 2}px;
  60. background-size: 100% ${settings.edgeWidth * 2}px;
  61. }
  62. video {
  63. position: relative;
  64. z-index: 2;
  65. border: none !important;
  66. }
  67. .video-player__overlay {
  68. position: relative;
  69. z-index: 3;
  70. }
  71. `;
  72. document.head.appendChild(style);
  73. }
  74. function createLightEffect() {
  75. const videoContainer = document.querySelector('.video-player__container');
  76. if (!videoContainer) return;
  77. const topEffect = document.createElement('div');
  78. topEffect.classList.add('dynamic-light-effect', 'top');
  79. videoContainer.appendChild(topEffect);
  80. const bottomEffect = document.createElement('div');
  81. bottomEffect.classList.add('dynamic-light-effect', 'bottom');
  82. videoContainer.appendChild(bottomEffect);
  83. const videoElement = document.querySelector('video');
  84. if (!videoElement) return;
  85. const canvas = document.createElement('canvas');
  86. const ctx = canvas.getContext('2d');
  87. function updateLightEffect() {
  88. if (!videoElement || videoElement.readyState < 2) return;
  89. // Получаем размеры видео и контейнера
  90. const videoRect = videoElement.getBoundingClientRect();
  91. const containerRect = videoContainer.getBoundingClientRect();
  92. // Вычисляем соотношение размеров видео и контейнера
  93. const scaleX = videoRect.width / videoElement.videoWidth;
  94. const scaleY = videoRect.height / videoElement.videoHeight;
  95. // Устанавливаем размер canvas под размер видео
  96. canvas.width = videoElement.videoWidth;
  97. canvas.height = videoElement.videoHeight;
  98. ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
  99. const topColors = [];
  100. const bottomColors = [];
  101. // Анализируем верхний край видео
  102. for (let x = 0; x < canvas.width; x += 5) {
  103. const topPixel = ctx.getImageData(x, 0, 1, 1).data;
  104. const opacity = settings.baseOpacity * (1 - (x / canvas.width)); // Прозрачность уменьшается к краю
  105. topColors.push(`rgba(${topPixel[0]}, ${topPixel[1]}, ${topPixel[2]}, ${opacity})`);
  106. }
  107. // Анализируем нижний край видео
  108. for (let x = 0; x < canvas.width; x += 5) {
  109. const bottomPixel = ctx.getImageData(x, canvas.height - 1, 1, 1).data;
  110. const opacity = settings.baseOpacity * (1 - (x / canvas.width)); // Прозрачность уменьшается к краю
  111. bottomColors.push(`rgba(${bottomPixel[0]}, ${bottomPixel[1]}, ${bottomPixel[2]}, ${opacity})`);
  112. }
  113. // Создаем градиент для верхнего и нижнего краев
  114. const topGradient = `linear-gradient(to right, ${topColors.join(', ')})`;
  115. const bottomGradient = `linear-gradient(to right, ${bottomColors.join(', ')})`;
  116. // Применяем градиент к эффекту света
  117. topEffect.style.background = topGradient;
  118. bottomEffect.style.background = bottomGradient;
  119. // Корректируем позицию и размеры эффекта, чтобы они соответствовали видео
  120. topEffect.style.left = `${(containerRect.width - videoRect.width) / 2}px`;
  121. topEffect.style.right = `${(containerRect.width - videoRect.width) / 2}px`;
  122. topEffect.style.width = `${videoRect.width}px`;
  123. bottomEffect.style.left = `${(containerRect.width - videoRect.width) / 2}px`;
  124. bottomEffect.style.right = `${(containerRect.width - videoRect.width) / 2}px`;
  125. bottomEffect.style.width = `${videoRect.width}px`;
  126. }
  127. setInterval(updateLightEffect, settings.updateInterval);
  128. }
  129. addStyles();
  130. window.addEventListener('load', createLightEffect);
  131. })();