// ==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.3
// @grant none
// @downloadURL none
// ==/UserScript==
(()=>{
//親コンテナの幅制限を解除
$(".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("");
let _preblank = true;
// ページ組み換えボタン
let $reconst = $("
").text("Suppley");
$suppley.css(
{
'background-color': "gray",
'flex-basis': "70px",
'padding': "0 10px",
}
);
$suppley.click(
() => {
pages.forEach(
val => {
if( val.error )
{
loaded--;
val.$image.attr(
'src',
val.src + "?" + String(Math.random()).slice(2)
);
console.log(val.index, val.$image );
}
}
);
}
);
let $control = $("
").css(
{
'position': "fixed",
'display': "flex",
'left': 0,
'top': 0,
'width': "100%",
'opacity': 0,
'height': "20px",
'text-align': "center",
'line-height': "20px",
}
);
// コントロールバーを隠しておく
let AutoHide = (_this, mark) => {
$(_this).stop();
$(_this).animate(
{
'opacity': mark
}, "fast"
);
}
$control.hover(
function(){ AutoHide(this, 0.8); },
function(){ AutoHide(this, 0); }
);
$control.append($reconst);
$control.append($suppley);
$("body").append($control);
// ページのテンプレート
const $sheet = $("
").css(
{
'position': "relative",
'pointer-events': "none",
'margin': 0,
'margin-bottom': "10px",
'width': "50%",
'display': "flex",
'align-items': "center",
}
);
// ページを入れるコンテナ
let $IMAGE_CONTAINER = $(".lazy-container").css( 'width', "auto" );
// 各ページを管理する配列
let pages;
// ロード済みの画像をカウント
let loaded = 0;
// ページを作成
let InitImage = () => {
// 画像一覧を取得
pages = [];
$.getJSON(
$IMAGE_CONTAINER.data("url"),
idata => {
idata.forEach(
(val, i) => {
let $i = $("
![]()
").attr(
{
'src': val,
'num': i
}
);
// ロードした画像が見開きっぽければ、属性とスタイルを追加
// (見開き関連の処理はヤングエースUPでは必要ないけど……)
$i.on(
{
'load': () => {
if( loaded==0 ) Centering();
},
// 画像が読み込み不全になった場合
'error': function(){
let index = $(this).attr('index');
if( index )
{
pages[index].error = true;
}
console.log("error", index, pages[index]);
},
}
);
let $s = $sheet.clone();
$s.append($i);
// 管理配列にページ情報を追加
pages.push(
{
'index': i,
'src': val,
'$sheet': $s,
'$image': $i,
'error': null,
'side': null,
'pos': 0,
}
);
}
);
// 一応ページ順をソートしておく
pages.sort( (v1, v2) => v1.index
$IMAGE_CONTAINER.append( val.$sheet )
);
// clearfix
$IMAGE_CONTAINER.append(
$("").css(
{
'height': 0,
'clear': "both",
}
)
);
// クリックスクロール用領域
let $scrL = $("
").css(
{
'position': "absolute",
'width': "50%",
'height': "100%",
'top': 0
}
);
let $scrR = $scrL.clone();
$scrL.css( 'left', 0);
$scrR.css( 'right', 0);
$IMAGE_CONTAINER.prepend($scrL);
$IMAGE_CONTAINER.prepend($scrR);
// 次か前のページにスクロールする
let ScrollToPage = delta => {
let st = $(window).scrollTop();
let i;
for( i=pages.length-1; i>=0; i-- )
{
// 次のページ
if( delta>0 && st >= pages[i].pos )
{
i++;
break;
}
// 前のページ
else if( delta<0 && !(st <= pages[i].pos) )
{
break;
}
}
$('html,body').stop();
$('html,body').animate({
scrollTop: pages.round(i).pos
},300);
};
// エピソード移動
let MoveEpisode = ($nav, homepos) => {
if( $nav.length>0 &&
$(window).scrollTop() == homepos )
{
location.href = $nav.attr('href');
}
};
$scrL.on(
{
// 左側クリックで次のページへ
'click': (e) => {
e.stopPropagation();
ScrollToPage(1);
},
// 最後の左ページをダブルクリックで次の話
'dblclick': () => {
MoveEpisode( $(".viewerbtn a"), pages.lastv().pos );
}
}
);
$scrR.on(
{
// 右側クリックで前のページへ
'click': (e) => {
e.stopPropagation();
ScrollToPage(-1);
},
}
);
// ロード完了まで暫定的にセンタリングする
// 画像がキャッシュされていないサイズが取得できないので、
// すべての画像がロードされた時もう一度中央寄せする必要がある
Centering();
// サイズ調整
Resize();
}
);
};
// スクロール位置を記録しておく配列
let PosUpdate = () =>{
pages.forEach(
val => val.pos = Math.ceil(val.$sheet.offset().top)
);
};
// 各ページの画像を真ん中に寄せる
let Centering = blankin => {
if( _preblank != null &&
blankin != null ) _preblank = blankin;
let count = 0;
// フラグが立っていれば前見返しを表示
if( _preblank ) count++;
pages.forEach(
val => {
let $s = val.$sheet;
// 偶数カウントであれば右ページ(画像は左寄せ)
if( count%2==0 )
{
val.side = "right";
$s.attr( 'side', "right");
$s.css(
{
'float': "right",
'justify-content': "flex-start",
}
);
}
else
{
val.side = "left";
$s.attr( 'side', "left");
$s.css(
{
'float': "none",
'justify-content': "flex-end",
}
);
}
count++;
}
);
PosUpdate();
};
const sqt = Math.sqrt(2);
let Resize = () => {
let wh = $(window).height();
let ww = $(window).width();
$IMAGE_CONTAINER.css( 'width', ww );
pages.forEach(
val => {
val.$sheet.css( 'height', wh);
if( wh*sqt
{
InitImage();
},
}
);
$(window).on(
{
// readyで初期化できていなかった場合
'load': () => {
if( pages==null ) InitImage();
},
// リサイズ時に画像サイズをアジャスト
'resize': () => {
Resize();
}
}
);
})();