Zoom function for YouTube

YouTube video zoom feature

目前為 2020-09-10 提交的版本,檢視 最新版本

  1. "use strict";
  2. // ==UserScript==
  3. // @name Zoom function for YouTube
  4. // @name:ja YouTubeで動画をズーム
  5. // @description YouTube video zoom feature
  6. // @description:ja YouTubeの動画プレイヤーにズーム機能を追加します
  7. // @version 2.0.1
  8. // @include /https?:\/\/www\.youtube\.com.*/
  9. // @author sititou70
  10. // @namespace https://github.com/sititou70/
  11. // @run-at document-idle
  12. // @license MIT; https://opensource.org/licenses/MIT
  13. // ==/UserScript==
  14. (function () {
  15. // consts
  16. var SCRIPT_NAME = 'youtube video zoom';
  17. var VIDEO_CONTAINER_SELECTOR = '#movie_player';
  18. var VIDEO_SELECTOR = VIDEO_CONTAINER_SELECTOR + " video";
  19. // functions
  20. var getScaleFromVideo = function (video) {
  21. var scale_string = video.style.transform.match(/scale\((.+?)\)/);
  22. if (scale_string === null)
  23. return 1;
  24. var scale = parseFloat(scale_string[1]);
  25. if (isNaN(scale))
  26. return 1;
  27. return scale;
  28. };
  29. var zoomVideoToRect = function (video, rect) {
  30. var video_container = document.querySelector(VIDEO_CONTAINER_SELECTOR);
  31. if (video_container === null)
  32. return;
  33. var video_container_rect = video_container.getBoundingClientRect();
  34. var player_aspect_ratio = video_container_rect.width / video_container_rect.height;
  35. var selected_aspect_ratio = rect.width / rect.height;
  36. var fit_width = player_aspect_ratio < selected_aspect_ratio; // or height?
  37. var scale = fit_width ? video_container_rect.width / rect.width :
  38. video_container_rect.height / rect.height;
  39. var centering_offset = {
  40. x: fit_width ? 0 : (video_container_rect.width / scale - rect.width) / 2,
  41. y: fit_width ? (video_container_rect.height / scale - rect.height) / 2 :
  42. 0,
  43. };
  44. video.style.transform = "translateX(" + ((video_container_rect.width / 2) -
  45. (rect.top_left.x + rect.width / 2)) *
  46. scale + "px) translateY(" + ((video_container_rect.height / 2) -
  47. (rect.top_left.y + rect.height / 2)) *
  48. scale + "px) scale(" + scale + ")";
  49. video.style.transition = 'all 0.3s ease';
  50. };
  51. var drag_start_position;
  52. var handleDragStart = function (e) {
  53. var video = e.target;
  54. var video_rect = video.getBoundingClientRect();
  55. var scale = getScaleFromVideo(video);
  56. drag_start_position = {
  57. x: (e.clientX - video_rect.x) / scale,
  58. y: (e.clientY - video_rect.y) / scale,
  59. };
  60. };
  61. var handleDragEnd = function (e) {
  62. var video = e.target;
  63. var video_rect = video.getBoundingClientRect();
  64. var scale = getScaleFromVideo(video);
  65. var drag_end_position = {
  66. x: (e.clientX - video_rect.x) / scale,
  67. y: (e.clientY - video_rect.y) / scale,
  68. };
  69. var top_left = {
  70. x: Math.min(drag_start_position.x, drag_end_position.x),
  71. y: Math.min(drag_start_position.y, drag_end_position.y),
  72. };
  73. var bottom_right = {
  74. x: Math.max(drag_start_position.x, drag_end_position.x),
  75. y: Math.max(drag_start_position.y, drag_end_position.y),
  76. };
  77. var selected_rect = {
  78. top_left: top_left,
  79. bottom_right: bottom_right,
  80. width: bottom_right.x - top_left.x,
  81. height: bottom_right.y - top_left.y,
  82. };
  83. if (selected_rect.width <= 10 || selected_rect.height <= 10)
  84. return;
  85. zoomVideoToRect(video, selected_rect);
  86. video.click();
  87. };
  88. var setupZoomFeature = function () {
  89. var video = document.querySelector(VIDEO_SELECTOR);
  90. if (video === null)
  91. return;
  92. video.addEventListener('mousedown', handleDragStart);
  93. video.addEventListener('mouseup', handleDragEnd);
  94. };
  95. var onKeyPress = function (e) {
  96. var video = document.querySelector(VIDEO_SELECTOR);
  97. if (video === null)
  98. return;
  99. if (e.key === 'r')
  100. video.style.transform = '';
  101. };
  102. // main
  103. var main = function () {
  104. var document_observer = new MutationObserver(setupZoomFeature);
  105. document_observer.observe(document.body, {
  106. attributes: true,
  107. });
  108. document.addEventListener('keypress', onKeyPress);
  109. };
  110. console.log("[" + SCRIPT_NAME + "] loaded.");
  111. main();
  112. })();