Pixiv 工具箱

增强P站查看原图功能

当前为 2021-04-11 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Pixiv 工具箱
// @version      1.2.0
// @description  增强P站查看原图功能
// @author       sakura-flutter
// @namespace    https://github.com/sakura-flutter/tampermonkey-scripts
// @license      GPL-3.0
// @compatible   chrome Latest
// @compatible   firefox Latest
// @compatible   edge Latest
// @noframes
// @match        https://www.pixiv.net
// @match        https://www.pixiv.net/*
// @grant        window.onurlchange
// @grant        GM_getResourceText
// @grant        GM_addStyle
// @resource     viewerCSS https://cdn.jsdelivr.net/npm/viewerjs@1/dist/viewer.min.css
// @require      https://cdn.jsdelivr.net/npm/viewerjs@1/dist/viewer.min.js
// ==/UserScript==

/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
var __webpack_exports__ = {};

;// CONCATENATED MODULE: ./src/utils/selector.ts
const $ = document.querySelector.bind(document);
const $$ = document.querySelectorAll.bind(document);
;// CONCATENATED MODULE: ./src/utils/log.ts
const isDebug = "production" !== 'production';

function warn(...args) {
  isDebug && console.warn(...args);
}

function table(...args) {
  isDebug && console.table(...args);
}


;// CONCATENATED MODULE: ./src/scripts/pixiv/index.js
function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }

var id = 0;

function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }



/* global Viewer */

function main() {
  GM_addStyle(GM_getResourceText('viewerCSS'));
  GM_addStyle(['.viewer-backdrop { background-color: rgb(0 0 0 / 0.8) }', // 背景暗一点
  '.viewer-container .viewer-title { text-shadow: 1px 1px 1px #000 }', // 添加标题阴影 在图片是白底时显示得清楚点
  '.viewer-container .viewer-navbar ul, .viewer-container .viewer-navbar li { width: 66px; height: 110px }' // 加大导航栏
  ].join('')); // eslint-disable-next-line no-new

  new Previewer('figure [role="presentation"] a img', {
    includePathname: /^\/artworks\/(\w)+/
  });
}

var _el = _classPrivateFieldLooseKey("el");

var _options = _classPrivateFieldLooseKey("options");

var _viewer = _classPrivateFieldLooseKey("viewer");

var _init = _classPrivateFieldLooseKey("init");

var _process = _classPrivateFieldLooseKey("process");

var _getArtworks = _classPrivateFieldLooseKey("getArtworks");

var _createOriginalImgEls = _classPrivateFieldLooseKey("createOriginalImgEls");

var _preview = _classPrivateFieldLooseKey("preview");

class Previewer {
  constructor(el, options) {
    Object.defineProperty(this, _preview, {
      value: _preview2
    });
    Object.defineProperty(this, _createOriginalImgEls, {
      value: _createOriginalImgEls2
    });
    Object.defineProperty(this, _getArtworks, {
      value: _getArtworks2
    });
    Object.defineProperty(this, _init, {
      value: _init2
    });
    Object.defineProperty(this, _el, {
      writable: true,
      value: void 0
    });
    Object.defineProperty(this, _options, {
      writable: true,
      value: {
        includePathname: null
      }
    });
    Object.defineProperty(this, _viewer, {
      writable: true,
      value: null
    });
    Object.defineProperty(this, _process, {
      writable: true,
      value: function (event) {
        /* 这么多的判断多数是没有意义的
         * 只是为了日后可能失效,尽量避免影响原点击事件
         */
        if (!_classPrivateFieldLooseBase(this, _options)[_options].includePathname.test(location.pathname)) return;

        const artworks = _classPrivateFieldLooseBase(this, _getArtworks)[_getArtworks]();

        if (artworks.length === 0) return;
        let index = -1; // 比较5层深度应该足够了

        event.composedPath().slice(0, 5).find(target => {
          index = artworks.findIndex(artwork => artwork === target);
          return index > -1;
        });
        warn(event, index);
        if (index === -1) return;

        const originalArtworks = _classPrivateFieldLooseBase(this, _createOriginalImgEls)[_createOriginalImgEls](artworks);

        if (originalArtworks.length === 0) return;
        event.preventDefault();
        event.stopPropagation();
        event.stopImmediatePropagation(); // 释放上一次

        _classPrivateFieldLooseBase(this, _viewer)[_viewer]?.destroy();
        _classPrivateFieldLooseBase(this, _viewer)[_viewer] = _classPrivateFieldLooseBase(this, _preview)[_preview](originalArtworks, {
          initialViewIndex: index
        });
      }
    });
    _classPrivateFieldLooseBase(this, _process)[_process] = _classPrivateFieldLooseBase(this, _process)[_process].bind(this);
    _classPrivateFieldLooseBase(this, _el)[_el] = el;
    Object.assign(_classPrivateFieldLooseBase(this, _options)[_options], options);

    _classPrivateFieldLooseBase(this, _init)[_init]();
  }

}

var _init2 = function _init2() {
  window.addEventListener('click', _classPrivateFieldLooseBase(this, _process)[_process], true);
  window.addEventListener('urlchange', info => {
    warn('urlchange', info);

    if (_classPrivateFieldLooseBase(this, _viewer)[_viewer]) {
      _classPrivateFieldLooseBase(this, _viewer)[_viewer].destroy();

      _classPrivateFieldLooseBase(this, _viewer)[_viewer] = null;
    }
  });
};

var _getArtworks2 = function _getArtworks2() {
  return [...$$(_classPrivateFieldLooseBase(this, _el)[_el])];
};

var _createOriginalImgEls2 = function _createOriginalImgEls2(imgEls) {
  return imgEls.reduce((acc, img) => {
    const {
      parentNode
    } = img; // 原图在其父级a标签href上

    if (parentNode.tagName === 'A') {
      const image = new Image();
      image.src = parentNode.href;
      image.alt = img.alt;
      acc.push(image);
    }

    return acc;
  }, []);
};

var _preview2 = function _preview2(imgEls, viewerOpts) {
  const container = document.createElement('div');
  container.append(...imgEls);
  viewerOpts = Object.assign({
    navbar: imgEls.length > 1,
    loop: false,
    zoomRatio: 0.5,
    minZoomRatio: 0.1,
    maxZoomRatio: 1.5,

    viewed() {
      this.viewer.tooltip();
    }

  }, viewerOpts);
  const viewer = new Viewer(container, viewerOpts);
  viewer.show();
  warn('viewer:', container, viewer);
  return viewer;
};

main();
/******/ })()
;