// ==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.2
// @grant 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("<style type='text/css'> div[id^=img] {display:none} </style>");
// ページ組み換えボタン
var $reconst = $("<div id='constraction' />").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 = $("<div class='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 = $("<img>").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",
}
);
$(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<v2.index? -1: 1;
}
);
// ページを追加していく
// 前見返し
$IMAGE_CONTAINER.append( $preblank );
// ページ画像
$.each( pages,
function(i, val)
{
$IMAGE_CONTAINER.append( val.$page );
}
);
// 後ろ見返し
$IMAGE_CONTAINER.append( $aftblank );
// clearfix
$IMAGE_CONTAINER.append(
$("<div class='clearfix'>").css(
{
'height': 0,
'clear': "both",
}
)
);
// クリックスクロール用領域
var $scrL = $("<div/>").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);
}
);
};
// スクロール位置を記録しておく配列
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();
// サイズ調整
Resize();
};
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<ww? {
//横長
'height': "100%",
'width': "auto",
'margin': 0
}:
{
//縦長
'height': "auto",
'width': "100%",
'margin-top': ((wh-ww/2*sqt) / 2)
};
$.each(
pages, function(i, val)
{
val.$image.css(prm);
}
);
PosUpdate();
};
$(document).on(
{
'ready': function()
{
InitImage();
},
}
);
$(window).on(
{
// リサイズ時に画像サイズをアジャスト
'resize': function()
{
Resize();
}
}
);
})();