YouTube Avatar Decorations

YouTube Avatars enhances the visual experience on YouTube by allowing users to customize their avatars on both channel and video pages.

  1. // ==UserScript==
  2. // @name YouTube Avatar Decorations
  3. // @name:tr YouTube Avatar Dekorasyonları
  4. // @name:de YouTube-Avatar-Dekorationen
  5. // @name:ru Украшения для аватаров YouTube
  6. // @name:es Decoraciones de avatares de YouTube
  7. // @name:zh-CN YouTube 头像装饰
  8. // @name:hi यूट्यूब अवतार सजावट
  9. // @name:fr Décorations d'avatar YouTube
  10. // @name:pt Decorações de avatar do YouTube
  11. // @name:ja YouTube アバターのデコレーション
  12. // @name:ko YouTube 아바타 장식
  13. // @name:ta YouTube அவதார் அலங்காரங்கள்
  14. // @name:hr Dekoracije YouTube avatara
  15. // @name:it Decorazioni per avatar di YouTube
  16. // @name:id Dekorasi Avatar YouTube
  17. // @name:tk YouTube Awatar bezegleri
  18. // @name:az YouTube Avatar Dekorasiyaları
  19. // @license MIT
  20. // @namespace http://tampermonkey.net/
  21. // @version 1.5
  22. // @description YouTube Avatars enhances the visual experience on YouTube by allowing users to customize their avatars on both channel and video pages.
  23. // @description:tr YouTube Avatarları, kullanıcıların hem kanal hem de video sayfalarında avatarlarını özelleştirmelerine olanak tanıyarak YouTube'daki görsel deneyimi geliştirir.
  24. // @description:de YouTube-Avatare verbessern das visuelle Erlebnis auf YouTube, indem sie es Benutzern ermöglichen, ihre Avatare sowohl auf Kanal- als auch auf Videoseiten anzupassen.
  25. // @description:ru Аватары YouTube улучшают визуальное восприятие YouTube, позволяя пользователям настраивать свои аватары как на страницах канала, так и на страницах видео.
  26. // @description:es YouTube Avatars mejora la experiencia visual en YouTube al permitir a los usuarios personalizar sus avatares tanto en el canal como en las páginas de video.
  27. // @description:zh-CN YouTube Avatars 允许用户在频道和视频页面上自定义自己的头像,从而增强了 YouTube 上的视觉体验。
  28. // @description:hi YouTube अवतार उपयोगकर्ताओं को चैनल और वीडियो पेज दोनों पर अपने अवतारों को अनुकूलित करने की अनुमति देकर YouTube पर दृश्य अनुभव को बढ़ाता है।
  29. // @description:fr YouTube Avatars améliore l'expérience visuelle sur YouTube en permettant aux utilisateurs de personnaliser leurs avatars sur les pages de la chaîne et des vidéos.
  30. // @description:pt Os Avatares do YouTube aprimoram a experiência visual no YouTube, permitindo que os usuários personalizem seus avatares nas páginas do canal e do vídeo.
  31. // @description:ja YouTube アバターは、ユーザーがチャンネルとビデオ ページの両方でアバターをカスタマイズできるようにすることで、YouTube でのビジュアル エクスペリエンスを強化します。
  32. // @description:ko YouTube 아바타는 사용자가 채널과 동영상 페이지 모두에서 아바타를 맞춤설정할 수 있도록 하여 YouTube의 시각적 경험을 향상시킵니다.
  33. // @description:ta சேனல் மற்றும் வீடியோ பக்கங்களில் பயனர்கள் தங்கள் அவதாரங்களைத் தனிப்பயனாக்க அனுமதிப்பதன் மூலம் YouTube அவதாரங்கள் YouTube இல் காட்சி அனுபவத்தை மேம்படுத்துகிறது.
  34. // @description:hr YouTube Avatari poboljšavaju vizualno iskustvo na YouTubeu dopuštajući korisnicima da prilagode svoje avatare na stranicama kanala i videozapisa.
  35. // @description:it Gli avatar di YouTube migliorano l'esperienza visiva su YouTube consentendo agli utenti di personalizzare i propri avatar sia sul canale che sulle pagine video.
  36. // @description:id Avatar YouTube meningkatkan pengalaman visual di YouTube dengan memungkinkan pengguna menyesuaikan avatar mereka di saluran dan laman video.
  37. // @description:tk “YouTube Avatars”, ulanyjylara awatarlaryny iki kanalda we wideo sahypalarynda sazlamaga mümkinçilik bermek bilen, YouTube-da görüş tejribesini ýokarlandyrýar.
  38. // @description:az YouTube Avatarları istifadəçilərə həm kanal, həm də video səhifələrində öz avatarlarını fərdiləşdirməyə imkan verməklə YouTube-da vizual təcrübəni artırır.
  39. // @author Phaticusthiccy
  40. // @icon https://i.hizliresim.com/723p62n.png
  41. // @match https://www.youtube.com/*
  42. // @supportURL https://github.com/phaticusthiccy/YoutubeAvatars/issues/new
  43. // @homepageURL https://github.com/phaticusthiccy/YoutubeAvatars
  44. // @grant none
  45. // ==/UserScript==
  46.  
  47. (function() {
  48. 'use strict';
  49.  
  50. const avatarCategories = {
  51. "General": [
  52. { name: "Glitch", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_e90ebc0114e7bdc30353c8b11953ea41.png?size=96&passthrough=true" },
  53. { name: "Cybernetics", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_c6b3bc1dc49e5b284dca0b6437831004.png?size=96&passthrough=true" },
  54. { name: "Golden Crown", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_65db91cee351e36150a2b506b26eba71.png?size=96&passthrough=true" },
  55. { name: "Evil Crown", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_d1ea7b8650bf3d64a03304c2ceb7d089.png?size=96&passthrough=true" },
  56. { name: "Color Wave", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_49c479e15533fb4c02eb320c9c137433.png?size=96&passthrough=true" },
  57. { name: "Oasis", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_f740031cc97d1b7eb73c0d0ac1dd09f3.png?size=96&passthrough=true" },
  58. { name: "Rainy Mood", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_e8c11f139e55dac538cdaafb3caa2317.png?size=96&passthrough=true" },
  59. { name: "Doodle", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_5873ecaa76fb549654b40095293f902e.png?size=96&passthrough=true" },
  60. { name: "Green Smoke", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_10b9f886b513b77ccdd67c8784f1a496.png?size=96&passthrough=true" },
  61. { name: "Victory", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/Animation-1723308469539-ezgif.com-optipng.png", scale: 1.21 },
  62. { name: "Strings", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/strings.png", scale: 1.5 },
  63. { name: "Sketch Hat", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/hat.png" },
  64. { name: "Robin Hood Hat", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/robin_hood.png?raw=true" },
  65. { name: "Devil Horns", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/devil_horn.png" },
  66. { name: "Light Bulbs", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_88f42fb7360d8224a670a50c3496f315.png?size=96&passthrough=true" },
  67. ],
  68. "Valentine": [
  69. { name: "Angel", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_c86b11a49bb8057ce9c974a6f7ad658a.png?size=96&passthrough=true" },
  70. { name: "In Love", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_7f44d538ec830f479605f7bf8720afda.png?size=96&passthrough=true" },
  71. { name: "Hearts", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_3e1fc3c7ee2e34e8176f4737427e8f4f.png?size=96&passthrough=true" },
  72. { name: "Sakura", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_13913a00bd9990ab4102a3bf069f0f3f.png?size=96&passthrough=true" },
  73. { name: "Sakura Warrior", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_7cf09c7e78d6eb35ae354acc1d5cc676.png?size=96&passthrough=true" },
  74. { name: "Fallen Leaves", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_7fecc9d20cbbf54644c9a532f7db4664.png?size=96&passthrough=true", left: "-1.8px" },
  75. { name: "Heart Lamps (Blue)", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_42cc3fe7133523096466102e7a222003.png?size=96&passthrough=true" },
  76. { name: "Heart Lamps (Red)", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_63a69109db554a66764cbe61c6e556ef.png?size=96&passthrough=true" },
  77. { name: "Fluffy Teddy Bear", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_555ad9b90a13534180b9274d013e3651.png?size=96&passthrough=true" },
  78. { name: "Heart Ring", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_a1c0581971d4a296908829289fea2c47.png?size=96&passthrough=true", scale: 1.09 },
  79.  
  80. ],
  81. "Animals": [
  82. { name: "Cat Ears", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_c3cffc19e9784f7d0b005eecdf1b566e.png?size=96&passthrough=true" },
  83. { name: "Sleepy Cat", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_77b7b6a740a9451e1ef39c0252154ef8.png?size=96&passthrough=true" },
  84. { name: "Blob Cat", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/blobcat.gif" },
  85. { name: "Space Whale", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/spcae_whale.gif", scale: 1.03 },
  86. ],
  87. "Anime": [
  88. { name: "Flying Hearts", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_8ffa2ba9bff18e96b76c2e66fd0d7fa3.png?size=96&passthrough=true" },
  89. { name: "Ki Energy", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_f3af281c65cf0cf590e9e1f59e9c6cf6.png?size=96&passthrough=true" },
  90. { name: "Gushing Energy", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_c7e1751e8122f1b475cb3006966fb28c.png?size=96&passthrough=true" },
  91. { name: "Shocked", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_b98e8b204d59882fb7f9f7c86922c0bf.png?size=96&passthrough=true" },
  92. { name: 'Anger', url: 'https://cdn.discordapp.com/avatar-decoration-presets/a_3c97a2d37f433a7913a1c7b7a735d000.png?size=96&passthrough=true' },
  93. { name: "Starts", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_d72066b8cecbadd9fc951913ebcc384f.png?size=96&passthrough=true" },
  94. { name: "Soul", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_c3c09bd122898be35093d0d59850f627.png?size=96&passthrough=true" },
  95. { name: "Cute Radish", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_89cd445201a0c6c64d46876503d0e90e.png?size=96&passthrough=true" },
  96. { name: "Sweat Drops", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_55c9d0354290afa8b7fe47ea9bd7dbcf.png?size=96&passthrough=true" },
  97. { name: "Cat Hat", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/cat_hat.png?raw=true" },
  98. ],
  99. "Nature": [
  100. { name: "Flower Clouds", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_d9ff5ff133ed9176895a4a2b5e58f1b8.png?size=96&passthrough=true" },
  101. { name: "Rainbow", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_bba669bfb28f492b64852e00fde4989d.png?size=96&passthrough=true" },
  102. { name: "Patrick the Starfish", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_0f7fa66bc185c858f92a7918ea4dd47a.png?size=96&passthrough=true" },
  103. { name: "Gary the Snail", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_4db5b8518672197225c69fe72f07a945.png?size=96&passthrough=true" },
  104. { name: "Wind", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_554b7c34f7b6c709f19535aacb128e7b.png?size=96&passthrough=true" },
  105. { name: "Water", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_250640ab00a8837a1d56f35879138177.png?size=96&passthrough=true" },
  106. { name: "Butterfly", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_4cd9ae5a8d103c219eacd3674d7730cd.png?size=96&passthrough=true" },
  107. { name: "Lightening", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_365eed4178528fe8293c4212e8e2d5cb.png?size=96&passthrough=true" },
  108. { name: "Constellations", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_8552f9857793aed0cf816f370e2df3be.png?size=96&passthrough=true" },
  109. { name: "Blackhole", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_6d16b27d9415cafe3b289053644337c4.png?size=96&passthrough=true" },
  110. { name: "UFO", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_6fdbddb6229453eac3bbb212edf5cd1c.png?size=96&passthrough=true" },
  111. { name: "Neon Star", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/rotating_star.png?raw=true" },
  112. { name: "Daisy Ring", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/daisy_ring.png?raw=true" },
  113. { name: "Fire", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/circle_fire.gif?raw=true", scale: 1.7 },
  114. { name: "Roses", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/roses.gif?raw=true" },
  115. { name: "Fluid Silver", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/fluid_silver.gif?raw=true", scale: 1.21 },
  116. { name: "Acid", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/acid.webp?raw=true", scale: 1.45, top: "10px", left: "-2.5px", videoTop: "-5.7px", videoLeft: "-10.9px", videoScale: 1.3 },
  117. { name: "Falling Star", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/falling%20star.gif", scale: 1.45, top: "-5px", left: "-5px", videoTop: "-11px", videoLeft: "-10.9px", videoScale: 1.3 },
  118. { name: "Space Helmet", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_bb31faaec1be1ef5ff32dcdc5f37efbf.png?size=96&passthrough=true" },
  119. { name: "Snow Globe", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_85a8f9ca60cb4328378270a7f13ed7fd.png?size=96&passthrough=true" },
  120. ],
  121. "Mystic": [
  122. { name: "Spirit Sparks", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_1005898c6acf56a9ac5010baf444f6fd.png?size=96&passthrough=true" },
  123. { name: "Skull Medallion", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_9d67a1cbf81fe7197c871e94f619b04b.png?size=96&passthrough=true" },
  124. { name: "The Wand", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_db9baf0ba7cf449d2b027c06309dbe8d.png?size=96&passthrough=true" },
  125. { name: "Fairies", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_fe3c76cac2adf426832a7e495e8329d3.png?size=96&passthrough=true" },
  126. { name: "Blue Yonder", url: "https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/items/917950/9155ed2050954e8bd0e74f0f0dcfa0e96b37ec34.png" },
  127. { name: "Sparkles", url: "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/items/1192640/6b555763a9ff0815cff7d45480f03ff4d1ca4ab3.png" },
  128. { name: "Divination", url: "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/items/2271980/2727a0bbab23f6ecc60b86b2f4946bd31d986165.png" },
  129. { name: "Energy Ball", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/energy_ball.png" },
  130. { name: "Eyes", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/eyes.png?raw=true" },
  131. { name: "Devil", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/devil.png?raw=true" },
  132. { name: "Shining Star", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/final_light.png?raw=true" },
  133. { name: "Aetheria", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/aetheria2.gif?raw=true", scale: 1.4, videoScale: 1.2 },
  134. { name: "Shining Star 2", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/stars2.gif?raw=true" },
  135. ],
  136. "Games": [
  137. { name: "Valorant - Viper", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_62cd9d7c0031a7c1eb5ad5cc96992189.png?size=96&passthrough=true" },
  138. { name: "Valorant - Death", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_09de63526a45be1ddac70e84718ee04a.png?size=96&passthrough=true" },
  139. { name: "Valorant - Yoru", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_da532f804b47f1681006c2996eb07b2a.png?size=96&passthrough=true" },
  140. { name: "Valorant - Cypher", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_b1efe77f379c6c9c6e47e6b6299d5a7d.png?size=96&passthrough=true" },
  141. { name: "Valorant - Clove", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_98555e40cc6802bd3a4fed906af1d992.png?size=96&passthrough=true" },
  142. { name: "Valorant - Omen", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_c45abe8c7585fdb41b8d8d4d666f1588.png?size=96&passthrough=true" },
  143. { name: "Valorant - Reyna", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_a87e3efa4de2956331831681231ce63b.png?size=96&passthrough=true" },
  144. { name: "Valorant - Jett", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_904b1989077c91fca1168d39bfcaa0a4.png?size=96&passthrough=true" },
  145. { name: "Palworld - Chillet", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_48b8411feb1e80a69048fc65b3275b75.png?size=96&passthrough=true" },
  146. { name: "Palworld - Cattiva", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_d260c70fa8f38c499fa452c3cbdc5a0c.png?size=96&passthrough=true" },
  147. { name: "Palworld - Lamball", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_949a575b693c81ced8f56a7579d0969f.png?size=96&passthrough=true" },
  148. { name: "Palworld - Depresso", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_b7e2813fb97fe05b0f9f29a1bb7fde41.png?size=96&passthrough=true" },
  149. { name: "Palworld - Selyne", url: "https://cdn.discordapp.com/avatar-decoration-presets/a_0830085f29712a6f3a23a123302050b4.png?size=96&passthrough=true" },
  150. { name: "Starfield - Grav Wave", url: "https://cdn.akamai.steamstatic.com/steamcommunity/public/images/items/1716740/ff0e84c4996b1c9cb299ba2ab1c6454c5d129b49.png" },
  151. { name: "Genshin - Little Matron", url: "https://upload-os-bbs.hoyolab.com/upload/2024/07/22/d070e73b57eebc782658856f83400c0f_4985728381431752077.webp?x-oss-process=image/auto-orient,0/interlace,1/format,webp/quality,q_70" },
  152. { name: "Genshin - Lumine", url: "https://fastcdn.hoyoverse.com/static-resource-v2/2024/04/10/e0c33a668dfe55c3d28c153fd26d2566_7549684827555419407.webp?x-oss-process=image/auto-orient,0/interlace,1/format,webp/quality,q_70" },
  153. { name: "Honkai - Zhu Yuan", url: "https://upload-os-bbs.hoyolab.com/upload/2024/07/23/1b34e54ec5ac3fbe67c079dd29c5f632_5221289561156079104.webp?x-oss-process=image/auto-orient,0/interlace,1/format,webp/quality,q_70" },
  154. { name: "Honkai - Ellen", url: "https://upload-os-bbs.hoyolab.com/upload/2024/07/04/98126629588606c7ed379693c30b8c6c_1697937515325313185.webp?x-oss-process=image/auto-orient,0/interlace,1/format,webp/quality,q_70" },
  155. { name: "Minecraft - Cave", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/mc_cave.gif", scale: 1.08 },
  156. ],
  157. "Static Frames": [
  158. { name: "Neon 1", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/static1.png" },
  159. { name: "Neon 2", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/static2.png", scale: 1.21 },
  160. { name: "Neon 3", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/static3.png", top: "5px", scale: 1.1, onlyChannel: true, videoTop: "-8px" },
  161. { name: "DTCQ", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/static5.png", top: "5px", scale: 1.1, onlyChannel: true, videoTop: "-8px" },
  162. { name: "Lilith", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/static6.png" },
  163. { name: "Valentine", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/static7.png", scale: 1.1 },
  164. { name: "Jellyfish", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/jelly.png" },
  165. { name: "Burger", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/burger.png", scale: 1.19, dontScaleVideos: true },
  166. { name: "Glitch 1", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/glitch.png", scale: 1.3 },
  167. { name: "Glitch 2", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/glitch2.png", scale: 1.3 },
  168. { name: "Cute Doodles", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/cute_doodles.png", scale: 1.4 },
  169. { name: "Love Letter", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/love_letter.png", scale: 1.4 },
  170. { name: "Pink Ribbon", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/ribbon.png", scale: 1.1 },
  171. { name: "Arrival Movie 1", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/arrival.png", scale: 1.2, onlyChannel: true, top: "4px", left: "4px", darkMode: true },
  172. { name: "Arrival Movie 2", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/arrival2.png", scale: 1.1, onlyChannel: true, top: "7px", darkMode: true },
  173. { name: "Arrival Movie 3", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/arrival3.png", scale: 1.2, left: "5px", darkMode: true },
  174. { name: "Valentine 2", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/val2.png", scale: 1.1 },
  175. { name: "Halloween", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/halloween.png", scale: 1.1 },
  176. { name: "Halloween 2", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/halloween2.png", scale: 1.1 },
  177. { name: "Valentine 3", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/val3.png", scale: 1.1 },
  178. { name: "Pink Sea", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/pink_sea.gif", scale: 1.21 },
  179. { name: "Saturn", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/saturn.png", scale: 1.5 },
  180. { name: "Ghost Cat", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/ghost_cat.gif" },
  181. { name: "Fantasy Nature", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/fantasy_nature.png" },
  182. { name: "Fantasy Fire", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/fantasy_fire.png" },
  183. { name: "Fantasy Sea", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/fantasy_sea.png" },
  184. { name: "Fantasy Dark", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/fantasy_dark.png" },
  185. { name: "Dark Cat", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/dark_cat.png", top: "5px", scale: 1.1 },
  186. { name: "Headset", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/headset.png" },
  187. { name: "Detective", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/detective.png", scale: 1.1 },
  188. { name: "Lying Figures", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/lying_figures.png?raw=true", top: "-2px", scale: 1.03 },
  189. { name: "Unicorn", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/unicorn.png?raw=true" },
  190. { name: "Panda", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/panda.png?raw=true", top: "-3px" },
  191. { name: "LGBT Transsexual", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/lgbt_trans.png", scale: 0.9 },
  192. { name: "LGBT Lesbian", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/lgnt_les.png", scale: 1.04 },
  193. { name: "LGBT Femboy", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/lgbt_femboy.png", scale: 0.9 },
  194. { name: "LGBT Non-Binary", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/lgbt_nonb.png", scale: 0.9 },
  195. { name: "LGBT Pride", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/lgbt_pride.png", scale: 0.9 },
  196. { name: "LGBT Gay", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/lgbt_gay.png", scale: 0.9 },
  197. ],
  198. "AI Static": [
  199. { name: "AI Flowers", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/flowers.png", videoLeft: "-11.3px", left: "-6px", scale:1.12 },
  200. { name: "Pikachu", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/pikachu.png", scale: 1.21, left: "-2px" },
  201. ],
  202. "Experimental": [
  203. { name: "Valorant - Clove HQ", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/clove_2.gif", top: "-10px" },
  204. { name: "Magic HQ", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/magic.gif", top: "-12px", scale: 1.3 },
  205. { name: "Cute Anime", url: "https://raw.githubusercontent.com/phaticusthiccy/phaticusthiccy/main/youtube_animated_avatars/cute_anime.gif", top: "-8px", scale: 1.4, left: "-8px", videoTop: "-11.2px" },
  206. ]
  207. };
  208.  
  209. for (let _category in avatarCategories) {
  210. avatarCategories[_category].sort((a, b) => a.name.localeCompare(b.name));
  211. }
  212.  
  213. let selectedAvatarUrl = localStorage.getItem('selectedAvatar') || '';
  214. let selectedCategory = ""
  215.  
  216. function saveSelectedAvatar(url, category) {
  217. localStorage.setItem('selectedAvatar', url);
  218. localStorage.setItem('selectedMenu', category);
  219. selectedAvatarUrl = url;
  220. selectedCategory = category;
  221. }
  222.  
  223. function getSelectedAvatar() {
  224. return localStorage.getItem('selectedAvatar') || '';
  225. }
  226.  
  227. function getSelectedMenu() {
  228. return localStorage.getItem('selectedMenu');
  229. }
  230.  
  231. function categoryContainsSelectedAvatar(category, selectedAvatar) {
  232. return avatarCategories[category].some(avatar => avatar.url === selectedAvatar);
  233. }
  234.  
  235. function isValidUrl() {
  236. const currentUrl = document.location.href.split(".com/")[1];
  237. return currentUrl.startsWith("@") || currentUrl.startsWith("watch") || currentUrl.startsWith("c/") || currentUrl.startsWith("channel/");
  238. }
  239.  
  240. function isChannel() {
  241. const currentUrl = document.location.href.split(".com/")[1];
  242. return currentUrl.startsWith("@") || currentUrl.startsWith("c/") || currentUrl.startsWith("channel/");
  243. }
  244.  
  245. function isYouTubeDarkMode() {
  246. try {
  247. function isDarkColor(color) {
  248. const rgb = color.match(/\d+/g);
  249. if (rgb) {
  250. const [r, g, b] = rgb.map(Number);
  251. const brightness = (r * 299 + g * 587 + b * 114) / 1000;
  252. return brightness < 128;
  253. }
  254. return false;
  255. }
  256.  
  257. const appContainer = document.querySelector('ytd-app');
  258. if (appContainer) {
  259. const bgColor = window.getComputedStyle(appContainer).backgroundColor;
  260. return isDarkColor(bgColor);
  261. }
  262.  
  263. const bodyBgColor = window.getComputedStyle(document.body).backgroundColor;
  264. return isDarkColor(bodyBgColor);
  265. } catch {
  266. return false
  267. }
  268. }
  269.  
  270. var searchTerm = ""
  271.  
  272. function createMenu(idName = "") {
  273. /*if (document.getElementById('avatar-menu2')) {
  274. return;
  275. }*/
  276.  
  277. var menu;
  278. if (document.getElementById('avatar-menu2')) {
  279. menu = document.getElementById('avatar-menu2')
  280. return menu
  281. } else {
  282. menu = document.createElement('div');
  283. };
  284.  
  285. menu.id = idName == "" ? 'avatar-menu' : idName;
  286. menu.style.position = 'absolute';
  287. menu.style.backgroundColor = '#fff';
  288. menu.style.border = '1px solid #ccc';
  289. menu.style.padding = '23px';
  290. menu.style.boxShadow = '0 4px 12px rgba(0,0,0,0.2)';
  291. menu.style.borderRadius = '8px';
  292. menu.style.zIndex = '9999';
  293. menu.style.display = 'none';
  294. menu.style.transition = 'opacity 0.3s ease';
  295. menu.style.opacity = '0';
  296. menu.style.maxHeight = '500px';
  297. menu.style.overflowY = 'auto';
  298. menu.style.overflowX = 'hidden';
  299. menu.style.minWidth = '250px';
  300. menu.style.fontSize = '14px';
  301. menu.style.userSelect = 'none';
  302.  
  303.  
  304. const searchInput = document.createElement('input');
  305. searchInput.type = 'text';
  306. searchInput.placeholder = 'Search Effect...';
  307. searchInput.style.width = '100%';
  308. searchInput.style.padding = '10px';
  309. searchInput.style.marginBottom = '10px';
  310. searchInput.style.minWidth = '250px';
  311. searchInput.style.border = 'none';
  312. searchInput.style.outline = 'none';
  313. searchInput.style.boxShadow = 'none';
  314.  
  315. searchInput.addEventListener('focus', () => {
  316. searchInput.style.border = 'none';
  317. searchInput.style.outline = 'none';
  318. searchInput.style.boxShadow = 'none';
  319. });
  320.  
  321. searchInput.addEventListener('blur', () => {
  322. searchInput.style.border = 'none';
  323. searchInput.style.outline = 'none';
  324. searchInput.style.boxShadow = 'none';
  325. });
  326.  
  327.  
  328. searchInput.addEventListener('input', (event) => {
  329. const searchTerm = event.target.value.toLowerCase();
  330. menu.querySelectorAll('div > div > div').forEach((item) => {
  331. if (searchTerm === '') {
  332. item.style.display = '';
  333. item.parentElement.style.display = 'none';
  334. item.parentElement.parentElement.style.display = 'block';
  335. //item.parentElement.parentElement.children[1].style.display = 'none';
  336. } else if (item.textContent.toLowerCase().includes(searchTerm)) {
  337. item.style.display = "block"
  338. item.parentElement.style.display = 'block';
  339. item.parentElement.parentElement.style.display = 'block';
  340. item.parentElement.parentElement.children[1].style.display = 'block';
  341. } else {
  342. item.style.display = 'none';
  343. }
  344. });
  345. });
  346.  
  347. menu.insertBefore(searchInput, menu.firstChild);
  348.  
  349. const selectedAvatar = getSelectedAvatar();
  350. const selectedCategory = getSelectedMenu();
  351.  
  352. for (const [category, avatars] of Object.entries(avatarCategories)) {
  353. const categoryDiv = document.createElement('div');
  354. categoryDiv.style.marginBottom = '15px';
  355.  
  356. const categoryTitle = document.createElement('div');
  357. categoryTitle.textContent = category;
  358. categoryTitle.style.fontWeight = 'bold';
  359. categoryTitle.style.marginBottom = '8px';
  360. categoryTitle.style.cursor = 'pointer';
  361. categoryTitle.style.padding = '8px';
  362. categoryTitle.style.backgroundColor = '#f0f0f0';
  363. categoryTitle.style.borderRadius = '4px';
  364.  
  365.  
  366. if (categoryContainsSelectedAvatar(category, selectedAvatar) == true) {
  367. categoryTitle.style.color = '#369626';
  368. }
  369.  
  370. const avatarList = document.createElement('div');
  371. avatarList.style.display = 'none';
  372. avatarList.style.paddingLeft = '15px';
  373.  
  374. categoryTitle.addEventListener('click', (event) => {
  375. avatarList.style.display = avatarList.style.display === 'none' ? 'block' : 'none';
  376. event.stopPropagation();
  377. });
  378.  
  379. avatars.forEach(avatar => {
  380. const item = document.createElement('div');
  381. item.style.padding = '10px';
  382. item.style.cursor = 'pointer';
  383. item.style.borderBottom = '1px solid #eee';
  384. item.style.transition = 'background-color 0.2s';
  385. item.style.display = 'flex';
  386. item.style.alignItems = 'center';
  387. item.style.position = 'relative';
  388.  
  389. const avatarName = document.createElement('span');
  390. avatarName.textContent = avatar.name;
  391. avatarName.style.flexGrow = '1';
  392.  
  393.  
  394. const previewImg = document.createElement('img');
  395. previewImg.style.width = '30px';
  396. previewImg.style.height = '30px';
  397. previewImg.style.marginLeft = '20px';
  398. previewImg.style.marginRight = '25px';
  399. previewImg.style.display = 'none';
  400. previewImg.style.position = 'absolute';
  401. previewImg.style.right = '0';
  402. previewImg.style.top = '50%';
  403. previewImg.style.transform = 'translateY(-50%)';
  404.  
  405. item.appendChild(avatarName);
  406. item.appendChild(previewImg);
  407.  
  408. item.addEventListener('mouseenter', () => {
  409. item.style.backgroundColor = '#f5f5f5';
  410. item.style.transform = 'scale(1.2)';
  411. item.style.transition = 'transform 0.2s ease';
  412. item.style.zIndex = '100';
  413. previewImg.style.display = 'block';
  414.  
  415. if (!previewImg.src) {
  416. previewImg.src = avatar.url;
  417. }
  418. previewImg.style.display = 'block';
  419.  
  420. });
  421. item.addEventListener('mouseleave', () => {
  422. item.style.backgroundColor = '#fff';
  423. item.style.transform = 'scale(1)';
  424. item.style.transition = 'transform 0.2s ease';
  425. item.style.zIndex = '0';
  426. previewImg.style.display = 'none';
  427. });
  428.  
  429. item.addEventListener('click', () => {
  430.  
  431. var selectedAvatar2 = avatar.url
  432. var selectedCategory2 = findCategoryByUrl(selectedAvatar2, avatarCategories)
  433.  
  434. if (selectedAvatar2 && selectedCategory2) {
  435. var effectName = document.querySelector("#selectedEffectName")
  436. if (effectName) {
  437. let findAvatarName = avatarCategories[selectedCategory2].find((avatar3) => avatar3.url == selectedAvatar2)
  438. effectName.textContent = `${selectedCategory2} ${findAvatarName.name}`
  439. } else {
  440. let selectedAvatarInfo = document.createElement('div');
  441. selectedAvatarInfo.style.fontWeight = 'bold';
  442. selectedAvatarInfo.style.marginBottom = '10px';
  443. selectedAvatarInfo.style.textAlign = "center"
  444. selectedAvatarInfo.style.color = "#369626"
  445. selectedAvatarInfo.id = "selectedEffectName"
  446. let findAvatarName = avatarCategories[selectedCategory2].find((avatar3) => avatar3.url == selectedAvatar2)
  447. selectedAvatarInfo.textContent = `${selectedCategory2} ${findAvatarName.name}`
  448. menu.insertBefore(selectedAvatarInfo, menu.firstChild);
  449. }
  450. }
  451.  
  452. applyAvatar(avatar.url);
  453. saveSelectedAvatar(avatar.url, category);
  454. updateMenu(menu);
  455. //menu.style.opacity = '0';
  456. //setTimeout(() => menu.style.display = 'none', 300);
  457. });
  458. item.addEventListener('mouseover', () => {
  459. item.style.backgroundColor = '#f5f5f5';
  460. });
  461. item.addEventListener('mouseout', () => {
  462. item.style.backgroundColor = '#fff';
  463. });
  464. avatarList.appendChild(item);
  465. });
  466.  
  467. categoryDiv.appendChild(categoryTitle);
  468. categoryDiv.appendChild(avatarList);
  469. menu.appendChild(categoryDiv);
  470. }
  471.  
  472. const removeItem = document.createElement('div');
  473. removeItem.style.padding = '10px';
  474. removeItem.style.cursor = 'pointer';
  475. removeItem.style.borderTop = '1px solid #eee';
  476. removeItem.style.color = '#ff4d4d';
  477. removeItem.style.fontWeight = 'bold';
  478. removeItem.textContent = 'Remove';
  479. removeItem.style.textAlign = "center"
  480. removeItem.addEventListener('click', () => {
  481. var effectName = document.querySelector("#selectedEffectName")
  482. if (effectName) effectName.remove()
  483. removeAvatar();
  484. saveSelectedAvatar('', '');
  485. updateMenu(menu);
  486. menu.style.opacity = '0';
  487. setTimeout(() => menu.style.display = 'none', 300);
  488. });
  489. removeItem.addEventListener('mouseover', () => {
  490. removeItem.style.backgroundColor = '#f5f5f5';
  491. });
  492. removeItem.addEventListener('mouseout', () => {
  493. removeItem.style.backgroundColor = '#fff';
  494. });
  495. menu.appendChild(removeItem);
  496.  
  497. removeItem.addEventListener('mouseenter', () => {
  498. removeItem.style.backgroundColor = '#f5f5f5';
  499. removeItem.style.transform = 'scale(1.2)';
  500. removeItem.style.transition = 'transform 0.2s ease';
  501. removeItem.style.zIndex = '100';
  502. });
  503. removeItem.addEventListener('mouseleave', () => {
  504. removeItem.style.backgroundColor = '#fff';
  505. removeItem.style.transform = 'scale(1)';
  506. removeItem.style.transition = 'transform 0.2s ease';
  507. removeItem.style.zIndex = '0';
  508. });
  509.  
  510. document.body.appendChild(menu);
  511.  
  512. document.addEventListener('click', (event) => {
  513. if (menu.style.display === 'block' && !menu.contains(event.target) && event.target.id !== 'avatar-icon') {
  514. menu.style.opacity = '0';
  515. setTimeout(() => menu.style.display = 'none', 300);
  516. }
  517. });
  518.  
  519. try {
  520. if (selectedAvatar && selectedCategory) {
  521. const selectedAvatarInfo = document.createElement('div');
  522. selectedAvatarInfo.style.fontWeight = 'bold';
  523. selectedAvatarInfo.style.marginBottom = '10px';
  524. selectedAvatarInfo.style.textAlign = "center"
  525. selectedAvatarInfo.style.color = "#369626"
  526. selectedAvatarInfo.id = "selectedEffectName"
  527. var findAvatarName = avatarCategories[selectedCategory].find((avatar) => avatar.url == selectedAvatar)
  528. selectedAvatarInfo.textContent = `${selectedCategory} ${findAvatarName.name}`;
  529. menu.insertBefore(selectedAvatarInfo, menu.firstChild);
  530. }
  531. } catch {}
  532.  
  533. return menu;
  534. }
  535.  
  536. function updateMenu(menu) {
  537. const selectedAvatar = getSelectedAvatar();
  538. menu.querySelectorAll('div > div').forEach((item) => {
  539. if (item.style.padding === '8px') {
  540. item.style.color = '';
  541. }
  542. });
  543. }
  544.  
  545. function findCategoryByUrl(url, avatarCategories) {
  546. for (let category in avatarCategories) {
  547. for (let item of avatarCategories[category]) {
  548. if (item.url === url) {
  549. return category;
  550. }
  551. }
  552. }
  553. return null;
  554. }
  555.  
  556. function applyAvatar(url) {
  557. if (!isValidUrl() || !url) return;
  558.  
  559. if (isChannel()) {
  560. applyChannelAvatar(url);
  561. } else {
  562. applyVideoAvatar(url);
  563. }
  564. }
  565.  
  566. function applyChannelAvatar(url) {
  567. const avatarShape = document.querySelector('yt-avatar-shape');
  568. const findAvatarByURL = (url) => {
  569. for (const category in avatarCategories) {
  570. const avatar = avatarCategories[category].find((avatar) => avatar.url === url);
  571. if (avatar) return avatar;
  572. }
  573. return {};
  574. };
  575. if (avatarShape) {
  576.  
  577. var channelFind = findAvatarByURL(url)
  578. var channelTop = channelFind.top == undefined ? "0" : String(channelFind.top);
  579. var channelScale = channelFind.scale == undefined ? 'none' : String(channelFind.scale);
  580. var channelFilter = channelFind.darkMode == true ? isYouTubeDarkMode() == true ? "invert(1)" : "none" : "none"
  581. var channelLeft = channelFind.left == undefined ? '0' : String(channelFind.left);
  582.  
  583. let gifWrapper = avatarShape.querySelector('#gif-wrapper');
  584. if (!gifWrapper) {
  585. gifWrapper = document.createElement('div');
  586. gifWrapper.id = 'gif-wrapper';
  587. gifWrapper.style.position = 'absolute';
  588. gifWrapper.style.width = '160px';
  589. gifWrapper.style.height = '160px';
  590. gifWrapper.style.zIndex = '10';
  591. gifWrapper.style.scale = '1.21';
  592.  
  593. const gifElement = document.createElement('img');
  594. gifElement.id = 'gif-element';
  595. gifElement.style.position = 'absolute';
  596. gifElement.style.top = channelTop
  597. gifElement.style.left = channelLeft
  598. gifElement.style.width = '100%';
  599. gifElement.style.height = '100%';
  600. gifElement.style.zIndex = '10';
  601. gifElement.style.scale = channelScale
  602. gifElement.style.filter = channelFilter
  603.  
  604. gifWrapper.appendChild(gifElement);
  605. avatarShape.insertBefore(gifWrapper, avatarShape.firstChild);
  606. }
  607. const gifElement = gifWrapper.querySelector('#gif-element');
  608. if (gifElement.src !== url) {
  609. gifElement.src = url;
  610. gifElement.style.scale = channelScale
  611. gifElement.style.top = channelTop
  612. gifElement.style.filter = channelFilter
  613. gifElement.style.left = channelLeft
  614. }
  615. }
  616. }
  617.  
  618. function applyVideoAvatar(url) {
  619. const findAvatarByURL = (url) => {
  620. for (const category in avatarCategories) {
  621. const avatar = avatarCategories[category].find((avatar) => avatar.url === url);
  622. if (avatar) return avatar;
  623. }
  624. return {};
  625. };
  626. const avatar = document.querySelector('#avatar');
  627.  
  628. var objectAvatar = findAvatarByURL(url)
  629. var videoTop = objectAvatar.videoTop == undefined ? objectAvatar.top == undefined ? "-10px" : objectAvatar.onlyChannel == true ? objectAvatar.videoTop == undefined ? "-10px" : objectAvatar.videoTop : String(objectAvatar.top) : objectAvatar.videoTop;
  630. var videoScale = objectAvatar.videoScale == undefined ? objectAvatar.scale == undefined ? 'none' : objectAvatar.dontScaleVideos == true ? 'none' : String(objectAvatar.scale) : String(objectAvatar.videoScale);
  631. var videoFilter = objectAvatar.darkMode == true ? isYouTubeDarkMode() == true ? "invert(1)" : "none" : "none"
  632. var videoLeft = objectAvatar.videoLeft == undefined ? '-10px' : String(objectAvatar.videoLeft);
  633.  
  634. if (avatar) {
  635. let uploadInfo = document.querySelector('#upload-info');
  636. if (uploadInfo) {
  637. uploadInfo.style.position = 'relative';
  638. uploadInfo.style.left = '10px';
  639. }
  640.  
  641. let gifWrapper = document.querySelector('#gif-wrapper');
  642. if (!gifWrapper) {
  643. gifWrapper = document.createElement('div');
  644. gifWrapper.id = 'gif-wrapper';
  645. gifWrapper.style.position = 'relative';
  646. gifWrapper.style.width = '40px';
  647. gifWrapper.style.height = '40px';
  648. gifWrapper.style.zIndex = '10';
  649.  
  650. let gifElement = document.createElement('img');
  651. gifElement.id = 'gif-element';
  652. gifElement.style.position = 'absolute';
  653. gifElement.style.left = videoLeft
  654. gifElement.style.width = '60px';
  655. gifElement.style.height = '60px';
  656. gifElement.style.zIndex = '10';
  657. gifElement.style.scale = videoScale
  658. gifElement.style.top = videoTop
  659. gifElement.style.filter = videoFilter
  660.  
  661. gifWrapper.appendChild(gifElement);
  662. avatar.parentElement.insertBefore(gifWrapper, avatar);
  663. gifWrapper.appendChild(avatar);
  664. }
  665. let gifElement = document.querySelector('#gif-element');
  666. if (gifElement.src !== url) {
  667. gifElement.src = url;
  668. gifElement.style.scale = videoScale
  669. gifElement.style.top = videoTop
  670. gifElement.style.filter = videoFilter
  671. gifElement.style.left = videoLeft
  672. }
  673. }
  674.  
  675. const avatar2 = document.querySelector('a.yt-simple-endpoint.style-scope.ytd-video-owner-renderer #avatar');
  676. if (avatar2) {
  677. let uploadInfo = document.querySelector('#upload-info');
  678. if (uploadInfo) {
  679. uploadInfo.style.position = 'relative';
  680. uploadInfo.style.left = '10px';
  681. }
  682.  
  683. let gifWrapper = document.querySelector('#gif-wrapper');
  684. if (!gifWrapper) {
  685. gifWrapper = document.createElement('div');
  686. gifWrapper.id = 'gif-wrapper';
  687. gifWrapper.style.position = 'relative';
  688. gifWrapper.style.width = '40px';
  689. gifWrapper.style.height = '40px';
  690. gifWrapper.style.zIndex = '10';
  691.  
  692. let gifElement = document.createElement('img');
  693. gifElement.id = 'gif-element';
  694. gifElement.style.position = 'absolute';
  695. gifElement.style.left = videoLeft
  696. gifElement.style.width = '60px';
  697. gifElement.style.height = '60px';
  698. gifElement.style.zIndex = '10';
  699. gifElement.style.scale = videoScale
  700. gifElement.style.top = videoTop
  701. gifElement.style.filter = videoFilter
  702.  
  703. gifWrapper.appendChild(gifElement);
  704. avatar2.parentElement.insertBefore(gifWrapper, avatar2);
  705. gifWrapper.appendChild(avatar2);
  706. }
  707. let gifElement = document.querySelector('#gif-element');
  708. if (gifElement.src !== url) {
  709. gifElement.src = url;
  710. gifElement.style.scale = videoScale
  711. gifElement.style.top = videoTop
  712. gifElement.style.filter = videoFilter
  713. gifElement.style.left = videoLeft
  714. }
  715. }
  716.  
  717. const avatar3 = document.querySelector("ytd-watch-flexy a.yt-simple-endpoint.style-scope.ytd-video-owner-renderer #avatar")
  718. if (avatar3) {
  719. let uploadInfo = document.querySelector('#upload-info');
  720. if (uploadInfo) {
  721. uploadInfo.style.position = 'relative';
  722. uploadInfo.style.left = '10px';
  723. }
  724.  
  725. let gifWrapper = document.querySelector('#gif-wrapper');
  726. if (!gifWrapper) {
  727. gifWrapper = document.createElement('div');
  728. gifWrapper.id = 'gif-wrapper';
  729. gifWrapper.style.position = 'relative';
  730. gifWrapper.style.width = '40px';
  731. gifWrapper.style.height = '40px';
  732. gifWrapper.style.zIndex = '10';
  733.  
  734. let gifElement = document.createElement('img');
  735. gifElement.id = 'gif-element';
  736. gifElement.style.position = 'absolute';
  737. gifElement.style.left = videoLeft
  738. gifElement.style.width = '60px';
  739. gifElement.style.height = '60px';
  740. gifElement.style.zIndex = '10';
  741. gifElement.style.scale = videoScale
  742. gifElement.style.top = videoTop
  743. gifElement.style.filter = videoFilter
  744.  
  745. gifWrapper.appendChild(gifElement);
  746. avatar3.parentElement.insertBefore(gifWrapper, avatar3);
  747. gifWrapper.appendChild(avatar3);
  748. }
  749. let gifElement = document.querySelector('#gif-element');
  750. if (gifElement.src !== url) {
  751. gifElement.src = url;
  752. gifElement.style.scale = videoScale
  753. gifElement.style.top = videoTop
  754. gifElement.style.filter = videoFilter
  755. gifElement.style.left = videoLeft
  756. }
  757. }
  758. }
  759.  
  760. function removeAvatar() {
  761. if (isChannel()) {
  762. const gifWrapper = document.querySelector('yt-avatar-shape #gif-wrapper');
  763. if (gifWrapper) {
  764. gifWrapper.remove();
  765. }
  766. } else {
  767. const gifWrapper = document.querySelector('#gif-wrapper');
  768. if (gifWrapper) {
  769. const uploadInfo = document.querySelector('#upload-info');
  770. if (uploadInfo) {
  771. uploadInfo.style.position = 'relative';
  772. uploadInfo.style.left = '0px';
  773. }
  774. const avatar = gifWrapper.querySelector('#avatar');
  775. gifWrapper.parentElement.insertBefore(avatar, gifWrapper);
  776. gifWrapper.remove();
  777. }
  778. }
  779. }
  780.  
  781. function addIcon() {
  782. const topBar = document.querySelector('ytd-topbar-menu-button-renderer');
  783. if (topBar && !document.querySelector('#avatar-icon')) {
  784. const iconWrapper = document.createElement('div');
  785. iconWrapper.style.display = 'flex';
  786. iconWrapper.style.alignItems = 'center';
  787.  
  788. const icon = document.createElement('img');
  789. icon.id = 'avatar-icon';
  790. icon.src = 'https://cdn.iconscout.com/icon/free/png-512/free-settings-2856913-2377697.png?f=webp&w=256';
  791. icon.style.width = '24px';
  792. icon.style.height = '24px';
  793. icon.style.cursor = 'pointer';
  794. icon.style.marginRight = '10px';
  795. icon.style.userSelect = 'none';
  796.  
  797. icon.addEventListener('click', () => {
  798. const menu = createMenu("avatar-menu2");
  799. function showToast(message) {
  800. const toast = document.createElement('div');
  801. toast.textContent = message;
  802. toast.style.position = 'fixed';
  803. toast.style["font-size"] = "larger";
  804. toast.style.top = '60px';
  805. toast.style.right = '20px';
  806. toast.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
  807. toast.style.color = 'white';
  808. toast.style.padding = '10px 20px';
  809. toast.style.borderRadius = '5px';
  810. toast.style.zIndex = '9999';
  811. toast.style.transition = 'opacity 0.5s';
  812.  
  813. document.body.appendChild(toast);
  814.  
  815. setTimeout(() => {
  816. toast.style.opacity = '0';
  817. setTimeout(() => {
  818. document.body.removeChild(toast);
  819. }, 500);
  820. }, 3000);
  821. }
  822.  
  823. if (!isValidUrl()) {
  824. showToast("You can only use this while watching a video or on a channel page");
  825. return;
  826. }
  827.  
  828. if (menu.style.display === 'none') {
  829. updateMenu(menu);
  830. menu.style.display = 'block';
  831. setTimeout(() => menu.style.opacity = '1', 0);
  832. const rect = icon.getBoundingClientRect();
  833.  
  834. const topOffset = rect.bottom + window.scrollY + (rect.height * 1.25);
  835. const leftOffset = rect.left + window.scrollX - (rect.width * 0.5);
  836.  
  837. menu.style.top = topOffset + "px"
  838. menu.style.left = `82%`;
  839. } else {
  840. menu.style.opacity = '0';
  841. setTimeout(() => menu.style.display = 'none', 300);
  842. }
  843. });
  844.  
  845. iconWrapper.appendChild(icon);
  846. topBar.parentElement.insertBefore(iconWrapper, topBar);
  847. }
  848. }
  849.  
  850. function applyStoredAvatar() {
  851. const selectedAvatar = getSelectedAvatar();
  852. if (selectedAvatar) {
  853. applyAvatar(selectedAvatar);
  854. }
  855. }
  856.  
  857. function keepAlive() {
  858. setInterval(() => {
  859. addIcon();
  860. //createMenu();
  861. }, 2000)
  862. }
  863.  
  864. function checkForTopBar() {
  865. const observer = new MutationObserver((mutations, obs) => {
  866. if (document.querySelector('ytd-topbar-menu-button-renderer')) {
  867. addIcon();
  868. applyStoredAvatar();
  869. obs.disconnect();
  870. }
  871. });
  872.  
  873. observer.observe(document, {
  874. childList: true,
  875. subtree: true
  876. });
  877. }
  878.  
  879. function checkForChannelAvatar() {
  880. const observer = new MutationObserver((mutations, obs) => {
  881. if (document.querySelector('yt-avatar-shape')) {
  882. applyStoredAvatar();
  883. obs.disconnect();
  884. }
  885. });
  886.  
  887. observer.observe(document, {
  888. childList: true,
  889. subtree: true
  890. });
  891. }
  892.  
  893. function observeUrlChange() {
  894. let lastUrl = location.href;
  895. new MutationObserver(() => {
  896. const url = location.href;
  897. if (url !== lastUrl) {
  898. lastUrl = url;
  899. onUrlChange();
  900. }
  901. }).observe(document, { subtree: true, childList: true });
  902. }
  903.  
  904. function onUrlChange() {
  905. if (!isValidUrl()) return;
  906. if (document.location.href.includes("index=") || document.location.href.includes("list=")) {
  907. true;
  908. } else {
  909. location.reload(true);
  910. }
  911. const selectedAvatar = getSelectedAvatar();
  912. if (selectedAvatar) {
  913. applyAvatar(selectedAvatar);
  914. }
  915. }
  916.  
  917. function init() {
  918. checkForTopBar();
  919. const selectedAvatar = getSelectedAvatar();
  920. if (selectedAvatar) {
  921. checkForChannelAvatar();
  922. }
  923. observeUrlChange();
  924. keepAlive();
  925. }
  926.  
  927. function checkAndApplyChannelAvatar() {
  928. if (!isValidUrl()) return;
  929. const selectedAvatar = getSelectedAvatar();
  930. if (selectedAvatar) {
  931. if (isChannel()) {
  932. const avatarShape = document.querySelector('yt-avatar-shape');
  933. if (avatarShape) {
  934. const gifElement = avatarShape.querySelector('#gif-element');
  935. if (!gifElement) {
  936. applyChannelAvatar(selectedAvatar);
  937. }
  938. }
  939. } else {
  940. applyVideoAvatar(selectedAvatar);
  941. }
  942. }
  943. }
  944.  
  945. //setInterval(checkAndApplyChannelAvatar, 500);
  946. init();
  947. window.addEventListener('load', init);
  948. })();