// ==UserScript== // @name Pixiv Previewer // @namespace // @version 1.27 // @description 显示大图预览,按热门度排序(pixiv_sk),批量下载。View Preview, Sort by favorite numbers, Bulk download.(仅搜索排行页生效, Only available in search and rank page) // @author Ocrosoft // @match https://www.pixiv.net/search.php* // @match https://www.pixiv.net/member_illust.php?mode=* // @match https://www.pixiv.net/ranking.php* // @grant none // @require http://code.jquery.com/jquery-2.1.4.min.js // @namespace https://github.com/Ocrosoft/PixivPreviewer // @downloadURL none // ==/UserScript== function log(text) { console.log(text); } /** * ---------------------------------------- 以下为 设置 部分 ---------------------------------------- */ // 注意: 设置部分以 Cookie 为准,此处表示没有 Cookie 时的默认设置 // 是否开启预览功能 var ENABLE_PREVIEW = true; // 是否开启排序功能 var ENABLE_SORT = true; // 每次加载的页数 var GETTING_PAGE_COUNT = 3; // 收藏量在此以下的不显示 var FAV_FILTER = 3; // true,使用新标签页打开图片;false,保持默认 var IS_LINK_BLANK = true; /** * ---------------------------------------- 以下为 预览功能 部分 ---------------------------------------- */ /** * 节点结构 * -div, [picList] * --div * ---figure * ----div, [picDiv] * -----a, [picHref] * ------img(图片节点), [picNode] * -----div(菜单) */ var dataDiv, picList, picDiv = [], picHref = [], picNode = []; // 相关元素,含义见上 var dataStr; // 更新后图片信息使用 json 保存在了 dataDiv 的 data-items 属性中 var imgData; // 保存解析后的 json var mousePos; // 鼠标位置 var SORT_END = false; // 是否排序完成 // 获取相关的元素 function getImageElements() { $('.popular-introduction').remove(); dataDiv = $('#js-mount-point-search-result-list'); dataStr = dataDiv.attr('data-items'); imgData = eval(dataStr); picList = dataDiv.children()[0]; var pics = $(picList).children(); picDiv = [], picHref = [], picNode = []; for (var i = 0; i < pics.length; i++) { picDiv.push(pics[i].childNodes[0].childNodes[0]); $(picDiv[i]).attr('data-index', i); picHref.push(picDiv[i].childNodes[0]); $(picHref[i]).attr('data-index', i); picNode.push($(picHref[i]).children('img')[0]); $(picNode[i]).attr('data-index', i); $(picNode[i]).attr('data-id', imgData[i].illustId); } } // 动图预览在相关页面调用的函数(自动执行,非动图页面无操作) (function animePreview() { // 动图下载 if (location.href.indexOf('medium') != -1) { var script = document.createElement('script'); script.src = 'https://greasyfork.org/scripts/30681-pixiv%E5%8A%A8%E5%9B%BE%E4%B8%8B%E8%BD%BD/code/Pixiv%E5%8A%A8%E5%9B%BE%E4%B8%8B%E8%BD%BD.user.js'; document.body.appendChild(script); } // 普通查看转换为全屏查看 if (location.href.indexOf('medium') != -1 && location.href.indexOf('animePreview') != -1) { location.href = location.href.replace('medium', 'ugoira_view'); return; } // 全图预览调节并返回 canvas 大小 if (location.href.indexOf('ugoira_view') != -1 && location.href.indexOf('animePreview') != -1) { var height = parseInt($('canvas').css('height').split('px')); var width = parseInt($('canvas').css('width').split('px')); var newHeight = 580 / width * height; $('canvas').css({ 'height': newHeight + 'px', 'width': 580 + 'px' }); var div = document.createElement('div'); $(div).addClass('embed'); div.innerHTML = '
'; $('canvas').parent()[0].appendChild(div); window.parent.iframeLoaded(newHeight + 25, 580); var reg = new RegExp('src.*zip'); var t = $('html')[0].innerHTML; var full = reg.exec(t)[0]; full = full.split(':"')[1]; $('#dl_full').click(function () { window.open(full); }); return; } })(); // iframe 加载完成时调用(动图预览) // arg: canvas 元素高,canvas 元素宽 function iframeLoaded(height, width) { $('.pixivPreview').children('iframe').css({ 'width': width + 20 + 'px', 'height': height + 20 + 'px' }); // 调整位置 var divX = mousePos.x, divY = mousePos.y; var screenWidth = document.documentElement.clientWidth; var screenHeight = document.documentElement.clientHeight; if (mousePos.x > screenWidth / 2) { divX -= width; } if ((mousePos.y - document.body.scrollTop) > screenHeight / 2) { divY -= height; } $('.pixivPreview').css({ 'left': divX + 'px', 'top': divY + 'px' }); $('.pixivPreview').children('iframe').css('display', ''); $('.pixivPreview').children('img').remove(); } // 测试图片是否有效 function validateImage(url) { url = url.replace('manga', 'manga_big'); url += '&page=0'; var xmlHttp = new XMLHttpRequest(); xmlHttp.open('GET', url, false); xmlHttp.send(null); var src = $($(xmlHttp.responseText)[$(xmlHttp.responseText).length - 1]).attr('src'); if (src.indexOf('.png') == -1) return true; else return false; } function pixivPreviewer() { // 开启预览功能 function activePreview() { // 鼠标移动到图片上显示预览图 $(picHref).mouseover(function (e) { // 按住 Ctrl键 不显示预览图 if (e.ctrlKey) { return; } // 从预览图移动到图片上,不应再次显示 try { if ($(e.relatedTarget.parentNode).hasClass('pixivPreview')) { return; } } catch (e) { } // 图片索引 var dataIndex = $(this).attr('data-index'); // 图片节点 var imgNode = picNode[dataIndex]; // 鼠标位置 mousePos = { x: e.pageX, y: e.pageY }; // 预览 Div var previewDiv = document.createElement('div'); $(previewDiv).css({ 'position': 'absolute', 'z-index': '999999' }); $(previewDiv).addClass('pixivPreview'); $(previewDiv).attr('data-index', dataIndex); // 添加 Div 到 body $('.pixivPreview').remove(); $('body')[0].appendChild(previewDiv); // 加载中图片节点 var loadingImg = new Image(); loadingImg.src = 'https://raw.githubusercontent.com/shikato/pixiv_sk/master/loading.gif'; $(loadingImg).css('position', 'absolute'); $(loadingImg).attr('data-index', dataIndex); previewDiv.appendChild(loadingImg); // 要显示的预览图节点 var loadImg = new Image(); $(loadImg).attr('data-index', dataIndex); previewDiv.appendChild(loadImg); // 表示显示的是原图的图标 var originIcon = new Image(); originIcon.src = 'https://source.pixiv.net/www/images/pixivcomic-favorite.png'; $(originIcon).css({ 'position': 'absolute', 'bottom': '0px', 'right': '0px', 'display': 'none' }); $(originIcon).attr('data-index', dataIndex); previewDiv.appendChild(originIcon); // 点击图标新网页打开原图 $(originIcon).click(function () { window.open($(previewDiv).children('img')[1].src); }); $(previewDiv).css({ 'left': mousePos.x + 'px', 'top': mousePos.y + 'px' }); // 显示预览图 // args: 图片地址数组,下标,原图地址数组 function viewImages(imgs, index, imgsOrigin) { if (!imgs || imgs.length == 0) return; if (index < 0) return; if (!imgsOrigin || imgsOrigin.length == 0 || imgs.length != imgsOrigin.length) return; if (!index) index = 0; // 绑定点击事件,Ctrl+左键 单击切换原图 if ($(previewDiv).children('script').length == 0) { loadImg.addEventListener('click', function (ev) { // 按住 Ctrl 来回切换原图 if (ev.ctrlKey) { if (loadImg.src.indexOf('origin') == -1) { viewImages(allImgsOrigin, parseInt($($('.pixivPreview').children('img')[1]).attr('img-index')), allImgs); } else { viewImages(allImgs, parseInt($($('.pixivPreview').children('img')[1]).attr('img-index')), allImgsOrigin); } } // 按住 Shift 点击图片新标签页打开原图 else if (ev.shiftKey) { window.open(allImgsOrigin[parseInt($($('.pixivPreview').children('img')[1]).attr('img-index'))]); } }); } // 多图时绑定点击事件,点击图片切换到下一张 if (index == 0 && imgs.length != 1 && $(previewDiv).children('._work').length == 0) { loadImg.addEventListener('click', function (e) { if (e.ctrlKey || e.shiftKey) return; var newIndex = parseInt($($('.pixivPreview').children('img')[1]).attr('img-index')) + 1; if (newIndex == allImgs.length) newIndex = 0; $('.pixivPreview').children('div').children('div').children('span')[0].innerHTML = (newIndex + 1) + '/' + allImgs.length; if (loadImg.src.indexOf('origin') == -1) { viewImages(allImgs, newIndex, allImgsOrigin); } else { viewImages(allImgsOrigin, newIndex, allImgs); } }); } // 右上角张数标记 if (imgs.length != 1 && index == 0 && $(previewDiv).children('._work').length == 0) { var iconDiv = document.createElement('div'); iconDiv.innerHTML = '
1/' + imgs.length + '
'; $(iconDiv).addClass('_work'); $(iconDiv).css({ 'position': 'absolute', 'top': '0px', 'display': 'none' }); $(iconDiv).attr('data-index', dataIndex); $(iconDiv.childNodes).attr('data-index', dataIndex); previewDiv.appendChild(iconDiv); } // 预加载 loadImg.src = ''; $(loadImg).css({ 'width': '', 'height': '', 'display': 'none' }); $(loadingImg).css('display', ''); $(originIcon).css('display', 'none'); $(iconDiv).css({ 'display': 'none' }); // 图片预加载完成 loadImg.addEventListener('load', function () { if (loadImg.src.indexOf('githubusercontent') != -1) return; // 调整图片大小 var width = loadImg.width, screenWidth = document.documentElement.clientWidth; var height = loadImg.height, screenHeight = document.documentElement.clientHeight; var viewHeight, viewWidth; // 长图 if (height > width) { viewHeight = screenHeight / 2; viewWidth = viewHeight / height * width; var scale = 1.0; while (viewWidth * scale > screenWidth / 2) { scale -= 0.01; } } // 宽图 else { viewWidth = screenWidth / 2; viewHeight = viewWidth / width * height; var scale = 1.0; while (viewHeight * scale > screenHeight / 2) { scale -= 0.01; } } $(loadImg).css({ 'height': viewHeight * scale + 'px', 'width': viewWidth * scale + 'px' }); $(previewDiv).css({ 'height': viewHeight * scale + 'px', 'width': viewWidth * scale + 'px' }); $(loadingImg).css({ 'left': viewWidth * scale / 2 - 24 + 'px', 'top': viewHeight * scale / 2 - 24 + 'px' }); $(loadImg).css('display', ''); $(loadingImg).css('display', 'none'); $(iconDiv).css({ 'display': '' }); if (loadImg.src.indexOf('origin') != -1) { $(originIcon).css({ 'display': '' }); } else { $(originIcon).css({ 'display': 'none' }); } // 调整图片位置 adjustDivPos(loadImg, previewDiv, screenWidth, screenHeight); // 第一次显示预览时将图片列表添加到末尾 if ($(previewDiv).children('script').length == 0) { var s = document.createElement('script'); // 输出预览图URL var tmp = "var allImgs=['"; tmp += imgs[0]; for (var i = 1; i < imgs.length; ++i) { tmp += "','" + imgs[i]; } tmp += "'];"; // 输出原图URL tmp += "var allImgsOrigin=['"; tmp += imgsOrigin[0]; for (var i = 1; i < imgsOrigin.length; ++i) { tmp += "','" + imgsOrigin[i]; } tmp += "'];"; // 输出 s.innerHTML = tmp; previewDiv.appendChild(s); } }); $(loadImg).attr('img-index', index); loadImg.src = imgs[index]; } // 进行 http 请求,获取预览图链接 var xmlHttp = new XMLHttpRequest(); xmlHttp.onreadystatechange = function () { if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { var resText = xmlHttp.responseText; // 单图 try { // 取得图片地址 // 预览图 var imgSource = RegExp('
[^>]*>'). exec(resText)[0].split('<')[2].split('\"')[1]; // 原图 var imgOrigin = RegExp('
')[1]. split('')[0])) !== null) { imgs.push(img[0]); } // 推出来的原图URL,暂时没有想到效率高的办法(imgs.length 次xmlHttpRequest) var imgsOrigin = []; var is_jpg = validateImage(xmlHttp.responseURL); for (var i = 0; i < imgs.length; ++i) { imgsOrigin.push(imgs[i].replace('img-master', 'img-original')); imgsOrigin[i] = imgsOrigin[i].replace('_master1200', ''); if (!is_jpg) imgsOrigin[i] = imgsOrigin[i].replace('.jpg', '.png'); } viewImages(imgs, 0, imgsOrigin); return; } catch (e) { // empty } } }; // 动图,illustType 值为2 if (imgData[dataIndex].illustType == 2) { $(previewDiv).children().remove(); previewDiv.innerHTML = '