// ==UserScript== // @name Younge Ace UP Comic Viewer // @namespace phodra // @description ヤングエースUPの漫画を見開きで表示する // @include https://web-ace.jp/youngaceup/contents/* // @require https://greasyfork.org/scripts/36978-arrayex/code/ArrayEx.js?version=240772 // @version 0.2.3 // @grant none // @downloadURL none // ==/UserScript== (function (){ //親コンテナの幅制限を解除 $(".col-viewer").width("auto"); $(".inner-delivery-contents").css( 'padding', "10px 0 0 0"); $(".top-brand-logo, .global-navigation, .sub-navigation, .containerMain, .footer").css( { 'max-width': "initial", 'min-width': "initial", } ); $(".displayFlex").css( 'flex-flow', "row wrap"); $(".nav-youngaceup").hide(); // 元の画像を非表示 $("head").append(""); // ページ組み換えボタン var $reconst = $("
").css( { 'position': "fixed", 'left': 0, 'top': 0, 'width': "100%", 'height': "20px", 'background-color': "darkgray", 'opacity': 0, 'text-align': "center", 'line-height': "20px", } ); $reconst.text("Construction"); var _preblank = true; $reconst.on( { 'click': function() { if( pages==null ) { // なにかの不具合でページが構築されていないときのため InitImage(); } else { // クリックするたびにページ組みを切り替える Centering(!_preblank); } }, // ボタンバーを隠しておく 'mouseenter': function() { $(this).stop() $(this).animate( { 'opacity': 0.8 },"fast" ); }, 'mouseleave': function() { $(this).stop() $(this).animate( { 'opacity': 0 },"fast" ); }, } ); $("body").append($reconst); // ページのテンプレート var $page = $("
").css( { 'margin': 0, 'margin-bottom': "10px", 'width': "50%", } ); var $preblank = $page.clone().attr('class',"page pre_blank"); var $aftblank = $page.clone().attr('class',"page aft_blank"); $preblank.css( 'float', "right" ); $aftblank.css( 'float', "left"); // ページを入れるコンテナ var $IMAGE_CONTAINER = $(".lazy-container").css( 'width', "auto" ); // 各ページを管理する配列 var pages; // ロード済みの画像をカウント var mihiraki = false; var loaded = 0; // ページを作成 var InitImage = function() { // 画像一覧を取得 pages = []; $.getJSON( $IMAGE_CONTAINER.data("url"), function(data) { $.each( data, function(i, val) { var $i = $("").attr( { 'src': val, 'num': i } ); // ロードした画像が見開きっぽければ、属性とスタイルを追加 // (見開き関連の処理はヤングエースUPでは必要ないけど……) $i.load( function() { var img = new Image(); img.src = $(this).attr('src'); if( img.width > img.height ) { mihiraki = true; $(this).parent().attr( 'mihiraki', true); $(this).parent().css( { 'width': "100%", 'float': "none", 'clear': "both", } ); $(this).css( { 'margin': "0 auto", 'float': "none", } ); // 見開きが一枚目だった場合、前見返しを非表示に if( $(this).attr('num')==0 ) { $preblank.hide(); _preblank = null; } } loaded++; // 見開きが存在し、すべてロード完了したときに中央寄せ if( mihiraki && loaded==pages.length ) { Centering(); } } ); // 管理配列にページ情報を追加 pages.push( { 'index': i, 'src': val, '$page': $page.clone().append($i), '$image': $i, } ); } ); // 一応ページ順をソートしておく pages.sort( function(v1, v2) { return v1.index").css( { 'height': 0, 'clear': "both", } ) ); // クリックスクロール用領域 var $scrL = $("
").css( { 'position': "absolute", 'width': "50%", 'height': "100%", 'top': 0 } ); var $scrR = $scrL.clone(); $scrL.css( 'left', 0); $scrR.css( 'right', 0); $IMAGE_CONTAINER.prepend($scrL); $IMAGE_CONTAINER.prepend($scrR); // 次か前のページにスクロールする var ScrollToPage = function(e, delta) { var st = $(window).scrollTop(); var i; for( i=pagepos.length-1; i>=0; i-- ) { // 次のページ if( delta<0 && st >= pagepos[i] ) { i++; break; } // 前のページ else if( delta>0 && !(st <= pagepos[i]) ) { break; } } $('html,body').stop(); $('html,body').animate({ scrollTop: pagepos.round(i) },300); } // エピソード移動 var MoveEpisode = function($nav, homepos) { if( $nav.length>0 && $(window).scrollTop() == homepos ) { location.href = $nav.attr('href'); } }; $scrL.on( { // 左側クリックで次のページへ 'click': function(e) { e.stopPropagation(); ScrollToPage(e, -1); }, // 最後の左ページをダブルクリックで次の話 'dblclick': function() { MoveEpisode( $(".viewerbtn a"), pagepos.lastv() ); } } ); $scrR.on( { // 右側クリックで前のページへ 'click': function(e) { e.stopPropagation(); ScrollToPage(e, 1); }, } ); // ロード完了まで暫定的にセンタリングする //  画像がキャッシュされていないサイズが取得できないので、 //  すべての画像がロードされた時もう一度中央寄せする必要がある Centering(true); // サイズ調整 Resize(); } ); }; // スクロール位置を記録しておく配列 var pagepos = []; var PosUpdate = function() { pagepos = []; $.each( pages, function(i, val) { var target = Math.ceil(val.$page.offset().top); if( pagepos.lastIndexOf(target)<0 ) { pagepos.push( target ); } } ); }; // 各ページの画像を真ん中に寄せる var Centering = function(blankin) { if( _preblank != null && blankin != null ) _preblank = blankin; var count = 0; // フラグが立っていれば前見返しを表示 if( _preblank ) { $preblank.show(); count++; } else { $preblank.hide(); } $.each( pages, function(i, val) { var $p = val.$page; var $i = val.$image; var img = new Image(); img.src = $i.attr('src'); // 画像サイズで見開きを判定 // (キャッシュがあれば直接取得できる) // (ないときのためロードを待ってもう一度Centering関数を実行すること) if( img.width > img.height || $p.attr('mihiraki') ) { // カウントをリセット(次のページは強制的に右) count = 0; } else { // 偶数カウントであれば右ページ(画像は左寄せ) $p.css( { 'width': "50%", 'float': count%2!=0? "left": "right", } ); $i.css( 'float', count%2==0? "left": "right" ); count++; } } ); // 最後が右ページであれば後ろ見返しを表示 if( count%2!=0 ) { $aftblank.show(); } else { $aftblank.hide(); } PosUpdate(); }; const sqt = Math.sqrt(2); var Resize = function() { var wh = $(window).height(); var ww = $(window).width(); $IMAGE_CONTAINER.css( 'width', ww ); $preblank.css('height', wh); $aftblank.css('height', wh); $.each( pages, function(i, val) { val.$page.css( 'height', wh); } ); // 画像をアジャスト var prm = wh*sqt