Pixiv 工具箱

增强P站查看原图功能

目前為 2021-02-16 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Pixiv 工具箱
  3. // @version 1.1.0
  4. // @description 增强P站查看原图功能
  5. // @author sakura-flutter
  6. // @namespace https://github.com/sakura-flutter/tampermonkey-scripts
  7. // @license GPL-3.0
  8. // @compatible chrome Latest
  9. // @compatible firefox Latest
  10. // @compatible edge Latest
  11. // @noframes
  12. // @match https://www.pixiv.net
  13. // @match https://www.pixiv.net/*
  14. // @grant window.onurlchange
  15. // @grant GM_getResourceText
  16. // @grant GM_addStyle
  17. // @resource viewerCSS https://cdn.jsdelivr.net/npm/viewerjs@1/dist/viewer.min.css
  18. // @require https://cdn.jsdelivr.net/npm/viewerjs@1/dist/viewer.min.js
  19. // ==/UserScript==
  20.  
  21. /******/ (() => { // webpackBootstrap
  22. /******/ "use strict";
  23.  
  24. ;// CONCATENATED MODULE: ./src/utils/selector.js
  25. const $ = document.querySelector.bind(document);
  26. const $$ = document.querySelectorAll.bind(document);
  27. ;// CONCATENATED MODULE: ./src/utils/log.js
  28. const isDebug = "production" !== 'production';
  29.  
  30. function warn(...args) {
  31. isDebug && console.warn(...args);
  32. }
  33.  
  34. function table(...args) {
  35. isDebug && console.table(...args);
  36. }
  37.  
  38.  
  39. ;// CONCATENATED MODULE: ./src/scripts/pixiv/index.js
  40. function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }
  41.  
  42. var id = 0;
  43.  
  44. function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
  45.  
  46.  
  47.  
  48. /* global Viewer */
  49.  
  50. function main() {
  51. GM_addStyle(GM_getResourceText('viewerCSS'));
  52. GM_addStyle(['.viewer-backdrop { background-color: rgb(0 0 0 / 0.8) }', // 背景暗一点
  53. '.viewer-container .viewer-title { text-shadow: 1px 1px 1px #000 }' // 添加标题阴影 在图片是白底时显示得清楚点
  54. ].join('')); // eslint-disable-next-line no-new
  55.  
  56. new Previewer('figure [role="presentation"] a img', {
  57. includePathname: /^\/artworks\/(\w)+/
  58. });
  59. }
  60.  
  61. var _el = _classPrivateFieldLooseKey("el");
  62.  
  63. var _options = _classPrivateFieldLooseKey("options");
  64.  
  65. var _viewer = _classPrivateFieldLooseKey("viewer");
  66.  
  67. var _init = _classPrivateFieldLooseKey("init");
  68.  
  69. var _process = _classPrivateFieldLooseKey("process");
  70.  
  71. var _getArtworks = _classPrivateFieldLooseKey("getArtworks");
  72.  
  73. var _createOriginalImgEls = _classPrivateFieldLooseKey("createOriginalImgEls");
  74.  
  75. var _preview = _classPrivateFieldLooseKey("preview");
  76.  
  77. class Previewer {
  78. constructor(el, options) {
  79. Object.defineProperty(this, _preview, {
  80. value: _preview2
  81. });
  82. Object.defineProperty(this, _createOriginalImgEls, {
  83. value: _createOriginalImgEls2
  84. });
  85. Object.defineProperty(this, _getArtworks, {
  86. value: _getArtworks2
  87. });
  88. Object.defineProperty(this, _init, {
  89. value: _init2
  90. });
  91. Object.defineProperty(this, _el, {
  92. writable: true,
  93. value: void 0
  94. });
  95. Object.defineProperty(this, _options, {
  96. writable: true,
  97. value: {
  98. includePathname: null
  99. }
  100. });
  101. Object.defineProperty(this, _viewer, {
  102. writable: true,
  103. value: null
  104. });
  105. Object.defineProperty(this, _process, {
  106. writable: true,
  107. value: function (event) {
  108. /* 这么多的判断多数是没有意义的
  109. * 只是为了日后可能失效,尽量避免影响原点击事件
  110. */
  111. if (!_classPrivateFieldLooseBase(this, _options)[_options].includePathname.test(location.pathname)) return;
  112.  
  113. const artworks = _classPrivateFieldLooseBase(this, _getArtworks)[_getArtworks]();
  114.  
  115. if (artworks.length === 0) return;
  116. let index = -1; // 比较5层深度应该足够了
  117.  
  118. event.composedPath().slice(0, 5).find(target => {
  119. index = artworks.findIndex(artwork => artwork === target);
  120. return index > -1;
  121. });
  122. warn(event, index);
  123. if (index === -1) return;
  124.  
  125. const originalArtworks = _classPrivateFieldLooseBase(this, _createOriginalImgEls)[_createOriginalImgEls](artworks);
  126.  
  127. if (originalArtworks.length === 0) return;
  128. event.preventDefault();
  129. event.stopPropagation();
  130. event.stopImmediatePropagation(); // 释放上一次
  131.  
  132. _classPrivateFieldLooseBase(this, _viewer)[_viewer]?.destroy();
  133. _classPrivateFieldLooseBase(this, _viewer)[_viewer] = _classPrivateFieldLooseBase(this, _preview)[_preview](originalArtworks, {
  134. initialViewIndex: index
  135. });
  136. }
  137. });
  138. _classPrivateFieldLooseBase(this, _process)[_process] = _classPrivateFieldLooseBase(this, _process)[_process].bind(this);
  139. _classPrivateFieldLooseBase(this, _el)[_el] = el;
  140. Object.assign(_classPrivateFieldLooseBase(this, _options)[_options], options);
  141.  
  142. _classPrivateFieldLooseBase(this, _init)[_init]();
  143. }
  144.  
  145. }
  146.  
  147. var _init2 = function _init2() {
  148. window.addEventListener('click', _classPrivateFieldLooseBase(this, _process)[_process], true);
  149. window.addEventListener('urlchange', info => {
  150. warn('urlchange', info);
  151.  
  152. if (_classPrivateFieldLooseBase(this, _viewer)[_viewer]) {
  153. _classPrivateFieldLooseBase(this, _viewer)[_viewer].destroy();
  154.  
  155. _classPrivateFieldLooseBase(this, _viewer)[_viewer] = null;
  156. }
  157. });
  158. };
  159.  
  160. var _getArtworks2 = function _getArtworks2() {
  161. return [...$$(_classPrivateFieldLooseBase(this, _el)[_el])];
  162. };
  163.  
  164. var _createOriginalImgEls2 = function _createOriginalImgEls2(imgEls) {
  165. return imgEls.reduce((acc, img) => {
  166. const {
  167. parentNode
  168. } = img; // 原图在其父级a标签href上
  169.  
  170. if (parentNode.tagName === 'A') {
  171. const image = new Image();
  172. image.src = parentNode.href;
  173. image.alt = img.alt;
  174. acc.push(image);
  175. }
  176.  
  177. return acc;
  178. }, []);
  179. };
  180.  
  181. var _preview2 = function _preview2(imgEls, viewerOpts) {
  182. const container = document.createElement('div');
  183. container.append(...imgEls);
  184. viewerOpts = Object.assign({
  185. navbar: imgEls.length > 1,
  186. loop: false,
  187. zoomRatio: 0.5,
  188. minZoomRatio: 0.1,
  189. maxZoomRatio: 1.5,
  190.  
  191. viewed() {
  192. this.viewer.tooltip();
  193. }
  194.  
  195. }, viewerOpts);
  196. const viewer = new Viewer(container, viewerOpts);
  197. viewer.show();
  198. warn('viewer:', container, viewer);
  199. return viewer;
  200. };
  201.  
  202. main();
  203. /******/ })()
  204. ;

QingJ © 2025

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