Pixiv hover zoom

hover zoom for Pixiv

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey, Greasemonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

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

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्क्रिप्ट व्यवस्थापक एक्स्टेंशन इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्क्रिप्ट व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्टाईल व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

/* global window, document, jQuery */

// ==UserScript==
// @name         Pixiv hover zoom
// @namespace    https://github.com/rplus
// @version      1.1.2
// @description  hover zoom for Pixiv
// @author       Rplus
// @include      http://www.pixiv.net/*
// @grant        none
// ==/UserScript==

;(function(window, document, $) {
  'use strict';

  var phzw = $('#pixiv-hz-wrap');
  var phzwPos = [];
  var phzwPattern = /member_illust\.php\?mode=medium&illust_id=(\d+)/;
  var phzwAPI = '//www.pixiv.net/rpc/index.php?mode=get_illust_detail_by_ids&illust_ids=';
  var phzwAPICache = {};
  var imgSize = 'm'; // size: '240mw', m', 'big'
  var body = document.body;
  var isAutoLoadNextPage = true;
  var pager = {};

  var phzwToggle = function(_switch) {
    if (_switch) {
      phzw.css({
        'top': phzwPos[0],
        'left': phzwPos[1],
        'opacity': 1,
        'visibility': 'visible',
        'transform': 'translateX(' + phzwPos[2] + '%)'
      });
    } else {
      if ('0' !== phzw[0].style.opacity) {
        phzw.css({
          'visibility': 'hidden',
          'opacity': 0
        });
      }
    }
  };

  var getAllId = function() {
    var ids = [];

    $.each($('#wrapper').find('a'), function() {
      var _href = $(this).attr('href');
      var _match = _href && _href.match(phzwPattern);
      if (_match) {
        ids.push(_match.pop());
      }
    });

    return ids;
  };

  var pullIdsData = function(idsArr) {
    var deferred = $.Deferred();

    $.getJSON(phzwAPI + idsArr.join())
      .done(function(data) {

        if (!data.error) {
          for (var _item in data.body) {
            if (data.body.hasOwnProperty(_item)) {
              phzwAPICache[_item] = data.body[_item];
            }
          }
          deferred.resolve(); //update state
        } else {
          deferred.reject();
        }

      })
      .fail(function() {
        deferred.reject();
      });

    return deferred.promise();
  };

  var render = function(_id) {
    var data = phzwAPICache[_id];
    if (!data) { return; }

    if (_id !== phzw.data('id')) {
      var tpl = '<a href="/member_illust.php?mode=medium&illust_id=' + _id + '"><img src="' + data.url[imgSize] + '" title="' + data.illust_title + '"></a>';
      phzw.html(tpl);

      phzw.data('id', _id);
    }

    phzwToggle(true);
  };

  var updatePos = function(ele) {
    var eleRect = ele.getBoundingClientRect();
    phzwPos = [eleRect.top + body.scrollTop + eleRect.height, eleRect.left, -100 * eleRect.left / body.scrollWidth];
  };

  $(function() {

    // phzw init
    if (!phzw.length) {
      $(body).append('<div id="pixiv-hz-wrap" />');
      phzw = $('#pixiv-hz-wrap').css({
        'position': 'absolute',
        'visibility': 'hidden',
        'opacity': 0,
        'box-shadow': '0 0 0 3px #fff, 0 0 3px 3px',
        'transition': 'all .3s',
        'z-index': '1000'
      });

      phzw.on('mouseenter', function() {
        phzw.one('mouseleave', function() {
          phzwToggle(false);
        });
      });
    }

    // delay pre-load data in page
    setTimeout(function() {
      pullIdsData(getAllId());
    }, 1000);

    $('#wrapper').on('mouseenter.phzw', 'a', function(e) {
      var _match = $(this).attr('href').match(phzwPattern);

      if (!_match) { return; }

      var _id = _match.pop();

      e.stopPropagation();
      updatePos(this);

      if (phzwAPICache[_id]) {
        render(_id);
      } else {
        $.when(pullIdsData([_id]))
          .then(function() {
            render(_id);
          });
      }
    });

    $(document).on('click.phzw', function() {
      phzwToggle(false);
    });

    if (isAutoLoadNextPage) {
      pager.container = $('.pager-container').eq(0);

      if (!pager.container.length) { return; }

      pager.current = pager.container.find('li.current').text();
      pager.baseHref = pager.container.find('a')[0].href.replace(/&p=\d+/, '');
      pager.parent = $('._image-items').eq(0).parent();

      var autoLoadNextPage = function() {
        var nextPage = pager.current * 1 + 1;
        var nextPageHref = pager.baseHref + '&p=' + nextPage;
        var separator = '<hr style="border: 1px dashed #ccc" /><a href="' + nextPageHref + '">::: page: ' + nextPage + '</a>';

        if (nextPage > pager.max) {
          $(window).off('scroll.autoLoadNextPage');
          return;
        }

        // prepare a div container for ajax lond next-page content
        $('<div />').appendTo( pager.parent.append(separator) )
          .load(nextPageHref + ' ._image-items', function(_html) {
            pager.current = nextPage;
            pager.loading = false;

            // check for max page
            var nextPagerLists = _html.match(/pager-container.+?(<ul .+?<\/ul>)/).pop();
            pager.max = $(nextPagerLists).find('li').last().text() * 1;
          });
      };

      $(window).on('scroll.autoLoadNextPage', function() {
        if (!pager.loading && (pager.parent[0].getBoundingClientRect().bottom < document.documentElement.clientHeight * .3)) {
          pager.loading = true;
          autoLoadNextPage();
        }
      });
    }

    $('.link-item').eq(0).prepend('<button>-♥ preload all ♥-</button>').find('button').on('click', function(e) {
      e.preventDefault();

      $.when(pullIdsData(getAllId()))
        .then(function() {
          $.each(phzwAPICache, function(key, val) {
            // forcedly preload
            $('<img src="' + val.url[imgSize] + '">');
          });
        });

    });
  });

})(window, document, jQuery, undefined);