NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name poco // @namespace http://tampermonkey.net/ // @version 0.1 // @description show all full-scale images by Ctrl+` // @author You // @match http://www.poco.cn/works/detail* // @grant none // @license MIT // @updateURL https://openuserjs.org/meta/dc165015/poco.meta.js // @downloadURL https://openuserjs.org/install/dc165015/poco.user.js // @copyright 2019, dc165015 (https://openuserjs.org/users/dc165015) // ==/UserScript== (function() { 'use strict'; let $ = window.jQuery; let srcs = []; let bigImgsCount = 0; let isBoardShowed = false; let slidesHandler, slidesInerval = 1000; let title = document.title; let $loadedBigImgBoxes = new Map(); let $thumbs = $('.cc_thumbs_item > img'); let $board = $('<div class="top-board"></div>'); setStyle(); setHotkey(); function showAllBigImgs(doShow = true) { if (doShow) { $(document.body).prepend($board); startShow(); } else { $board.detach(); $board.children().detach(); } } function startShow() { let srcs = getBigImgsSrc(); let i = bigImgsCount = srcs.length; while (i-- > 0) { try { showBigImgBy(srcs[i]); } catch (e) {} } } function getBigImgsSrc() { let srcs=[]; $thumbs.each((i, img)=>{ let src = img.src.replace('W120', 'H1920'); srcs.push(src); }); return srcs; } function showBigImgBy(src, $box, retryNo = 0) { let $loadedImgBox, $img; if (!$box && ($loadedImgBox = $loadedBigImgBoxes.get(src))) { $board.prepend($loadedImgBox); } else { $box = $box || createBigImgWithBox(src); $img = $box.find('img'); $img.length && initImg(); } function initImg() { setImgSrc($img, src); return new Promise((resolve, reject) => { var img = $img[0]; $board.prepend($box); $img.load(() => { $img.css('display', 'block'); updateTitle(); resolve(); }); img.onerror = img.onsuspend = img.onstalled = img.onemptied = () => { retryImg(src, $img, ++retryNo); reject(retryNo); }; }); } } function updateTitle() { let loadedCount = $board.find('img[style*="display: block;"]').length; document.title = loadedCount != bigImgsCount ? `${loadedCount}/${bigImgsCount}|${title}` : title; } function createBigImgWithBox(src) { let $img = $('<img class="full-img"/>'); let $box = $('<div class="full-img-box"></div>'); $box.append($img); $loadedBigImgBoxes.set(src, $box); listenDblClick(); return $box; function listenDblClick() { $box.dblclick((e) => { if (e.ctrlKey) { $box.detach(); bigImgsCount--; } else { reload$img($img); } }); } } function reload$img($img) { let src = $img.attr('src'); let index = src.indexOf('?'); src = index == -1 ? src : src.substring(0, src.indexOf('?')); setImgSrc($img, src); } function setImgSrc($img, src) { // src = src + '?' + Date.now(); $img.attr('src', src); } function retryImg(src, $img, retryNo) { if (retryNo < 10) { setTimeout(() => { console.warn(`retry to load img(${src}) the ${retryNo} time.`); showBigImgBy(src, $img, retryNo); }, 10000 * retryNo * retryNo); } } function setStyle() { let style = document.createElement('STYLE'); style.type = 'text/css'; style.innerHTML = ` .top-board { background-color: black; position: absolute; min-height: 100%; width: 100%; z-index: 10000; } .full-img-box { display: block; position: relative; width: 100%; height: 100vh; margin-bottom: 1px; } .full-img { position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; max-width: 100%; max-height: 100%; } .trigger-link { float: right; color: blue !important; } `; document.head.append(style); } function setHotkey() { let scrollOptions = { behavior: "auto", block: "start", inline: "nearest" }; document.addEventListener('keydown', (e) => { if (e.ctrlKey) { if (e.key == '`') { window.scrollTo(0,0); showAllBigImgs(isBoardShowed = !isBoardShowed); } else if (e.key == 'Backspace') { reset(); } } else if (isBoardShowed) { e.stopPropagation(); e.preventDefault(); if (e.key == 'ArrowDown') { scrollToImgBox('next'); } else if (e.key == 'ArrowUp') { scrollToImgBox('previous'); } else if (e.key == ' ') { doSlides(); } } }); function reset() { showAllBigImgs(isBoardShowed = false); } function getCurrentImgBoxInView() { let boxes = getBoxes(); let current; for (let i = 0; i < boxes.length; i++) { current = boxes[i]; if (window.scrollY >= current.offsetTop && window.scrollY <= current.offsetTop + current.scrollHeight) { break; } }; return current; } function getBoxes() { return $board.find('.full-img-box'); } function scrollToImgBox(direction = 'next') { let prev, next, current = getCurrentImgBoxInView(); switch (direction) { case 'previous': prev = current.previousElementSibling || current; prev && prev.scrollIntoView(scrollOptions); break; case 'next': next = current.nextElementSibling || current; next && next.scrollIntoView(scrollOptions); } } function doSlides() { if (slidesHandler) { stopSlides(); } else { startSlides(); } } function stopSlides() { clearInterval(slidesHandler); slidesHandler = void 0; } function startSlides() { let current = getCurrentImgBoxInView(); if (current) { let prev = current.previousElementSibling; if (!prev) { prev = current.nextElementSibling; while (prev && prev.nextElementSibling) { prev = prev.nextElementSibling; } } prev.scrollIntoView(scrollOptions); slidesHandler = setTimeout(() => startSlides(prev), slidesInerval); } } } })();