Webコミックや連続した画像ファイルを読むのをお手伝いする JavaScript です。
Read (読む) と
Lead (導く) をかけて
Comic-Leader にしました。
目的とスクリプト自体はすごい車輪の再発明っぽいけど、気にしちゃダメですヨ。
わかりやすく使いやすいインターフェイスを提供するユーザーライクさと、 必要な全ての設定をHTML内で行え、インターフェイスも作者がある程度好きに作れる、 といった割と融通の利くオーナーライクさが、 一番の主眼であり特徴です。 (……ただ、その分いつものように無駄も多いかも)
まあ、過度の宣伝もアレだし、一見に如かないので、 まずは サンプル をご覧ください。
Windows + InternetExplorer-6.0, FireFox-1.0, Opera-7.0 で動作確認。
DOMがまともに使えないような古いブラウザだと動きません。対応する気もございません。
また、 カヤさん が記事の中でちらりと Comic-Leaderの紹介 をしてくれてたりしたので、そちらも参考にしてみてください。(感謝!)
しかし、第三者さんの紹介って、 どうしてこう自分で紹介するよりもずっと興味深いものになるのでしょうね。
function preload
周りをちょっと修正.comic/ |-- Comic.js // このスクリプト |+- comic-1/ // "comic-1" を為す一連のファイルがあるディレクトリ. |-- index.html // "comic-1" を表示するHTML. (HTMLソースは上のソースを参考にして記述) |-- 01.png // "comic-1" を為す連続する画像. (桁と拡張子は全て統一する) |-- 02.png |-- 03.png ... |-- 27.png |+- comic-2/ // "comic-2" ディレクトリ. Comic.js は "comic-1" と共用で使う. |-- index.html |-- 001.jpg |-- 002.jpg |-- 003.jpg ... |-- 013.jpg ...
Comic.js
を、上の設置例のように、HTMLよりひとつ上の階層に置くとき、
Comic.js を呼び出すソースは、
<script type="text/javascript" src="Comic.js"></script>
ではなく、
<script type="text/javascript" src="../Comic.js"></script>
とか書くのですよ。
(当たり前のことなのだけど一応。)
<script type="text/javascript" src="Comic.js"></script>
<div id="comic" class="section">
<h2>Comic</h2>
<ul class="images">
<li id="for-image2">
<a rel="prev" href="#image" accesskey=",">
<!--見開きのときに使う (任意) / last が無いときはこの要素の src から取得-->
<img id="image2" src="http://glas-gather.org/comic/disorderly/27.jpg" alt="最後のページの画像" /></a>
</li>
<li id="for-image">
<a rel="next" href="#image" accesskey=".">
<!--画像 (必須) / 各設定のための要素が無いときはこの要素の src から取得-->
<img id="image" src="http://glas-gather.org/comic/disorderly/01.jpg" alt="最初のページの画像" /></a>
</li>
</ul>
<noscript>
<!--JavaScriptが有効でない人のために、画像へのリンクを用意しておくと親切-->
<ul>
<li><a href="image/01.jpg">01P</a></li>
<li><a href="image/02.jpg">02P</a></li>
<li><a href="image/03.jpg">03P</a></li>
<li><a href="image/04.jpg">04P</a></li>
<li><a href="image/05.jpg">05P</a></li>
</ul>
</noscript>
</div>
<hr />
<form id="leader" class="section" action="#leader" method="get">
<h2>Leader</h2>
<fieldset class="interface">
<legend>Interface</legend>
<dl>
<dt>現在のページ</dt>
<dd>
<label title="現在のページ">
<input type="text" name="page" value="1" class="page" accesskey="@" />
</label>
<label title="先読みしたページ">
/
<input type="text" name="preload" value="" class="page" accesskey="^" />
</label>
<label title="クッキーに現在のページ情報を保存する?">
<input type="checkbox" name="cookie" value=";" accesskey="?" />Cookie
</label>
</dd>
<dt>前後移動</dt>
<dd>
<ul>
<li><button type="button" accesskey="{" onclick="Comic._.go(0)" onkeypress="this.onclick()" title="最初のページへ">first</button></li>
<li><button type="button" name="prev" accesskey="[" title="前のページへ戻る">prev</button></li>
<li><button type="button" name="next" accesskey="]" title="次のページへ進む">next</button></li>
<li><button type="button" accesskey="}" onclick="Comic._.go(-1)" onkeypress="this.onclick()" title="最後のページへ">last</button></li>
</ul>
</dd>
<dt>拡大・縮小, 見開き</dt>
<dd>
<label title="画像の拡大・縮小" accesskey=":">
<select name="zoom">
<option value="25">25%</option>
<option value="50">50%</option>
<option value="75">75%</option>
<option value="100" selected="selected">100%</option>
<option value="125">125%</option>
<option value="150">150%</option>
<option value="175">175%</option>
<option value="200">200%</option>
<option value="250">250%</option>
<option value="300">300%</option>
</select>
</label>
<label title="1P表示 / 見開き表示" accesskey="/">
<select name="spread">
<option value="0" title="1ページずつ読む">One-Page</option>
<option value="1" title="奇数ページで見開き">Odd-Spread</option>
<option value="2" title="偶数ページで見開き">Even-Spread</option>
<option value="-1" title="全ページを羅列する">All-Pages</option>
</select>
</label>
</dd>
</dl>
<div class="hidden">
<!--以下は設定 (任意) 無ければ image から自動取得-->
<!--最初の画像ファイルの番号-->
<!-- <input type="hidden" name="first" value="1" /> -->
<!--最後の画像ファイルの番号-->
<!-- <input type="hidden" name="last" value="13" /> -->
<!--全画像ファイルの番号の共通の(最低)桁数-->
<!-- <input type="hidden" name="digit" value="2" /> -->
<!--全画像ファイルのある共通のディレクトリ-->
<!-- <input type="hidden" name="dir" value="image/" /> -->
<!--全画像ファイルの共通の拡張子-->
<!-- <input type="hidden" name="extension" value="jpg" /> -->
<!--画像を先読みするとき、その限界数-->
<!-- <input type="hidden" name="prelimit" value="20" /> -->
<!--画像が別フレームにある場合そのフレームのname値-->
<!-- <input type="hidden" name="frame" value="image-page" /> -->
<!--クッキーやURL情報から、公開している設定を変えられるようにする-->
<!-- <input type="hidden" name="query" value="1" /> -->
<!--キー・ジェスチャーを有効にする-->
<input type="hidden" name="gesture" value="1" />
</div>
</fieldset>
</form>
以下、設定とか仕様とかのメモ。
上のHTMLのサンプルソースを見ながらどうぞ。
ページ数とかの必要な設定は、HTML内の要素で行います。
JS内はいじんなくてよさげです。
JS内にも設定がありますが、
これは、設定のためのHTML内の要素を取得するための設定です。
もし要素名を変えたくなったときは、この設定を変更すればよいです。
設定のための要素は、 Form要素内にあれば name値 により指定できますし、 Form要素外であれば id値 で指定してやります。
JSは、一応オブジェクト指向的に書かれてるので、
new Comic({ 新しい設定 })
とやると、同じページで複数の漫画が動かせるでしょう。
(やるひとおらんだろうけど)
設定で必要なのは、上のソースで言えば、
<div class="hidden">
の中にある
<input>
族です。
設定は任意です。
各項目が未設定(空白や 0 の場合も含む)の場合は、
<img id="image">
の画像ファイル名を元に、各値が設定されます。
それでも設定値が取得できなかった場合、 first値 には 0 が、 last値が 999 が、 他の値には 0 か 空文字 が入ります。 (実際に無い数値にしても特に閲覧には困らないみたいなので)
※例えば、http://hoge.com/001~100.jpg だったら、
first : 1,
last : 100,
digit : 3,
dir : http://hoge.com/,
extenstion : jpg,
って感じ。
汎用のための設定として、以下の項目もあります。
<img id="image">
メインの画像要素。(必須) ページを変えると、ここのsrcが変わる。
<img id="image2">
この画像要素があると、見開きページに対応できます。(任意)
また、last が無いときは、
この要素から最後のページの番号を取得しようとします。
なので、HTMLソースには、最後のページを書いておけばいいかもしれません。
<form id="leader">
この要素内に、以下(↓から)の設定要素を書けば、 id="***" の部分が name="***" でも許される。
以下(↓から)は全て任意の項目です。
<* id="prev">
その要素を押したとき 1P 戻る。
<* id="next">
その要素を押したとき 1P 進む。
また、次の画像を先読みしてるとき、
この要素の class 名に "loading" が追加される。
先読みし終わると、その class は消える。
<* id="page">
この要素のテキスト値に、現在のページ数が表示される。
この要素の値を変えると、そのページに飛ぶ。
<* id="zoom">
この要素の値を元に、画像が拡大・縮小する。
<* id="spread">
この要素の値によって、 1Pずつ見たり、見開きにしたり、全てのページを一気に並べたり、 そんなことができるようになったりもする。 (画面が狭いと並ばなかったりもする)
<* id="preload">
この要素があると、
ページを先読みしたら、その先読みしたページをこの要素に代入。
この要素の値を変えると、そのページから先読みを始める。
<* id="cookie">
この要素があると、ウィンドウを閉じたときに、
最後に読んだページ(最初と最後のページ以外)の情報がクッキーに保存されます。
この要素の値は、クッキーの保存日数になります。
ちなみに、
<input type="checkbox" id="cookie">
とチェックボックスにした場合、
クッキーを保存するかどうかは、ユーザーが選択できるようになります。
<* id="gesture">
この要素の値が有効なら、画像にフォーカスが当たっているときに キー・ジェスチャー(キーボードの特定のキーによる操作) が有効になります。
くわしくは キー・ジェスチャー機能の項 をご覧ください。
そのフォームの設定を元にした Comic オブジェクト。
その id を持つフォームの設定を元にした Comic オブジェクト。
デフォルトの Comic オブジェクトを差す。
例えば、
<* onclick="Comic.objects[ デフォルトのid ].go()">
の代わりに、
<* onclick="Comic._.go()">
と記述できるようになる。
そのページに進む。
<* onclick="Comic._.go(10)">
また、go(ページ数)
は、うまく修正されます。
ページ数が、最後の番号以上だったら、最後のページに。
ページ数が、最初の番号以下だったら、最初のページに。
ページ数が、マイナスだったら、最後のページから数えて行きます。
前のページに戻ります。
<* onclick="Comic._.prev()">
次のページに進みます。
<* onclick="Comic._.next()">
画像にフォーカスを当てます。 フォーカスを当てると、キー・ジェスチャーが使えるので便利です。
<* onclick="Comic._.focus()">
画像が拡大・縮小されます。 (倍率は % 単位)
<* onclick="Comic._.zoom(200)">
見開きになったりならなかったりします。
<* onclick="Comic._.spread(1)">
クッキーに、現在の情報を保存します。
<* onclick="Comic._.save_cookie(30)">
query が有効でないときは、現在のページ数のみ。
query が有効なときは、公開している設定要素の値を全て保存します。
そのページから、画像を先読みしていきます。
<* onclick="Comic._.preload(12)">
今のフォーム内の要素の値を元に、 そのオブジェクトをリセット・再設定します。
画像にフォーカスが当たっているとき、 キーボードの特定のキーを押すことで、いろいろイベントが起こせます。
画像にフォーカスを当てるには、 一度画像をクリックするか、 デフォルトでは accesskey に .(ドット) を指定してるので、 Windows なら "Alt + ."、 Macintosh なら "Ctrl + ." を押すと良さげです。 (ブラウザによってはこの限りではありません)
URLに、
"http://~~.html?10
"
というように、
"?ページ数
" を追加すると、
そのページが初期ページになります。
query が有効な場合、
URLに、
"http://~~.html?page=10&zoom=150&spread=1
"
というように、
"&設定名=設定値
"
を追加すると、
公開されている要素であれば、それを元に設定されます。
要望とかあったらどぞー。
サンプルソース をそのままコピーして、
メモ帳にそのまま全文ペーストして、
ファイル名を "test.html" にして保存して、
ブラウザで表示させればOKです。
わかんなかったらエライ人にきいてネ。
<a href="comic.html?13">13ページ目更新
ってやると 13P目 からスタートしますよ。
(このページ直接指定は、
query 設定値の有無によりません)
frame.html // 親フレームのHTML |- image.html // イメージがあるHTML |- tool.html // Comic.js を呼び出す、ツールボタンなどがあるHTML
上記のような構造であるとして。
親フレームにURL情報があれば、親フレームのURL情報をチェックし、
親フレームにURL情報が無ければ、
Comic.js を呼び出したHTMLのURL情報をチェックします。
つまり、
http://~~/frame.html
→
http://~~/tool.html?15
なら、15P、
http://~~/frame.html?10
→
http://~~/tool.html?15
なら、10P、
になります。
……で、いけるかと。
設定値を直接指定してやればいいのです。
手順を以下に簡単に書きます。
"サンプル" の "サンプル (別の漫画)" のように、 必要な設定を公開する。 (ユーザーが入力・選択できるようなフォームタイプにする)
query 設定値を有効にする。
(<input type="hidden" name="query" value="1" />
)
それから、その Comic-Leader.js を入れた HTML (例えば comic.html) へのリンクを、次のように書く。
いかがでしょうか。 (ただ、それでくれぐれも他所様のコミックを引っ張って来て貼ったりしないようにしましょうね。)
"必要な設定を公開する" 必要があることに注意してください。
公開するのはいいけど、ユーザーには見せたくないな、ってときは、
スタイルシートでそのアイテムを
display:none;
するなりして、対処してください。:-(
HTMLのソースから、その部分を削除すればいいじゃない。
"拡大・縮小"に限らず、全ての設定要素は、割と何でもよさげです。
<select name="zoom">
でも
<input type="text" name="zoom">
でも
<input type="radio" name="zoom">
でも
<input type="checkbox" name="zoom">
でも
<textarea name="zoom">
でも、
言ってしまえば <a id="zoom">
でもいいのです。
まあ <a>
だと内容の変更はできないのですけどね。:-P
サンプルソースそのままでは見開き(横に並ぶ)にはなりません。
サンプルでも、画面が小さいときは、横に並びません。
見開きモードにしたとき、
image2 の画像 には、
image の画像のひとつ前の画像が表示されます。
見開きモードでないときは、
image2 には display:none;
が付加されます。
見開きにするには、いくつか方法があるので、以下に書きます。
float
を使ってどうにかこうにかする。
(サンプルはこの手法)
display:inline;
や
white-space:nowrap;
を使ってどうこうする。
サンプルソース では、
image2 の画像の位置が image の画像よりも先にある、
ということに注意してください。
これはこれでいいのですが、
ただ、日本の漫画が、右から左に読むのが一般的なことを考えると、
ちょっと困った事態になります。
image2 のが image よりも先なので、
並べると、左から右に読む、配置になってしまうのです。
かと言って、配置を逆にすると、今度は、
画面が小さくて、見開きが縦に並んでしまったときに、不自然になります。
サンプルでは、
スタイルシートが効かないときでも、画面が小さいときでも、
特に不自然にならないように、
今の順配置で float:right
を使って対処していますが、
これは好きなようになさって構わないと思います。
どうしても見開きで見せたいのなら、
<table>
タグを使えばいいのです。:-)
こんな質問来るわけないけど、まあこの場を借りて。
例えば画像のサイズを 250kb とした場合、一気に200ページ読み込むと、 最低 50000kb = 約50Mb をキャッシュしてしまい、重くなりそうですね。
11/22 の更新で prelimit の設定項目を増やしました。 この値を調節してみてください。
例えば、prelimit を 20 にすると、 今表示されているページから数えて、20ページ先までしか先読みしなくなり、 また、20ページ前までのページはクリアされます。 つまり、前後20ページ、合計40ページまでキャッシュされることになります。
それと、prelimit がない、または、値を 0 にすると、 自動でデフォルト値の 20 が設定されます。 負の値 (-1等) にすると先読みしなくなります。
著作権を放棄するわけじゃないけど、表示はおまかせ。 邪魔ならつけなくても一向に構わないよ。
リンクとかも、自分が喜ぶだけで、特に貼る義務もないです。 改造とかもお好きにどうぞ。