Rotate Telegram Web

Addding button to rotate images and videos

  1. // ==UserScript==
  2. // @name Rotate Telegram Web
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.0
  5. // @description Addding button to rotate images and videos
  6. // @author Pink team
  7. // @match https://web.telegram.org/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function () {
  12. "use strict";
  13.  
  14. function createButton() {
  15. const button = document.createElement("button");
  16.  
  17. button.classList.add("btn-icon");
  18.  
  19. button.id = "rotate-button";
  20. button.innerHTML = `
  21. <span
  22. class="tgico button-icon"
  23. style="
  24. width: 24px;
  25. height: 24px;
  26. display: flex;
  27. align-items: center;
  28. justify-content: center;
  29. "
  30. >
  31. <svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="11.98 0.62 190.05 213.4" style="width: 20px; height: 20px;">
  32. <path fill="currentColor" d="M202 95c0 47-33 85-77 94v25l-69-40 69-40v24a65 65 0 1 0-77-35l-27 13a95 95 0 1 1 181-40z"/>
  33. </svg>
  34. </span>
  35. `;
  36.  
  37. button.addEventListener("click", (event) => {
  38. event.stopPropagation();
  39.  
  40. const image = document.querySelector(".media-viewer-aspecter img");
  41. const video = document.querySelector(".ckin__video");
  42.  
  43. const mediaElement = image || video;
  44.  
  45. if (!mediaElement) return;
  46.  
  47. const mover = document.querySelector(".media-viewer-mover");
  48.  
  49. const videoThumbnail = document.querySelector(
  50. ".media-viewer-aspecter .canvas-thumbnail"
  51. );
  52.  
  53. let currentRotation = parseInt(mediaElement.dataset.rotation) || 0;
  54.  
  55. currentRotation += 90;
  56.  
  57. let originalWidth = mediaElement.dataset.originalWidth;
  58. let originalHeight = mediaElement.dataset.originalHeight;
  59.  
  60. if (!originalWidth || !originalHeight) {
  61. originalWidth = mover.style.width.replace("px", "");
  62. originalHeight = mover.style.height.replace("px", "");
  63.  
  64. mediaElement.dataset.originalWidth = originalWidth;
  65. mediaElement.dataset.originalHeight = originalHeight;
  66.  
  67. mediaElement.style.minWidth = originalWidth + "px";
  68. mediaElement.style.minHeight = originalHeight + "px";
  69. }
  70.  
  71. let newWidth, newHeight;
  72.  
  73. switch (currentRotation % 360) {
  74. case 90:
  75. case 270:
  76. newWidth = originalHeight;
  77. newHeight = originalWidth;
  78. break;
  79. default:
  80. newWidth = originalWidth;
  81. newHeight = originalHeight;
  82. break;
  83. }
  84.  
  85. mediaElement.dataset.rotation = currentRotation;
  86. mediaElement.style.transform = `rotate(${currentRotation}deg)`;
  87.  
  88. if (videoThumbnail) {
  89. videoThumbnail.dataset.rotation = currentRotation;
  90. videoThumbnail.style.transform = `rotate(${currentRotation}deg)`;
  91. }
  92.  
  93. mover.style.width = `${newWidth}px`;
  94. mover.style.height = `${newHeight}px`;
  95. });
  96.  
  97. return button;
  98. }
  99.  
  100. function addButtonToMediaViewerButtons() {
  101. const mediaViewerButtons = document.querySelector(".media-viewer-buttons");
  102.  
  103. if (mediaViewerButtons && !document.querySelector("#rotate-button")) {
  104. const downloadButton = mediaViewerButtons.querySelectorAll(".btn-icon")[2];
  105.  
  106. downloadButton.after(createButton());
  107. }
  108.  
  109. const mediaViewerAspecter = document.querySelector(
  110. ".media-viewer-aspecter img"
  111. );
  112.  
  113. if (mediaViewerAspecter) {
  114. mediaViewerAspecter.style.transition = "transform var(--open-duration)";
  115. }
  116.  
  117. const mediaViewerMover = document.querySelector(".media-viewer-mover");
  118.  
  119. if (mediaViewerMover) {
  120. mediaViewerMover.style.overflow = "visible";
  121. }
  122.  
  123. const video = document.querySelector(".ckin__video");
  124.  
  125. if (video) {
  126. video.style.transition = "transform var(--open-duration)";
  127. }
  128.  
  129. const videoThumbnail = document.querySelector(
  130. ".media-viewer-aspecter .canvas-thumbnail"
  131. );
  132.  
  133. if (videoThumbnail) {
  134. videoThumbnail.style.transition = "transform var(--open-duration)";
  135. }
  136. }
  137.  
  138. const observer = new MutationObserver(() => {
  139. addButtonToMediaViewerButtons();
  140. });
  141.  
  142. observer.observe(document.body, { childList: true, subtree: true });
  143.  
  144. addButtonToMediaViewerButtons();
  145. })();

QingJ © 2025

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