您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Provides some functions to download from pixiv
当前为
// ==UserScript== // @name Pixiv Download Assistant // @name:ja Pixiv Download Assistant // @description Provides some functions to download from pixiv // @description:ja pixiv に作品の保存を容易にするための機能を追加します // @namespace https://gf.qytechs.cn/ja/users/24052-granony // @author granony // @version 0.2.0 // @grant GM_xmlhttpRequest // @include http://www.pixiv.net/member_illust.php?* // @include http://www.pixiv.net/novel/show.php?* // @connect pixiv.net // @require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.0.0/jszip.min.js // @license MIT License // ==/UserScript== (function(){ "use strict;"; /************************************************************************* * 設定 *************************************************************************/ // 現在はなし /************************************************************************* * 共通の処理 *************************************************************************/ var pixiv = unsafeWindow.pixiv; if(typeof(pixiv)=="undefined"){ return; } console.log("pda: start"); var directLinkIcon = getDirectLinkIcon(); var isCreatingZip = false; var metaInfo = getMetaInfo(); console.log(metaInfo); // ページの種類によって作業を分岐 if(metaInfo.workType=="illust-single"){ processSingleIllust(); }else if(metaInfo.workType=="manga-single"){ processSingleManga(); }else if(metaInfo.workType=="illust-multi"){ if(metaInfo.pageMode=="cover"){ if(metaInfo.multiIllustDirection=="horizontal"){ processMultiMangaCover(); }else if(metaInfo.multiIllustDirection=="vertical"){ processMultiIllustCover(); } }else if(metaInfo.pageMode=="index"){ if(metaInfo.multiIllustDirection=="horizontal"){ processMultiMangaIndex(); }else if(metaInfo.multiIllustDirection=="vertical"){ processMultiIllustIndex(); } } }else if(metaInfo.workType=="ugoira"){ processUgoira(); }else if(metaInfo.workType=="novel"){ processNovel(); } /************************************************************************* * 各ページの処理 *************************************************************************/ /* 1枚で構成されたmanga ページの処理 */ function processSingleManga(){ var origURL; var bigPageURL = "http://www.pixiv.net/member_illust.php?mode=big&illust_id="+metaInfo.workId; var zipButton; // 原寸画像の URL を取得,その後Zipボタンと直リンクボタンを生成 GM_xmlhttpRequest({ method: "GET", url: bigPageURL, headers: { referer: window.location.href, }, onload: function(xhr){ var parser = new DOMParser(); var dom = parser.parseFromString(xhr.responseText, "text/html"); origURL = dom.getElementsByTagName("img")[0].src; addDirectLink(); zipButton = addZipButtonInCoverPage(); setZipButtonHandlerForSingleIllustManga(zipButton, origURL); } }); /* 直リンクボタンを生成する */ function addDirectLink(){ addDirectLinkButtonStyle(); var button = createDirectLinkButton(origURL); var worksDisplay = document.getElementsByClassName("works_display")[0]; var thumbnail = worksDisplay.getElementsByClassName("_work")[0]; worksDisplay.insertBefore(button, thumbnail); } } /* 複数枚で構成された漫画について,cover ページの処理 */ function processMultiMangaCover(){ var zipButton = addZipButtonInCoverPage(); setZipButtonHandlerForMultiIllustManga(zipButton); } /* 複数枚で構成された漫画について,indexページの処理 */ function processMultiMangaIndex(){ var zipButton = addZipButton(); setZipButtonHandlerForMultiIllustManga(zipButton); function addZipButton(){ var container = document.getElementsByClassName("panel-container")[0]; var button = document.createElement("li"); button.innerHTML = 'ZIP'; button.style = 'display:inline-block; margin-left: 20px; cursor:pointer; background-color: #999; ' + 'font-weight:bold; color: #FFF; padding:5px; border-radius:5px;'; container.appendChild(button); return button; } } /* 1枚で構成されたイラストの処理 */ function processSingleIllust(){ var origURL = document.getElementsByClassName("_illust_modal")[0] .getElementsByTagName("img")[0] .getAttribute("data-src"); addDirectLink(); var zipButton = addZipButtonInCoverPage(); setZipButtonHandlerForSingleIllustManga(zipButton, origURL); function addDirectLink(){ addDirectLinkButtonStyle(); var button = createDirectLinkButton(origURL); var worksDisplay = document.getElementsByClassName("works_display")[0]; var thumbnail = worksDisplay.getElementsByClassName("_layout-thumbnail")[0]; worksDisplay.insertBefore(button, thumbnail); } } /* 複数枚で構成されたイラストについて,cover ページの処理 */ function processMultiIllustCover(){ var zipButton = addZipButtonInCoverPage(); setZipButtonHandlerForMultiIllustManga(zipButton); } /* 複数枚で構成されたイラストについて,index ページの処理 */ function processMultiIllustIndex(){ addDirectLinks(); var zipButton = addZipButton(); setZipButtonHandlerForMultiIllustManga(zipButton); function addDirectLinks(){ addDirectLinkButtonStyle(); var containers = document.getElementsByClassName('item-container'); for (var i = 0; i < containers.length; i++) { (function () { var container = containers[i]; var image = container.getElementsByClassName('image') [0]; var fsc = container.getElementsByClassName('full-size-container') [0]; var mangaBigURL = fsc.href; GM_xmlhttpRequest({ method: "GET", url: mangaBigURL, onload: function(xhr){ var parser = new DOMParser(); var dom = parser.parseFromString(xhr.responseText, "text/html"); var origURL = dom.getElementsByTagName("img")[0].src; var uiContainer = document.createElement('div'); uiContainer.style = 'display:inline-block;position:relative; width:37px;'; var button = createDirectLinkButton(origURL); //button.style = "position: absolute; display:block; top:40px;margin: 5px 5px 0 0;"; button.style.margin = "5px 0 0 0"; fsc = container.removeChild(fsc); uiContainer.appendChild(fsc); uiContainer.appendChild(button); container.insertBefore(uiContainer, image); } }); })(); } } function addZipButton() { var pageMenu = document.getElementsByClassName('page-menu') [0]; var button = document.createElement('div'); button.innerHTML = 'ZIP'; button.style = 'display:inline-block; margin-left: 5px; cursor:pointer; background-color: #FFF; ' + 'font-weight:bold; color: #999; padding:5px; border-radius:5px;'; pageMenu.appendChild(button); return button; } } /* うごイラの処理 */ function processUgoira(){ var zipButton = addZipButtonInCoverPage(); zipButton.addEventListener("click",function(){ if(isCreatingZip){return;} isCreatingZip = true; zipButton.setAttribute("class", "button-on"); createZipWrapper(); }); function createZipWrapper(){ var framesText=""; for(var i=0; i<pixiv.context.ugokuIllustFullscreenData.frames.length; i++){ var frame = pixiv.context.ugokuIllustFullscreenData.frames[i]; framesText+='{file:"'+frame.file+'", delay:'+frame.delay+'},'; } var player = document.getElementsByClassName("player")[0]; var canvas = player.getElementsByTagName("canvas")[0]; var cstyle = getComputedStyle(canvas,"null"); var defaultSizeText='width:'+canvas.width+',height:'+canvas.height; var ugoiraHTML = getUgoiraHTML(framesText, defaultSizeText); var url = pixiv.context.ugokuIllustFullscreenData.src; console.log(url); GM_xmlhttpRequest({ method: 'GET', url: url, overrideMimeType: 'text/plain; charset=x-user-defined', headers: {referer: window.location.href,}, onload: function (xhr) { var zip = new JSZip(); zip.file("ugoira.html",ugoiraHTML); zip.folder("src").loadAsync(xhr.responseText).then(function(){ zip.generateAsync({ type:"blob", }).then(function(content){ isCreatingZip = false; zipButton.setAttribute("class", "_button"); var zipURL = window.URL.createObjectURL(content); var zipFileName = getZipFileName(); makeUserDownloadFile(zipURL, zipFileName); }); }); }, }); } } /* 小説の処理 */ function processNovel(){ var isExpanded = false; var zipButton = addZipButtonInCoverPage(); var expandButton = addExpandButton(); zipButton.addEventListener("click", function(){ if(isCreatingZip){return;} isCreatingZip = true; zipButton.setAttribute("class", "button-on"); createZipWrapper(); }); expandButton.addEventListener("click", function(){ if(isExpanded){return;} expandButton.setAttribute("class", "button-on"); expandAllPages(document); hideScrollFollower(document); hidePageController(document); isExpanded = true; // ボタン連打を気にするなら,expandButton 内で設定したほうが良い }); function addExpandButton(){ var buttonContainer = document.createElement("div"); buttonContainer.style = "display:inline-block; line-height:20px; margin-right:10px; padding-left:0; padding-right:0"; var button = document.createElement("a"); button.setAttribute("class", "_button"); button.innerHTML = "Expand All"; buttonContainer.appendChild(button); var bookmarkContainer = document.getElementsByClassName("bookmark-container")[0]; bookmarkContainer.insertBefore(buttonContainer, bookmarkContainer.firstChild); return button; } function createZipWrapper(){ var html = getHTML(); var links = document.getElementsByTagName("link"); var imgs = document.getElementsByTagName("img"); var resourceURLs = []; var linkNum = 0; var imgNum = 0; var resourceNum = 0; var downloadedURLs = {}; var zip = new JSZip(); zip.file("novel.html", html); downloadLinkHref(); /* link 要素が外部のリソースを参照している場合,ダウンロードする */ function downloadLinkHref(){ if(linkNum>=links.length){ downloadResource(); return; } var link = links[linkNum]; linkNum++; if(link.rel=="stylesheet" && link.href.match(/^http/) && !downloadedURLs[link.href] ){ downloadedURLs[link.href]=true; console.log(link.href); GM_xmlhttpRequest({ method: "GET", url: link.href, onload:function(xhr){ var fileName = getFileName(link.href); var file = xhr.responseText; storeResourceURLs(file, link.href); file = modifyCSS(file); zip.folder("src").file(fileName, file); downloadLinkHref(); } }); }else{ downloadLinkHref(); } } function downloadBackgroundImage(){ var bStyle = getComputedStyle(document.body, null); if(bStyle.backgroundImage && bStyle.backgroundImage!="none"){ var url = bStyle.backgroundImage.match(/"([^"]+)/)[1]; downloadedURLs[url] = true; console.log(url); GM_xmlhttpRequest({ method: "GET", url: url, overrideMimeType: 'text/plain; charset=x-user-defined', headers: {referer: window.location }, onload:function(xhr){ var file = getFileName(url); zip.folder("src").file(file, xhr.responseText,{binary:true}); downloadImgSrc(); } }); }else{ downloadImgSrc(); } } // スタイルシートを解析して,外部リソースのURLを保存 function storeResourceURLs(text, stylesheetURL){ var url0s = text.match(/url\(['"][^data]([^"']+)["']\)/g); if(!url0s){return;} for (var i=0; i<url0s.length; i++){ var url0 = url0s[i]; var url1 = url0.match(/["'](.+)["']/)[1]; if( url1.match(/(png|jpg|gif)$/) ){ var url; if(url1.match(/^http/)){ url = url1; }else if(url1.match(/^\//)){ url = getOrigin(stylesheetURL)+url1; }else{ url = getDir(stylesheetURL)+url1; console.log(url); url = url.replace(/[^/]*?\/\.\.\//,""); url = url.replace(/[^/]*?\/\.\//,""); } resourceURLs.push(url); console.log(url); } } } // スタイルシートのパスを変更 function modifyCSS(text){ text = text.replace(/(url\(["'][^data])[^"']+\//g, "$1/"); return text; } function downloadResource(){ if(resourceNum>=resourceURLs.length){ downloadBackgroundImage(); return; } var url = resourceURLs[resourceNum]; resourceNum++; if(!downloadedURLs[url] && !url.match(/\.\./)){ downloadedURLs[url] = true; console.log(url); GM_xmlhttpRequest({ method: "GET", url: url, overrideMimeType: 'text/plain; charset=x-user-defined', headers: {referer: window.location }, onload: function(xhr){ var file = getFileName(url); zip.folder("src").file(file, xhr.responseText,{binary:true}); downloadResource(); } }); }else{ downloadResource(); } } function downloadImgSrc(){ if(imgNum>=imgs.length){ makeUserDownloadZip(); return; } var img = imgs[imgNum]; imgNum++; if(!downloadedURLs[img.src]){ downloadedURLs[img.src] = true; console.log(img.src); GM_xmlhttpRequest({ method: "GET", url: img.src, overrideMimeType: 'text/plain; charset=x-user-defined', headers: {referer: window.location.href }, onload:function(xhr){ var file = getFileName(img.src); zip.folder("src").file(file, xhr.responseText,{binary:true}); downloadImgSrc(); } }); }else{ downloadImgSrc(); } } function makeUserDownloadZip(){ isCreatingZip = false; zipButton.setAttribute("class","_button"); zip.generateAsync({ type: 'blob' }).then(function (content) { var zipURL = window.URL.createObjectURL(content); var zipFileName = getZipFileName(); makeUserDownloadFile(zipURL, zipFileName); }); } // document のコピーをとり, // オフラインの閲覧に適した形式に変更した html をテキストとして返す function getHTML(){ // DOM を変更 var parser = new DOMParser(); var serializer = new XMLSerializer(); var newdoc = parser.parseFromString(serializer.serializeToString(document), "text/html"); expandAllPages(newdoc); removeScript(newdoc); hideScrollFollower(newdoc); hidePageController(newdoc); hideToolMenu(newdoc); hideToolBarItems(newdoc); // HTML をテキストにし,パスを変更 var html = new XMLSerializer().serializeToString(newdoc); return modifyHTML(html); } } // 全ページを展開する // expandButton 経由と zipButton 経由とで呼びだされる // isExpanded のフラグは expandButton クリック時にのみセットされている function expandAllPages(dom){ if(isExpanded){return;} var novelPages = dom.getElementsByClassName("novel-page"); for(var i=0; i<novelPages.length; i++){ var novelPage = novelPages[i]; novelPage.style.display = "block"; novelPage.style.borderWidth = "1px"; novelPage.style.borderColor = "#999999"; novelPage.style.borderStyle = "none none solid none"; novelPage.innerHTML = '<p style="text-align:left;color:#999999;margin-bottom:2em;" id="'+(i+1)+'">page: '+(i+1)+'</p>'+novelPage.innerHTML; } var script = document.createElement('script'); // ページ内遷移を強制するためのアドホックな対処 script.text = ` $("a.novel-jump").click(function(event){ var url = event.currentTarget.href; var targetId = url.match(/#(.+)/)[1]; var target = document.getElementById(targetId); var rect = target.getBoundingClientRect(); var positionY = rect.top + window.pageYOffset; window.scrollTo( 0, positionY ); }); $("a.novel-jump").click(function(event){event.preventDefault()}); $("a.novel-jump").mouseup(function(event){event.preventDefault()}); $(".novel-outline a").click(function(event){ var url = event.currentTarget.href; var targetId = url.match(/#(.+)/)[1]; var target = document.getElementById(targetId); var rect = target.getBoundingClientRect(); var positionY = rect.top + window.pageYOffset; window.scrollTo( 0, positionY ); }); $(".novel-outline a").click(function(event){event.preventDefault()}); $(".novel-outline a").mouseup(function(event){event.preventDefault()}); `; document.head.appendChild(script).remove(); return dom; } function modifyHTML(html){ // link href=* のパスを変更 html = html.replace(/(<link[^>]*?href=")[^"]*\//g, '$1src/'); // パスの? 以降を削除 html = html.replace(/(<link[^>]*?href="[^"?]*)\?[^"]*/g,'$1'); // img src=* のパスを変更 html = html.replace(/(<img[^>]*?src=")[^"]*\//g, '$1src/'); // a href=*のパスを変更 html = html.replace(/(<a[^>]*?href=")\//g, '$1'+getOrigin(window.location.href)); // 背景画像のパスを変更 html = html.replace(/(background.*url\(')http[^']*\//g,"$1src/"); return html; } function hideScrollFollower(dom){ var scrollFollower = dom.getElementsByClassName("scroll-follower")[0]; scrollFollower.innerHTML = ""; //scrollFollower.parentNode.removeChild(scrollFollower); } function hidePageController(dom){ var pagers = dom.getElementsByClassName("pager"); for(var i=0; i<pagers.length; i++){ pagers[i].innerHTML = ""; } } function removeScript(dom){ // なぜか二重ループを回さないと消えない for (var j=0; j<10; j++){ var scripts = dom.getElementsByTagName("script"); for(var i=0; i<scripts.length; i++){ var script = scripts[i]; script.parentNode.removeChild(script); } } } // 右下の「pixiv sketch」等を非表示にする function hideToolMenu(dom){ var toolMenu = dom.getElementsByClassName("_toolmenu")[0]; toolMenu.style.display = "none"; //toolMenu.parentNode.removeChild(toolmenu); } // 右下の「サムネイルフィルター設定」を非表示にする function hideToolBarItems(dom){ var toolbarItems = dom.getElementById("toolbar-items"); toolbarItems.style.display = "none"; //toolbarItems.parentNode.removeChild(toolbarItems); } } /* メタ情報を取得 */ function getMetaInfo(){ var info = { workType: "", // illust-single, illust-multi, manga-single, ugoira, novel multiIllustDirection: "", // horizontal, vertical pageMode: "", // cover, index illustSize: "", // [width, height] workId: "", workTitle: "", authorName: "", authorId: "", }; // ユーザーの画像一覧を閲覧時に,ユーザーのIDが取得されてしまうが,害はない var url = location.href; info.workId = url.match(/id=(\d+)/)[1]; if(url.match(/novel/)){ info.workType = "novel"; info.workTitle = document.getElementsByClassName("work-info")[0] .getElementsByClassName("title")[0].innerHTML; }else if(url.match(/mode=medium/)){ info.pageMode = "cover"; info.workTitle = document.getElementsByClassName("work-info")[0] .getElementsByClassName("title")[0].innerHTML; var worksDisplay = document.getElementsByClassName("works_display")[0]; if(worksDisplay.getElementsByClassName("_ugoku-illust-player-container")[0]){ info.workType = "ugoira"; } else if(worksDisplay.getElementsByClassName("multiple")[0]){ info.workType = "illust-multi"; if(worksDisplay.getElementsByClassName("ltr")[0] || worksDisplay.getElementsByClassName("rtl")[0]){ info.multiIllustDirection = "horizontal"; }else{ info.multiIllustDirection = "vertical"; } } else{ if(document.getElementsByClassName("_illust_modal")[0]){ info.workType = "illust-single"; }else{ info.workType = "manga-single"; } } }else if(url.match(/mode=manga/)){ info.pageMode = "index"; info.workType = "illust-multi"; if(document.getElementsByClassName("_book-viewer")[0]){ info.multiIllustDirection = "horizontal"; info.workTitle = document.getElementsByTagName("title")[0].innerHTML; }else{ info.multiIllustDirection = "vertical"; info.workTitle = document.getElementsByClassName("thumbnail-container")[0] .getElementsByTagName("h1")[0].getElementsByTagName("a")[0].innerHTML; } } return info; } /************************************************************************** * 下請けの関数 **************************************************************************/ function getMimeType(url){ var suffix = url.match(/.*\.(.+)$/) [1]; return suffix == 'jpg' ? 'image/jpg' : suffix == 'png' ? 'image/png' : suffix == 'gif' ? 'image/gif' : undefined; } function getFileName(url){ return url.match(/.+\/([^\?#]*)/)[1]; } function getFileName0(url){ return url.match(/.+\/(.*)/)[1]; } function getDir(url){ return url.match(/^.+\//)[0]; } function getOrigin(url){ return url.match(/^.*:\/\/[^/]+/); } function modifyImageFileName(name){ return name.replace(/_p(\d)\./,"_p0$1."); } function makeUserDownloadFile(url, fileName){ var dummy = document.createElement('a'); dummy.href = url; dummy.download = fileName; document.body.appendChild(dummy); dummy.click(); document.body.removeChild(dummy); } function getZipFileName(){ var title = metaInfo.workTitle; title = title.replace(/[\\\/:\;\*\?\"<>\|]/g,"_"); return "pixiv_"+metaInfo.workId+"_"+metaInfo.workTitle+".zip"; } function addZipButtonInCoverPage(){ var buttonContainer = document.createElement("div"); buttonContainer.style = "display:inline-block; line-height:20px; margin-right:10px;"; var button = document.createElement("a"); button.setAttribute("class", "_button"); button.innerHTML = "Download as Zip"; buttonContainer.appendChild(button); var bookmarkContainer = document.getElementsByClassName("bookmark-container")[0]; bookmarkContainer.insertBefore(buttonContainer, bookmarkContainer.firstChild); return button; } function addDirectLinkButtonStyle(){ var style = document.createElement("style"); document.head.appendChild(style); style.sheet.insertRule(".pda_direct_link{"+ "display:inline-block;width:20px;height:20px;padding:5px;margin:5px 0 0 0;"+ "border-radius: 5px; border-style:none; border-width:1px; border-color:#d6dee5;"+ "background-image:url("+directLinkIcon+");}",0); } function createDirectLinkButton(url){ var buttonContainer = document.createElement("div"); buttonContainer.style = "text-align:left;"; var button = document.createElement("a"); button.href = url; button.setAttribute("class", "pda_direct_link"); buttonContainer.appendChild(button); button.addEventListener('mouseenter', function () { button.style.borderStyle = 'solid'; }); button.addEventListener('mouseleave', function () { button.style.borderStyle = 'none'; }); return buttonContainer; } function setZipButtonHandlerForSingleIllustManga(zipButton, origURL){ zipButton.addEventListener("click",function(){ if(isCreatingZip){return;} isCreatingZip = true; zipButton.setAttribute("class", "button-on"); var zip = new JSZip(); GM_xmlhttpRequest({ method: "GET", url: origURL, overrideMimeType: 'text/plain; charset=x-user-defined', headers: {referer: window.location.href,}, onload:function(xhr){ var imgFileName = modifyImageFileName(getFileName(origURL)); zip.file(imgFileName, xhr.responseText,{binary:true}); zip.generateAsync({ type: 'blob' }).then(function (content) { isCreatingZip = false; zipButton.setAttribute("class", "_button"); var zipURL = window.URL.createObjectURL(content); var zipFileName = getZipFileName(); makeUserDownloadFile(zipURL, zipFileName); }); }, }); }); } function setZipButtonHandlerForMultiIllustManga(zipButton){ zipButton.addEventListener("click", function(){ if(isCreatingZip){return;} isCreatingZip = true; if(metaInfo.pageMode=="cover"){ zipButton.setAttribute("class", "button-on"); GM_xmlhttpRequest({ method: "GET", url: "http://www.pixiv.net/member_illust.php?mode=manga&illust_id="+metaInfo.workId, onload: function(xhr){ var parser = new DOMParser(); var dom = parser.parseFromString(xhr.responseText, "text/html"); createZipWrapper(dom); }, }); }else{ createZipWrapper(document); } }); function createZipWrapper(dom) { var html = new XMLSerializer().serializeToString(dom); // manga と illust で処理を分ける必要があるかも(ないかも) var totalPage = html.match(/pixiv\.context\.images/g).length-1; var pageURLList = []; for (var i=0; i<totalPage; i++){ pageURLList.push("http://www.pixiv.net/member_illust.php?mode=manga_big&illust_id="+metaInfo.workId+"&page="+i); } var zip = new JSZip(); var pageNum = 0; createZip(); function createZip(){ zipButton.innerHTML = pageNum+"/"+totalPage; var pageURL = pageURLList[pageNum]; downloadBigPage(); function downloadBigPage(){ GM_xmlhttpRequest({ method: "GET", url: pageURL, onload: function(xhr){ var parser = new DOMParser(); var dom = parser.parseFromString(xhr.responseText, "text/html"); var imageURL = dom.getElementsByTagName("img")[0].src; var type = getMimeType(imageURL); if (!type) { alert('undefined file type for: ' + imageURL); return; } downloadOriginalImage(imageURL); } }); } function downloadOriginalImage(imageURL){ console.log(imageURL); GM_xmlhttpRequest({ method: 'GET', url: imageURL, overrideMimeType: 'text/plain; charset=x-user-defined', headers: { referer: window.location.href, //origin: getOrigin(window.location.href), }, onload: function (xhr) { var file = modifyImageFileName(getFileName(imageURL)); zip.file(file, xhr.responseText, { binary: true }); pageNum++; if (pageNum < pageURLList.length) { setTimeout(createZip, 1000); } else { makeUserDownloadZip(); } }, }); } function makeUserDownloadZip(){ isCreatingZip = false; if(metaInfo.pageMode=="cover"){ zipButton.setAttribute("class", "_button"); zipButton.innerHTML = "Downloas as Zip"; }else{ zipButton.innerHTML = "ZIP"; } zip.generateAsync({ type: 'blob' }).then(function (content) { var zipURL = window.URL.createObjectURL(content); var zipFileName = getZipFileName(); makeUserDownloadFile(zipURL, zipFileName); }); } } } } /*************************************************************************** * Resources ***************************************************************************/ // 直リンク用アイコンの SVG データ function getDirectLinkIcon(){ return "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgd2lkdGg9IjMwIiBoZWlnaHQ9IjMwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogPCEtLSBDcmVhdGVkIHdpdGggU1ZHLWVkaXQgLSBodHRwOi8vc3ZnLWVkaXQuZ29vZ2xlY29kZS5jb20vIC0tPgoKIDxnPgogIDx0aXRsZT5MYXllciAxPC90aXRsZT4KICA8cmVjdCByeT0iMSIgcng9IjEiIGZpbGw9IiNjY2NjY2MiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLXdpZHRoPSI1IiBzdHJva2UtZGFzaGFycmF5PSJudWxsIiBzdHJva2UtbGluZWpvaW49Im51bGwiIHN0cm9rZS1saW5lY2FwPSJudWxsIiBzdHJva2Utb3BhY2l0eT0iMCIgeD0iMiIgeT0iMjIiIHdpZHRoPSIyNiIgaGVpZ2h0PSI3IiBpZD0ic3ZnXzEiLz4KICA8cGF0aCB0cmFuc2Zvcm09InJvdGF0ZSgxODAsIDE1LjAwMiwgMTEuODU1NSkiIGlkPSJzdmdfMiIgZD0ibTQuNTAwMTcsMTEuODMxMjJsMTAuNTAxODMsLTEwLjMzMTM2bDEwLjUwMTgxMSwxMC4zMzEzNmwtNS4yNTA0NDEsMGwwLDEwLjM3OTg0bC0xMC41MDI2NywwbDAsLTEwLjM3OTg0bC01LjI1MDUzLDBsMCwweiIgc3Ryb2tlLW9wYWNpdHk9IjAiIHN0cm9rZS1saW5lY2FwPSJudWxsIiBzdHJva2UtbGluZWpvaW49Im51bGwiIHN0cm9rZS1kYXNoYXJyYXk9Im51bGwiIHN0cm9rZS13aWR0aD0iNSIgc3Ryb2tlPSIjMDAwMDAwIiBmaWxsPSIjY2NjY2NjIi8+CiA8L2c+Cjwvc3ZnPg=="; } // うごイラビューワー function getUgoiraHTML(frames, defaultSize){ var template = `<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>ugougo</title> <script> "use strict"; var frames = [$frames]; // [{file:"000000.jpg",delay:250},{file:"000001.jpg",delay:500},] var canvasDefaultSize = {$defaultSize}; // {width: "600", height: "400"} var aspectRatio = undefined; var frameNum = 0; var canvasMode = "default"; // 起動 window.onload = function(){ loadImages(); } // 全フレームの画像を読み込む function loadImages(){ //console.log("loadImages:",frameNum); var frame = frames[frameNum]; frame.image = document.createElement("img"); frame.image.addEventListener("load", function(){ frame.width = frame.image.width; frame.height = frame.image.height; if(!aspectRatio){ aspectRatio = frame.width/frame.height; } frameNum++; if(frameNum>=frames.length){ frameNum = 0; setCanvas(); drawCanvas(); }else{ loadImages(); } }); frame.image.src = "src/"+frame.file; }; // canvas の設定 function setCanvas(){ var canvas = document.getElementById("canvas"); var changeCanvasPosition = function(){ var bWidth = document.documentElement.clientWidth; var bHeight = document.documentElement.clientHeight; canvas.style.left = (bWidth-canvas.width)/2+"px"; canvas.style.top = (bHeight-canvas.height)/2+"px"; } var changeCanvasSize = function(){ var bWidth = document.documentElement.clientWidth; var bHeight = document.documentElement.clientHeight; var fWidth = frames[0].width; var fHeight = frames[0].height; if(canvasMode=="default"){ canvas.width = canvasDefaultSize.width; canvas.height = canvasDefaultSize.height; }else{ if(bWidth>fWidth && bHeight>fHeight){ canvas.width = fWidth; canvas.height = fHeight; }else{ if(bHeight*aspectRatio<bWidth){ canvas.width = bHeight*aspectRatio; canvas.height = bHeight; }else{ canvas.width = bWidth; canvas.height = bWidth/aspectRatio; } } } } // canvas の click 時, canvasMode を反転させ,canvas のサイズと位置を変更 canvas.addEventListener("click", function(){ if(canvasMode=="default"){ canvasMode = "zoom"; canvas.className = "zoom"; }else{ canvasMode = "default"; canvas.className = "default"; } changeCanvasSize(); changeCanvasPosition(); }); // Window のサイズ変更時, canvas のサイズと位置を変更 (function(){ var resizeTimer = false; window.addEventListener('resize', function () { if (resizeTimer !== false) { clearTimeout(resizeTimer); } resizeTimer = setTimeout(function () { changeCanvasSize(); changeCanvasPosition(); }, 50); }); })(); changeCanvasSize(); changeCanvasPosition(); } // 一定時間毎に canvas に描画 function drawCanvas(){ var frame = frames[frameNum]; var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.clearRect(0,0,canvas.width,canvas.height); ctx.drawImage(frame.image, 0,0,frame.width,frame.height,0,0,canvas.width,canvas.height); frameNum++; if(frameNum>=frames.length){frameNum = 0;} setTimeout(drawCanvas, frame.delay); } </script> <style> *{margin:0; padding:0;} body{ background-color: #FFFFFF; position: relative; } #canvas{ position:absolute; margin: auto; } #canvas.default{ cursor: zoom-in; } #canvas.zoom{ cursor: zoom-out; } </style> </head> <body> <canvas id ="canvas" class="default" width=600 height=400> </body> </html>`; template = template.replace("$frames", frames); template = template.replace("$defaultSize", defaultSize); return template; } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址