Zoom function for YouTube

YouTube video zoom feature

当前为 2020-09-11 提交的版本,查看 最新版本

  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.2
  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. video.style.transform = "translateX(" + ((video_container_rect.width / 2) -
  40. (rect.top_left.x + rect.width / 2)) *
  41. scale + "px) translateY(" + ((video_container_rect.height / 2) -
  42. (rect.top_left.y + rect.height / 2)) *
  43. scale + "px) scale(" + scale + ")";
  44. video.style.transition = 'all 0.3s ease';
  45. };
  46. var drag_start_position;
  47. var handleDragStart = function (e) {
  48. var video = e.target;
  49. var video_rect = video.getBoundingClientRect();
  50. var scale = getScaleFromVideo(video);
  51. drag_start_position = {
  52. x: (e.clientX - video_rect.x) / scale,
  53. y: (e.clientY - video_rect.y) / scale,
  54. };
  55. };
  56. var handleDragEnd = function (e) {
  57. var video = e.target;
  58. var video_rect = video.getBoundingClientRect();
  59. var scale = getScaleFromVideo(video);
  60. var drag_end_position = {
  61. x: (e.clientX - video_rect.x) / scale,
  62. y: (e.clientY - video_rect.y) / scale,
  63. };
  64. var top_left = {
  65. x: Math.min(drag_start_position.x, drag_end_position.x),
  66. y: Math.min(drag_start_position.y, drag_end_position.y),
  67. };
  68. var bottom_right = {
  69. x: Math.max(drag_start_position.x, drag_end_position.x),
  70. y: Math.max(drag_start_position.y, drag_end_position.y),
  71. };
  72. var selected_rect = {
  73. top_left: top_left,
  74. bottom_right: bottom_right,
  75. width: bottom_right.x - top_left.x,
  76. height: bottom_right.y - top_left.y,
  77. };
  78. if (selected_rect.width <= 10 || selected_rect.height <= 10)
  79. return;
  80. zoomVideoToRect(video, selected_rect);
  81. video.click();
  82. };
  83. var setupZoomFeature = function () {
  84. var video = document.querySelector(VIDEO_SELECTOR);
  85. if (video === null)
  86. return;
  87. video.addEventListener('mousedown', handleDragStart);
  88. video.addEventListener('mouseup', handleDragEnd);
  89. };
  90. var onKeyPress = function (e) {
  91. var video = document.querySelector(VIDEO_SELECTOR);
  92. if (video === null)
  93. return;
  94. if (e.key === 'r')
  95. video.style.transform = '';
  96. };
  97. // main
  98. var main = function () {
  99. var document_observer = new MutationObserver(setupZoomFeature);
  100. document_observer.observe(document.body, {
  101. attributes: true,
  102. });
  103. document.addEventListener('keypress', onKeyPress);
  104. };
  105. console.log("[" + SCRIPT_NAME + "] loaded.");
  106. main();
  107. })();