MyShowBox

显示图片的库

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/515677/1576435/MyShowBox.js

  1. // ==UserScript==
  2. // @name MyShowBox
  3. // @version 2025.04.24
  4. // @description 修复touch就滚两页的bug
  5. // @author You
  6. // @grant none
  7. // @grant GM_getValue
  8. // @grant GM_setValue
  9. // @grant GM_deleteValue
  10. // @grant GM_download
  11. // ==/UserScript==
  12.  
  13. if(window.GAIL == null || window.Downloader == null){alert("GAIL or Downloader is null");}
  14.  
  15. /**
  16. * 把图片全部添加到一个Showbox里的类,只能new一次
  17. * @class
  18. * @example
  19. const showBox = new ShowBox();
  20. showBox.Add(imgs);
  21. @ps Add函数只能调用一次
  22. */
  23. function ShowBox(){
  24. let imgs = null;
  25. let num = 10;
  26. let showNum = num;
  27. let nowIndex = 0;
  28. /**
  29. * @type {Downloader}
  30. */
  31. let downloader = window.Downloader ? new window.Downloader() : (() => { throw new DOMException("Downloader does not exist"); })();
  32. let box = $('.clickShowBox').length > 0 ? $('.clickShowBox') : CreateShowBox()
  33. downloader.Set_downloadType("GM_download");
  34. this.downloader = {get obj(){return downloader;}}
  35. /**
  36. * 把图片全部添加到一个Showbox里
  37. * @example Add(imgs)
  38. * @param {JQuery} iimgs
  39. * @ps 只能调用一次,等图片获取完了再调用
  40. */
  41. this.Add = (iimgs)=>{
  42. imgs = iimgs;
  43. AddImgs();
  44. }
  45. /**
  46. * @example controlType = "mouse"
  47. */
  48. this.controlType = "mouse";
  49. /**
  50. * 设置一次预加载多少图片,默认是10
  51. * @example SetShowNum = 20
  52. * @param {number} n
  53. * @ps 未加载的图片src为空,只有small_src和big_src
  54. */
  55. this.SetShowNum = (n) => {showNum = num = n;}
  56. /**
  57. * @param {string} type - {GM_download / atag / blob}
  58. */
  59. this.Set_donwloadType = (type)=>{downloader.Set_downloadType(type);}
  60.  
  61. /**
  62. * 重写下载图片的方法
  63. * @example SetDonloadFunction((imgs)=>{...})
  64. * @param {function(JQuery)} foo - (imgs)=>{}
  65. */
  66. this.SetDonloadFunction = (foo)=>{downloader.Download_img = foo;}
  67. function AddImgs(){
  68. imgs.each(function(){
  69. const item = $('<div class="item"></div>')
  70. .append($('<img>').attr({'small_src':this.src,src:"",'big_src':$(this).attr('big_src')}));
  71. $('.clickShowBox').append(item);
  72. })
  73. ClickShowNext({img:$('img'),onlyDown:false});
  74. }
  75. function CreateShowBox(){
  76. let box = `
  77. <div class="clickShowBox">
  78. <p class="pages">1/10</p>
  79. <button class="close">x</button>
  80. <div class="downloadBU">
  81. <button class="download">↓</button>
  82. <button class="downloadall">↓↓</button>
  83. </div>
  84. </div>
  85. <div class="clickShowBox_ShowBu"></div>
  86. `
  87. box = $(box);
  88. $('body').prepend(box);
  89. $('.clickShowBox .close').click(function(){
  90. $('.clickShowBox').fadeOut();
  91. $('.clickShowBox_ShowBu').show()
  92. })
  93. $('.clickShowBox_ShowBu').click(function(){
  94. $('.clickShowBox').fadeIn();
  95. $(this).hide();
  96. Show_imgs(num);
  97. })
  98. $('.clickShowBox .download').click(function(){
  99. BU_nomal($(this))
  100. const img = $('.clickShowBox .item img').eq(nowIndex);
  101. let src = img[0].src;
  102. if(img.attr('big_src')){
  103. src = img.attr('big_src');
  104. img[0].src = src;
  105. }
  106. let name = document.title + new Date().getTime() + src.match(/\.jpg|\.jpeg|\.webp|\.png/g)[0];
  107. if(img.attr('name')){
  108. name = img.attr('name');
  109. }
  110. BU_busy($(this))
  111. try{
  112. GM_download({
  113. url:src,
  114. name:name,
  115. onload:function(){
  116. BU_done($('.download'));
  117. },
  118. error:function(){
  119. BU_error($('.download'));
  120. }
  121. })
  122. }catch(error){
  123. console.log(error);
  124. BU_error($('.download'));
  125. }
  126. })
  127. $('.clickShowBox .downloadall').click(function(){
  128. BU_busy($(this));
  129. try{
  130. console.log(downloader)
  131. downloader.Download_img($('.clickShowBox .item img'));
  132. }catch(error){
  133. console.log(error);
  134. BU_error($(this));
  135. }
  136. })
  137. downloader.AllComplete(()=>{
  138. BU_done($('.clickShowBox .downloadall'));
  139. });
  140. downloader.OneSuccess((img)=>{
  141. var src = img.attr('big_src') || img.attr('big-src') || null;
  142. console.log(src);
  143. if(!src){return;}
  144. img.attr('src',src);
  145. // $('.clickShowBox .item img').filter(function(){return $(this).attr('big_src')||$(this).attr('small_src') == img[0].src})
  146. // .attr('src',img[0].src);
  147. });
  148. Add_ClickShowBox_css();
  149. $('.clickShowBox').hide();
  150. Add_keyControl()
  151. return box;
  152. }
  153. function Add_ClickShowBox_css(){
  154. let css = `
  155. .clickShowBox{
  156. width: 100%;
  157. height: 100%;
  158. background-color: #2d2d2d;
  159. overflow: hidden;
  160. border-radius: 0vw;
  161. position: fixed;
  162. z-index: 9999;
  163. }
  164. .clickShowBox .item{
  165. width: 100%;
  166. height: 100%;
  167. background-color: #2D2D2D;
  168. display: flex;
  169. align-items: center;
  170. justify-content: center;
  171. }
  172. .clickShowBox .item img{
  173. max-width: 100%;
  174. height: auto;
  175. max-height: 100%;
  176. }
  177. .clickShowBox .pages{
  178. font-size: 5vw;
  179. color: rgba(255,255,255,0.5);
  180. position: fixed;
  181. top: 1.5vw;
  182. margin: 2vw;
  183. right:12vw
  184. }
  185. .clickShowBox .close{
  186. width: 10vw;
  187. height:10vw;
  188. font-size: 6vw;
  189. border-radius: 10vw;
  190. background-color: rgba(255,255,255,0.1);
  191. color: rgba(255,255,255,0.1);
  192. position: fixed;
  193. right: 0;
  194. top:0;
  195. margin: 2vw;
  196. font-weight: bold;
  197. border: none;
  198. }
  199. .clickShowBox .close:active{
  200. filter:invert(100%);
  201. }
  202. .clickShowBox .downloadBU{
  203. display: flex;
  204. flex-direction: row;
  205. position: fixed;
  206. bottom:0;
  207. }
  208. .clickShowBox .download
  209. ,.clickShowBox .downloadall{
  210. width:100%;
  211. font-size: 5vmin;
  212. aspect-ratio: 1/1;
  213. border-radius: 2vmin;
  214. background-color: #ff8a17;
  215. color: white;
  216. margin: 0 0 2vw 2vw;
  217. border: none;
  218. opacity: .4;
  219. position: relative;
  220. }
  221. .clickShowBox .download:active
  222. ,.clickShowBox .downloadall:active{
  223. opacity: .6;
  224. }
  225. .clickShowBox .busy{
  226. animation: BU_busy infinite 1s linear;
  227. }
  228. @keyframes BU_busy{
  229. 0%{top:0}
  230. 25%{top:2vw}
  231. 75%{top:-2vw}
  232. 100%{top:0}
  233. }
  234. .clickShowBox .error{
  235. background-color: red;
  236. }
  237. .clickShowBox_ShowBu{
  238. width: 10vw;
  239. height: 10vw;
  240. border-radius: 10vw;
  241. background-color: orange;
  242. position: fixed;
  243. bottom: 30%;
  244. right: -5vw;
  245. z-index: 999999;
  246. display: flex;
  247. align-items: center;
  248. justify-content: center;
  249. }
  250. .clickShowBox_ShowBu::after{
  251. content: "";
  252. width: 70%;
  253. height: 70%;
  254. background-image: url('data:image/svg+xml;utf8,<svg width="10" height="10" xmlns="http://www.w3.org/2000/svg"><path d="M 10 10 L 0 5 L 10 0 Z" fill="White"/></svg>');
  255. background-size: cover;
  256. background-repeat: no-repeat;
  257. transform: scaleX(0.8);
  258. }
  259. `
  260. Add_css(css)
  261. }
  262. function BU_busy(bu){
  263. bu.addClass('busy');
  264. }
  265. function BU_done(bu){
  266. bu.removeClass('busy');
  267. }
  268. function BU_error(bu){
  269. bu.removeClass('busy');
  270. bu.addClass('error');
  271. }
  272. function BU_nomal(bu){
  273. bu.removeClass('busy').removeClass('error');
  274. }
  275. function Add_keyControl(){
  276. let downItem = $('<button><button>').click(function(){
  277. simulateClick($(window).width()/2,$(window).height()*0.8);
  278. })
  279. let upItem = $('<button><button>').click(function(){
  280. simulateClick($(window).width()/2,$(window).height()*0.2);
  281. })
  282. window.GAIL.AddKeyControl(downItem,upItem,null,null,true);
  283. }
  284. function ClickShowNext({img,onlyDown}){
  285. if(!$){return;}
  286. if(img.length<=1){console.log('only one img');return;}
  287. let item = $('.clickShowBox .item');
  288. $('.clickShowBox .pages').text(1+"/"+item.length);
  289. item.on("touchstart mousedown",function(event){
  290. if ($(window).height()>$(window).width() && event.type === 'mousedown'){return;}
  291. let y = event.clientY;
  292. if(event.touches){y = event.touches[0].clientY;}
  293. let index = item.index($(this));
  294. index = !onlyDown && y<$(this).height()/2 ? index-1:index+1;
  295. index = index>=0?Math.min(index,item.length-1):0
  296. item.eq(index)[0].scrollIntoView();
  297. $('.clickShowBox .pages').text((index+1)+"/"+item.length);
  298. nowIndex = index;
  299. Show_imgs(showNum);
  300. });
  301. }
  302. function Show_imgs(i){
  303. let img = $('.clickShowBox .item img[small_src][src=""]');
  304. let start = Math.max(0,nowIndex-i);
  305. let end = Math.min(img.length,nowIndex+i);
  306. img.slice(start,end).each(function(){
  307. this.src = $(this).attr('small_src');
  308. });
  309. console.log(`${start} ${end} ${img.length}`)
  310. }
  311. function Add_css(cssString){
  312. var style = document.createElement('style');
  313. style.type = 'text/css';
  314. style.innerHTML = cssString;
  315. document.body.appendChild(style);
  316. }
  317. }
  318.  
  319. window.ShowBox = ShowBox;
  320.  
  321. window.ShowBox.ShowInNewPage = (url)=>{
  322. GM_setValue('ShowBoxInNewPage','yes');
  323. window.open(url);
  324. const img = $('.clickShowBox img');
  325. GM_setValue('ShowBoxInNewPage_img',img.eq(0)[0].src);
  326. GM_setValue('ShowBoxInNewPage_num',img.length);
  327. let i = 1;
  328. let obo = setInterval(()=>{
  329. if(i==img.length){clearInterval(obo);return;}
  330. if(!GM_getValue('ShowBoxInNewPage_img')){
  331. GM_setValue('ShowBoxInNewPage_img',img.eq(++i).html());
  332. }
  333. },100);
  334. }
  335. window.ShowBox.Linsening_ShowInNewPage = ()=>{
  336. if(!GM_getValue('ShowBoxInNewPage')){
  337. return;
  338. }
  339. GM_deleteValue('ShowBoxInNewPage');
  340. const box = new window.ShowBox();
  341. let i = 0;
  342. let img = ''
  343. const num = Number(GM_getValue('ShowBoxInNewPage_num'));
  344. let obo = setInterval(()=>{
  345. if(i==num){GM_deleteValue('ShowBoxInNewPage_num');box.AddImgs($(img));clearInterval(obo);return;}
  346. if(GM_getValue('ShowBoxInNewPage_img')){
  347. img += GM_getValue('ShowBoxInNewPage_img')
  348. GM_deleteValue('ShowBoxInNewPage_img');
  349. }
  350. },100);
  351. }
  352. $(function(){
  353. window.ShowBox.Linsening_ShowInNewPage();
  354. })