| 1 |
# = #require hammer |
| 2 |
# = #require jquery.hammer |
| 3 |
# = require message_box |
| 4 |
# = require wait_circle |
| 5 |
|
| 6 |
# 使えない文字をエスケープ |
| 7 |
yomeya_escape = (s) -> |
| 8 |
return s.replace /([!"#$%&'?^|`\[\]{}+])/g, (s, m) -> |
| 9 |
r = "00" + (m.charCodeAt(0).toString(16)) |
| 10 |
return "%" + r.substring(r.length - 2) |
| 11 |
|
| 12 |
# ハッシュから値を削除 |
| 13 |
hash_delete_by = (h, k) -> |
| 14 |
r = {} |
| 15 |
$.each h, (hk, hv) -> |
| 16 |
if hk != k |
| 17 |
r[hk] = hv |
| 18 |
return true |
| 19 |
return r |
| 20 |
|
| 21 |
# 完了を待つpost |
| 22 |
syncPost = (url, data) -> |
| 23 |
show_wait_circle() |
| 24 |
|
| 25 |
r = jQuery.ajax({ |
| 26 |
type: "POST", |
| 27 |
url: url, |
| 28 |
data: data, |
| 29 |
dataType: "json", |
| 30 |
async: false |
| 31 |
}) |
| 32 |
|
| 33 |
hide_wait_circle() |
| 34 |
return r.responseJSON |
| 35 |
|
| 36 |
# Ajaxコマンド実行 |
| 37 |
ajax_exec_cmd = (cmd, message, skip=0) -> |
| 38 |
Y = window.yomeya |
| 39 |
hide_all_ui() |
| 40 |
message_box message, null, -> |
| 41 |
r = syncPost("/exec/#{cmd}", current_vpath_location()) |
| 42 |
Y.pagelist = r.pagelist |
| 43 |
$.each r.modify, (i, v) -> |
| 44 |
delete Y.page_cache[v] |
| 45 |
return true |
| 46 |
show_image(Y.loc_idx + skip) |
| 47 |
|
| 48 |
# locationからpageのURLを得る |
| 49 |
to_url = (location) -> |
| 50 |
Y = window.yomeya |
| 51 |
url = "/page/" + yomeya_escape(Y.vpath) + "?location=" + yomeya_escape(location) |
| 52 |
return url |
| 53 |
|
| 54 |
# 現在のvpathからなるオブジェクトを得る |
| 55 |
current_vpath = -> |
| 56 |
Y = window.yomeya |
| 57 |
return {path:Y.vpath} |
| 58 |
|
| 59 |
# 現在のvpathとlocationからなるオブジェクトを得る |
| 60 |
current_vpath_location = -> |
| 61 |
Y = window.yomeya |
| 62 |
return {path:Y.vpath, location:Y.pagelist[Y.loc_idx]} |
| 63 |
|
| 64 |
# 何頁目かを数値で得る |
| 65 |
location_to_idx = (location) -> |
| 66 |
Y = window.yomeya |
| 67 |
# まずは完全一致を探す |
| 68 |
i = Y.pagelist.indexOf(location) |
| 69 |
return i if i >= 0 |
| 70 |
# 完全一致がない場合は最も近いもの |
| 71 |
for loc, i in Y.pagelist |
| 72 |
if loc >= location |
| 73 |
return i |
| 74 |
return 0 # 見つからない場合は先頭頁 |
| 75 |
|
| 76 |
# 次に何頁をキャッシュに入れるか算出する |
| 77 |
get_next_prefetch_loc_idx = -> |
| 78 |
Y = window.yomeya |
| 79 |
for i in [0 .. 1] |
| 80 |
loc_idx = Y.loc_idx |
| 81 |
cache_direction = Y.page_cache_direction |
| 82 |
cache_direction *= -1 if i != 0 # 2周目は逆順 |
| 83 |
while true |
| 84 |
loc_idx += cache_direction |
| 85 |
if !(0 <= loc_idx < Y.pagelist.length) |
| 86 |
break |
| 87 |
location = Y.pagelist[loc_idx] |
| 88 |
if !Y.page_cache[location]? |
| 89 |
return loc_idx |
| 90 |
return 0 # 全頁キャッシュ済み |
| 91 |
|
| 92 |
# n頁目の画像オブジェクトを生成 |
| 93 |
get_image = (loc_idx, prefetch) -> |
| 94 |
Y = window.yomeya |
| 95 |
location = Y.pagelist[loc_idx] |
| 96 |
if location? |
| 97 |
# 既に生成済ならそれを返す (但しロード中かもしれない) |
| 98 |
if Y.page_cache[location]? |
| 99 |
return Y.page_cache[location] |
| 100 |
|
| 101 |
img = $("<img>").addClass("page").attr("id", "page_" + loc_idx) |
| 102 |
Y.page_cache[location] = img |
| 103 |
img.on "error", -> |
| 104 |
# エラー時は再試行 |
| 105 |
setTimeout(-> |
| 106 |
src = img.attr("src") |
| 107 |
img.attr("src", "").attr("src", src) |
| 108 |
, 500) |
| 109 |
img.on "load", -> |
| 110 |
$(this).addClass("loaded") |
| 111 |
if prefetch? |
| 112 |
setTimeout(-> |
| 113 |
get_image(get_next_prefetch_loc_idx(), true) |
| 114 |
, 787) |
| 115 |
img.attr("src", to_url(location)) |
| 116 |
return img |
| 117 |
return null |
| 118 |
|
| 119 |
# canvasに縦横比を保って内接するようサイズ調整 |
| 120 |
update_image_size = (canvas, img) -> |
| 121 |
Y = window.yomeya |
| 122 |
canvas_width = canvas.width() |
| 123 |
canvas_height = canvas.height() |
| 124 |
canvas_aspect_ratio = canvas_width / canvas_height # 大きいほど横長 |
| 125 |
img_width = img.width() |
| 126 |
img_height = img.height() |
| 127 |
img_aspect_ratio = img_width / img_height |
| 128 |
|
| 129 |
if canvas_aspect_ratio < 1 # 縦画面なら |
| 130 |
r = Y.settings.auto_rotate_p |
| 131 |
else |
| 132 |
r = Y.settings.auto_rotate_l |
| 133 |
if r == "r" || r == "l" |
| 134 |
auto_rotate = r |
| 135 |
else |
| 136 |
auto_rotate = null |
| 137 |
|
| 138 |
# 回転表示するかしないかの判定 |
| 139 |
rotate = null |
| 140 |
if auto_rotate? |
| 141 |
if canvas_aspect_ratio > 1 && img_aspect_ratio < 1 # 横長の画面に縦長の画像なら |
| 142 |
rotate = true |
| 143 |
else if canvas_aspect_ratio < 1 && img_aspect_ratio > 1 # 縦長の画面に横長の画像なら |
| 144 |
rotate = true |
| 145 |
|
| 146 |
if rotate? |
| 147 |
# 回転する場合は回転したうえで内接する大きさを計算 |
| 148 |
if 1/img_aspect_ratio > canvas_aspect_ratio # 画面より横長なら |
| 149 |
# 高さに合わせる |
| 150 |
new_height = canvas_width |
| 151 |
new_width = canvas_width * img_aspect_ratio |
| 152 |
else |
| 153 |
# 幅に合わせる |
| 154 |
new_height = canvas_height / img_aspect_ratio |
| 155 |
new_width = canvas_height |
| 156 |
else |
| 157 |
if img_aspect_ratio > canvas_aspect_ratio # 画面より横長なら |
| 158 |
# 幅に合わせる |
| 159 |
new_width = canvas_width |
| 160 |
new_height = canvas_width / img_aspect_ratio |
| 161 |
else |
| 162 |
# 高さに合わせる |
| 163 |
new_width = canvas_height * img_aspect_ratio |
| 164 |
new_height = canvas_height |
| 165 |
|
| 166 |
img.width(new_width) |
| 167 |
img.height(new_height) |
| 168 |
img.css("top", (canvas_height - new_height) / 2) |
| 169 |
img.css("left", (canvas_width - new_width) / 2) |
| 170 |
img.removeClass("rotate_l rotate_r") |
| 171 |
if rotate? |
| 172 |
if auto_rotate == "r" |
| 173 |
rc = "rotate_r" |
| 174 |
else # if auto_rotate == "l" |
| 175 |
rc = "rotate_l" |
| 176 |
img.addClass(rc) |
| 177 |
|
| 178 |
for e in ["cut", "fade", "right", "left"] |
| 179 |
for io in ["_in", "_out"] |
| 180 |
tc = e + io |
| 181 |
if img.hasClass(tc) |
| 182 |
img.removeClass(tc).addClass(tc + "_" + rc) |
| 183 |
|
| 184 |
# 頁の画像を表示する |
| 185 |
show_image = (loc_idx, transition) -> |
| 186 |
Y = window.yomeya |
| 187 |
slideshow("prevent") # スライドショー遷移を保留 |
| 188 |
loc_idx = Y.pagelist.length - 1 if loc_idx >= Y.pagelist.length |
| 189 |
loc_idx = 0 if loc_idx < 0 |
| 190 |
img = get_image(loc_idx) |
| 191 |
if !img.hasClass("loaded") |
| 192 |
# 画像のロードがまだ終わっていなければ待つ |
| 193 |
setTimeout(-> |
| 194 |
show_image(loc_idx) |
| 195 |
, 50) |
| 196 |
else |
| 197 |
canvas = $("#canvas") |
| 198 |
canvas.children().not(".showing").remove() # 今表示しているもの以外は削除 |
| 199 |
old = canvas.children() # 今表示しているもの |
| 200 |
old.removeClass("showing") |
| 201 |
img.addClass("showing") |
| 202 |
|
| 203 |
# ついているクラスを削除してきれいにする |
| 204 |
if !Y.transition_classes? |
| 205 |
Y.transition_classes = "" |
| 206 |
for e in ["cut", "fade", "right", "left"] |
| 207 |
for io in ["_in", "_out"] |
| 208 |
for r in ["", "_rotate_r", "_rotate_l"] |
| 209 |
Y.transition_classes += e + io + r + " " |
| 210 |
old.removeClass(Y.transition_classes) |
| 211 |
img.removeClass(Y.transition_classes) |
| 212 |
|
| 213 |
# img != old なら画面遷移 |
| 214 |
if !old.hasClass("showing") |
| 215 |
old_transition = "cut_out" |
| 216 |
img_transition = "" |
| 217 |
old_zindex = 0 |
| 218 |
img_zindex = -1 |
| 219 |
|
| 220 |
# 画面遷移効果 |
| 221 |
if transition? |
| 222 |
if /^(left|right)_in/.test(transition) |
| 223 |
old_transition = "fade_out" |
| 224 |
img_transition = transition |
| 225 |
old_zindex = -1 |
| 226 |
img_zindex = 0 |
| 227 |
else |
| 228 |
old_transition = transition |
| 229 |
img_transition = "fade_in" |
| 230 |
|
| 231 |
# プラス回転効果 |
| 232 |
if old.hasClass("rotate_r") |
| 233 |
old_transition = old_transition + "_rotate_r" |
| 234 |
if old.hasClass("rotate_l") |
| 235 |
old_transition = old_transition + "_rotate_l" |
| 236 |
|
| 237 |
old.css("z-index", old_zindex).addClass(old_transition) |
| 238 |
img.css("z-index", img_zindex).addClass(img_transition) |
| 239 |
|
| 240 |
# 画面遷移が終わった頃に古い画像をDOMツリーから削除 |
| 241 |
setTimeout(-> |
| 242 |
old.remove() if !old.hasClass("showing") |
| 243 |
, 500) |
| 244 |
|
| 245 |
canvas.prepend(img) |
| 246 |
update_image_size(canvas, img) |
| 247 |
|
| 248 |
# 内部情報更新 |
| 249 |
Y.loc_idx = loc_idx |
| 250 |
# メニュー1の情報更新 |
| 251 |
update_menu1() |
| 252 |
# サーバの情報更新 |
| 253 |
$.post("/viewer/loc", current_vpath_location()) |
| 254 |
# スライドショー中なら |
| 255 |
if slideshow("running?") |
| 256 |
slideshow("next") |
| 257 |
|
| 258 |
# 画面リサイズ時の処理 本体 |
| 259 |
_onresize_handler = -> |
| 260 |
Y = window.yomeya |
| 261 |
status_height = 0 |
| 262 |
w = window.innerWidth |
| 263 |
h = window.innerHeight |
| 264 |
|
| 265 |
if "ios" in Y.uatype |
| 266 |
if Y.settings.statusbar == "skip" |
| 267 |
status_height = 17 |
| 268 |
|
| 269 |
if window.innerWidth < window.innerHeight |
| 270 |
w = screen.width # 縦長の場合 |
| 271 |
h = screen.height |
| 272 |
else |
| 273 |
w = screen.height # 横長の場合 |
| 274 |
h = screen.width |
| 275 |
|
| 276 |
hide_all_ui() |
| 277 |
$('meta[name="viewport"]').attr("content", "width=#{w}px,height=#{h}px,user-scalable=no") |
| 278 |
$(".tap_panel").width(w).height(h) |
| 279 |
$(".ui_panel").width(w).height(h) |
| 280 |
$("#canvas").width(w).height(h - status_height).css("top", status_height) |
| 281 |
update_image_size($("#canvas"), $(".showing")) |
| 282 |
|
| 283 |
# 画面リサイズ時の処理 元請け |
| 284 |
onresize_handler = -> |
| 285 |
Y = window.yomeya |
| 286 |
if Y.onresize_handler_timer? |
| 287 |
clearTimeout(Y.onresize_handler_timer) |
| 288 |
Y.onresize_handler_timer = setTimeout(-> |
| 289 |
Y.onresize_handler_timer = null |
| 290 |
_onresize_handler() |
| 291 |
, 100) |
| 292 |
|
| 293 |
# フルスクリーン化 |
| 294 |
request_fullscreen = -> |
| 295 |
body = document.body |
| 296 |
if body.requestFullScreen? |
| 297 |
body.requestFullScreen() |
| 298 |
else if body.mozRequestFullScreen? |
| 299 |
body.mozRequestFullScreen() |
| 300 |
else if body.webkitRequestFullScreen? |
| 301 |
body.webkitRequestFullScreen() |
| 302 |
|
| 303 |
# キー入力時の処理 |
| 304 |
onkeydown_handler = (ev) -> |
| 305 |
return true if $("#menu1").css("display") != "none" |
| 306 |
|
| 307 |
Y = window.yomeya |
| 308 |
ev.preventDefault() |
| 309 |
w = ev.which |
| 310 |
k = ev.keyCode |
| 311 |
c = ev.charCode |
| 312 |
|
| 313 |
if k == 37 && c == 0 # [←] |
| 314 |
if Y.settings.reading_direction == "lr" |
| 315 |
move_prev_page() |
| 316 |
else |
| 317 |
move_next_page() |
| 318 |
else if k == 38 && c == 0 # [↑] |
| 319 |
move_prev_page() |
| 320 |
else if k == 39 && c == 0 # [→] |
| 321 |
if Y.settings.reading_direction == "lr" |
| 322 |
move_next_page() |
| 323 |
else |
| 324 |
move_prev_page() |
| 325 |
else if k == 40 && c == 0 # [↓] |
| 326 |
move_next_page() |
| 327 |
else if k == 8 && c == 0 # [BS] |
| 328 |
close_book() |
| 329 |
# else if k == 0 && c == 102 # [f] |
| 330 |
# request_fullscreen() |
| 331 |
# else |
| 332 |
# alert "w#{w} k#{k} c#{c}" |
| 333 |
|
| 334 |
# マウスホイール回転時の処理 |
| 335 |
onwheel_handler = (ev) -> |
| 336 |
return true if $("#menu1").css("display") != "none" |
| 337 |
|
| 338 |
Y = window.yomeya |
| 339 |
ev.preventDefault() |
| 340 |
dy = ev.originalEvent.deltaY |
| 341 |
if "firefox" in Y.uatype |
| 342 |
dy *= 100.0 / 3.0 |
| 343 |
|
| 344 |
Y.wheelY += dy |
| 345 |
if Y.wheelY <= -100 |
| 346 |
move_next_page() |
| 347 |
else if Y.wheelY >= 100 |
| 348 |
move_prev_page() |
| 349 |
Y.wheelY %= 100 |
| 350 |
|
| 351 |
# 初期設定 |
| 352 |
$ -> |
| 353 |
# controllerから引数を受け取る & 変数初期化 |
| 354 |
Y = window.yomeya = {} |
| 355 |
Y.uatype = $("#Y").data("uatype") |
| 356 |
Y.vpath = $("#Y").data("vpath") |
| 357 |
Y.pagelist = $("#Y").data("pagelist") |
| 358 |
Y.loc_idx = location_to_idx($("#Y").data("location")) |
| 359 |
Y.settings = $("#Y").data("settings") |
| 360 |
Y.wheelY = 0 |
| 361 |
Y.page_cache = {} |
| 362 |
Y.page_cache_direction = 1 |
| 363 |
|
| 364 |
# 一部を除きスクロール禁止 |
| 365 |
$(document).on "touchmove", (e) -> |
| 366 |
e.preventDefault() |
| 367 |
$(".scrollable").on "touchmove", (e) -> |
| 368 |
e.stopPropagation() |
| 369 |
|
| 370 |
# ハンドラ設定 |
| 371 |
$.each [ |
| 372 |
[".tap_close_book", close_book] |
| 373 |
[".tap_first", cmd_first_page] |
| 374 |
[".tap_last", cmd_last_page] |
| 375 |
[".tap_next", tap_next] |
| 376 |
[".tap_prev", tap_prev] |
| 377 |
[".tap_show_menu1", show_menu1] |
| 378 |
[".tap_show_menu2", show_menu2] |
| 379 |
["#cmd_first_page", cmd_first_page] |
| 380 |
["#cmd_last_page", cmd_last_page] |
| 381 |
["#cmd_close_book", close_book] |
| 382 |
["#cmd_close_menu", hide_menu1] |
| 383 |
["#cmd_next", -> cmd_moveto(1)] |
| 384 |
["#cmd_next10", -> cmd_moveto(10)] |
| 385 |
["#cmd_prev", -> cmd_moveto(-1)] |
| 386 |
["#cmd_prev10", -> cmd_moveto(-10)] |
| 387 |
["#cmd_pagelist", cmd_pagelist] |
| 388 |
["#pageinfo_panel", hide_pageinfo] |
| 389 |
], (_, v) -> |
| 390 |
# 反応のいいclickイベントハンドラを追加する |
| 391 |
$(v[0]).off().on "click touchstart", (ev) -> |
| 392 |
ev.preventDefault() |
| 393 |
v[1]() |
| 394 |
|
| 395 |
# 背景色の設定 |
| 396 |
switch Y.settings.bg_color |
| 397 |
when "black" |
| 398 |
$("body").css("background-color", "black") |
| 399 |
when "white" |
| 400 |
$("body").css("background-color", "white") |
| 401 |
when "gray" |
| 402 |
$("body").css("background-color", "gray") |
| 403 |
|
| 404 |
# メニュー1の情報更新 |
| 405 |
update_menu1() |
| 406 |
|
| 407 |
# フック |
| 408 |
_onresize_handler() |
| 409 |
$(window).on("orientationchange resize", onresize_handler) |
| 410 |
if "pc" in Y.uatype |
| 411 |
$(window).on("keydown", onkeydown_handler) |
| 412 |
$(window).on("wheel", onwheel_handler) |
| 413 |
# else |
| 414 |
# $(".tap_panel").hammer().on "swiperight", (ev) -> |
| 415 |
# ev.preventDefault() |
| 416 |
# tap_next() |
| 417 |
# $(".tap_panel").hammer().on "swipeleft", (ev) -> |
| 418 |
# ev.preventDefault() |
| 419 |
# tap_prev() |
| 420 |
|
| 421 |
# 画像を表示 & プリフェッチ開始 |
| 422 |
get_image(Y.loc_idx, true) |
| 423 |
show_image(Y.loc_idx) |
| 424 |
hide_wait_circle() |
| 425 |
|
| 426 |
############################################################ |
| 427 |
|
| 428 |
# スライドショーを行う処理 |
| 429 |
slideshow = (action) -> |
| 430 |
Y = window.yomeya |
| 431 |
if action == "start" |
| 432 |
Y.slideshow_interval = 3000 |
| 433 |
slideshow("next") |
| 434 |
else if action == "stop" |
| 435 |
Y.slideshow_interval = null |
| 436 |
if Y.slideshow_timer? |
| 437 |
clearTimeout(Y.slideshow_timer) |
| 438 |
Y.slideshow_timer = null |
| 439 |
else if action == "next" |
| 440 |
if Y.loc_idx < Y.pagelist.length - 1 |
| 441 |
Y.slideshow_timer = |
| 442 |
setTimeout(move_next_page, Y.slideshow_interval) |
| 443 |
else |
| 444 |
Y.slideshow_timer = setTimeout(-> |
| 445 |
notice("スライドショー終了") |
| 446 |
, Y.slideshow_interval) |
| 447 |
Y.slideshow_interval = null |
| 448 |
else if action == "running?" |
| 449 |
return Y.slideshow_interval? |
| 450 |
else if action == "prevent" |
| 451 |
if Y.slideshow_timer? |
| 452 |
clearTimeout(Y.slideshow_timer) |
| 453 |
Y.slideshow_timer = null |
| 454 |
|
| 455 |
############################################################ |
| 456 |
|
| 457 |
# 頁移動 |
| 458 |
move_page_to = (loc_idx, transition) -> |
| 459 |
Y = window.yomeya |
| 460 |
if loc_idx >= Y.pagelist.length |
| 461 |
loc_idx = Y.pagelist.length - 1 |
| 462 |
notice("最後の頁です") |
| 463 |
if loc_idx < 0 |
| 464 |
loc_idx = 0 |
| 465 |
notice("先頭の頁です") |
| 466 |
|
| 467 |
show_image(loc_idx, transition) |
| 468 |
|
| 469 |
move_first_page = -> |
| 470 |
move_page_to(0) |
| 471 |
|
| 472 |
move_last_page = -> |
| 473 |
move_page_to(window.yomeya.pagelist.length - 1) |
| 474 |
|
| 475 |
# 相対頁移動 |
| 476 |
move_page_relative = (offset) -> |
| 477 |
Y = window.yomeya |
| 478 |
loc_idx = Y.loc_idx + offset |
| 479 |
Y.page_cache_direction = if offset >= 0 then 1 else -1 |
| 480 |
|
| 481 |
transition = null |
| 482 |
if Y.settings.reading_direction == "rl" |
| 483 |
if offset > 0 |
| 484 |
transition = "right_out" |
| 485 |
else if offset < 0 |
| 486 |
transition = "right_in" |
| 487 |
else if Y.settings.reading_direction == "lr" |
| 488 |
if offset > 0 |
| 489 |
transition = "left_out" |
| 490 |
else if offset < 0 |
| 491 |
transition = "left_in" |
| 492 |
|
| 493 |
move_page_to(loc_idx, transition) |
| 494 |
|
| 495 |
move_next_page = -> |
| 496 |
move_page_relative(1) |
| 497 |
|
| 498 |
move_prev_page = -> |
| 499 |
move_page_relative(-1) |
| 500 |
|
| 501 |
############################################################ |
| 502 |
|
| 503 |
show_menu1 = -> |
| 504 |
Y = window.yomeya |
| 505 |
slideshow("stop") # とりあえずスライドショーを停止 |
| 506 |
tap = $(".tap_panel .tap") |
| 507 |
if tap.css("opacity") != 0 |
| 508 |
tap.css("opacity", 0) |
| 509 |
|
| 510 |
# メニューアイテムの設定 |
| 511 |
$("#menu1_cmds li").remove() |
| 512 |
cmds = [ |
| 513 |
["cmd_pageinfo", cmd_pageinfo, "この頁の情報を表示"] |
| 514 |
["cmd_set_tag", cmd_set_tag, "タグをつける"] |
| 515 |
["cmd_show_tag", cmd_show_tag, "つけたタグ"] |
| 516 |
["cmd_start_slideshow", cmd_start_slideshow, "スライドショー"] |
| 517 |
["cmd_rotate_page_r", cmd_rotate_page_r, "この頁を右90度回転"] |
| 518 |
["cmd_rotate_page_l", cmd_rotate_page_l, "この頁を左90度回転"] |
| 519 |
["cmd_join_page", cmd_join_page, "前の頁と見開きにする"] |
| 520 |
["cmd_hide_page", cmd_hide_page, "この頁を非表示にする"] |
| 521 |
["cmd_set_unread", cmd_set_unread, "この本を未読にする"] |
| 522 |
["cmd_set_read", cmd_set_read, "この本を読了にする"] |
| 523 |
["cmd_download_page", cmd_download_page, "この頁をダウンロード"] |
| 524 |
["cmd_download_book", cmd_download_book, "この本をダウンロード"] |
| 525 |
["cmd_fullscreen", cmd_fullscreen, "フルスクリーン表示"] |
| 526 |
["cmd_toggle_tap", cmd_toggle_tap, "画面タップのガイドを表示"] |
| 527 |
["cmd_setting", cmd_setting, "設定"] |
| 528 |
] |
| 529 |
$.each cmds, (_, cmd) -> |
| 530 |
icon = $("<div>").addClass("icon").attr("id", cmd[0]) |
| 531 |
text = $("<div>").text(cmd[2]) |
| 532 |
tr = $("<tr>").append($("<td>").append(icon)).append($("<td>").append(text)) |
| 533 |
li = $("<li>").addClass(cmd[0]).append($("<table>").append(tr)) |
| 534 |
$("#menu1_cmds").append(li) |
| 535 |
li.on "click", (ev) -> |
| 536 |
ev.preventDefault() |
| 537 |
cmd[1]() |
| 538 |
|
| 539 |
# アイコン画像を設定 |
| 540 |
src = "url(/assets/cmd.png)" |
| 541 |
if $("#menu1 .icon").css("background-image") != src |
| 542 |
# convert -strip +append cmd_*.png cmd.png |
| 543 |
$("#menu1 .icon").css("background-image", src) |
| 544 |
pos = 0 |
| 545 |
for el in [ |
| 546 |
"#cmd_close_book", "#cmd_close_menu", "#cmd_download_book", "#cmd_download_page", |
| 547 |
"#cmd_first_page", "#cmd_fullscreen", "#cmd_hide_page", "#cmd_join_page", |
| 548 |
"#cmd_last_page", "#cmd_next", "#cmd_next10", "#cmd_pageinfo", |
| 549 |
"#cmd_pagelist", "#cmd_prev", "#cmd_prev10", "#cmd_rotate_page_l", |
| 550 |
"#cmd_rotate_page_r", "#cmd_set_read", "#cmd_set_tag", "#cmd_set_unread", |
| 551 |
"#cmd_setting", "#cmd_show_tag", "#cmd_start_slideshow", "#cmd_toggle_tap" |
| 552 |
] |
| 553 |
$(el).css("background-position", "#{pos}px 0") |
| 554 |
pos -= $(el).width() |
| 555 |
|
| 556 |
# 不要なメニューアイテムを非表示にする |
| 557 |
if true |
| 558 |
$("#cmd_set_tag").parents("li").css("display", "none") |
| 559 |
$("#cmd_show_tag").parents("li").css("display", "none") |
| 560 |
unless "pc" in Y.uatype |
| 561 |
$("#cmd_download_page").parents("li").css("display", "none") |
| 562 |
$("#cmd_download_book").parents("li").css("display", "none") |
| 563 |
$("#cmd_fullscreen").parents("li").css("display", "none") |
| 564 |
|
| 565 |
hide_all_ui() |
| 566 |
$(".tap_panel").hide() |
| 567 |
$("#menu1").show() |
| 568 |
|
| 569 |
# メニューコマンドの幅を設定 |
| 570 |
ul = $("#menu1 ul") |
| 571 |
li = $("#menu1 ul li") |
| 572 |
if li.length > 0 |
| 573 |
menu1_columns = Math.floor(ul[0].clientWidth / 260) |
| 574 |
li.width(ul[0].clientWidth / menu1_columns) |
| 575 |
ul.height(window.innerHeight - $("#menu1_head").height() - $("#menu1_foot").height() - 2) # 2はborder |
| 576 |
|
| 577 |
hide_menu1 = -> |
| 578 |
$(".tap_panel").show() |
| 579 |
$("#menu1").fadeOut("fast") |
| 580 |
|
| 581 |
update_menu1 = -> |
| 582 |
Y = window.yomeya |
| 583 |
$("#menu1_vpath").text(Y.vpath.replace(/\/\*img$/, "/")) |
| 584 |
$("#menu1_location").text(Y.pagelist[Y.loc_idx]) |
| 585 |
$("#menu1_posbar").css("width", "#{Y.loc_idx / (Y.pagelist.length-1) * 100}%") |
| 586 |
$("#menu1_pages_count").text("#{Y.loc_idx+1} / #{Y.pagelist.length}") |
| 587 |
|
| 588 |
show_menu2 = -> |
| 589 |
|
| 590 |
# notice(画面上部 長)を表示 |
| 591 |
notice = (msg) -> |
| 592 |
Y = window.yomeya |
| 593 |
if Y.notice_timer? |
| 594 |
clearTimeout(Y.notice_timer) |
| 595 |
Y.notice_timer = null |
| 596 |
$("#notice").stop(true, true).text(msg).show() |
| 597 |
Y.notice_timer = setTimeout(-> |
| 598 |
Y.notice_timer = null |
| 599 |
$("#notice").fadeOut("slow") |
| 600 |
, 1500) |
| 601 |
|
| 602 |
# notice2(画面中央 短)を表示 |
| 603 |
notice2 = (msg) -> |
| 604 |
Y = window.yomeya |
| 605 |
if Y.notice2_timer? |
| 606 |
clearTimeout(Y.notice2_timer) |
| 607 |
Y.notice2_timer = null |
| 608 |
$("#notice2").stop(true, true).text(msg).show() |
| 609 |
Y.notice2_timer = setTimeout(-> |
| 610 |
Y.notice2_timer = null |
| 611 |
$("#notice2").fadeOut("fast") |
| 612 |
, 400) |
| 613 |
|
| 614 |
hide_all_ui = -> |
| 615 |
hide_menu1() |
| 616 |
hide_pageinfo() |
| 617 |
|
| 618 |
############################################################ |
| 619 |
|
| 620 |
tap_next = -> |
| 621 |
move_next_page() |
| 622 |
|
| 623 |
tap_prev = -> |
| 624 |
move_prev_page() |
| 625 |
|
| 626 |
close_book = -> |
| 627 |
show_wait_circle() |
| 628 |
location.href = "/to_parent" |
| 629 |
|
| 630 |
cmd_first_page = -> |
| 631 |
notice2("先頭の頁") |
| 632 |
move_first_page() |
| 633 |
|
| 634 |
cmd_last_page = -> |
| 635 |
notice2("最後の頁") |
| 636 |
move_last_page() |
| 637 |
|
| 638 |
cmd_pageinfo = -> |
| 639 |
r = syncPost("/exec/pageinfo", current_vpath_location()) |
| 640 |
hide_all_ui() |
| 641 |
$("#pageinfo_panel").show() |
| 642 |
$("#pageinfo").children().remove() |
| 643 |
if r.vpath? |
| 644 |
$("#pageinfo").append($("<div>").text(r.vpath)) |
| 645 |
if r.location? |
| 646 |
$("#pageinfo").append($("<div>").text(r.location)) |
| 647 |
if r.size? |
| 648 |
$("#pageinfo").append($("<div>").text(r.size)) |
| 649 |
if r.datetime? |
| 650 |
$("#pageinfo").append($("<div>").text(r.datetime)) |
| 651 |
if r.geometry? |
| 652 |
$("#pageinfo").append($("<div>").text(r.geometry)) |
| 653 |
if r.format? |
| 654 |
$("#pageinfo").append($("<div>").text(r.format)) |
| 655 |
|
| 656 |
hide_pageinfo = -> |
| 657 |
$(".tap_panel").show() |
| 658 |
$("#pageinfo_panel").fadeOut("fast") |
| 659 |
|
| 660 |
cmd_set_tag = -> |
| 661 |
Y = window.yomeya |
| 662 |
cmd = "set_tag" |
| 663 |
|
| 664 |
cmd_show_tag = -> |
| 665 |
Y = window.yomeya |
| 666 |
cmd = "show_tag" |
| 667 |
|
| 668 |
cmd_start_slideshow = -> |
| 669 |
hide_all_ui() |
| 670 |
if slideshow("running?") |
| 671 |
slideshow("stop") |
| 672 |
else |
| 673 |
slideshow("start") |
| 674 |
|
| 675 |
cmd_rotate_page_r = -> |
| 676 |
ajax_exec_cmd("rotate_r", "この頁を右回転します") |
| 677 |
|
| 678 |
cmd_rotate_page_l = -> |
| 679 |
ajax_exec_cmd("rotate_l", "この頁を左回転します") |
| 680 |
|
| 681 |
cmd_join_page = -> |
| 682 |
ajax_exec_cmd("join_page", "前の頁と結合して見開きにします", -1) |
| 683 |
|
| 684 |
cmd_hide_page = -> |
| 685 |
ajax_exec_cmd("hide_page", "この頁を非表示にします") |
| 686 |
|
| 687 |
cmd_set_unread = -> |
| 688 |
cmd = "set_unread" |
| 689 |
message_box "この本を未読にします", null, -> |
| 690 |
syncPost("/exec/#{cmd}", current_vpath()) |
| 691 |
close_book() |
| 692 |
|
| 693 |
cmd_set_read = -> |
| 694 |
cmd = "set_read" |
| 695 |
message_box "この本を読了にします", null, -> |
| 696 |
syncPost("/exec/#{cmd}", current_vpath()) |
| 697 |
close_book() |
| 698 |
|
| 699 |
cmd_fullscreen = -> |
| 700 |
request_fullscreen() |
| 701 |
|
| 702 |
cmd_download_page = -> |
| 703 |
ajax_exec_cmd("download_page", "download_page") |
| 704 |
|
| 705 |
cmd_download_book = -> |
| 706 |
ajax_exec_cmd("download_book", "download_book") |
| 707 |
|
| 708 |
cmd_toggle_tap = -> |
| 709 |
hide_all_ui() |
| 710 |
tap = $(".tap_panel .tap") |
| 711 |
tap.css("opacity", 1.0) |
| 712 |
|
| 713 |
cmd_setting = -> |
| 714 |
show_wait_circle() |
| 715 |
location.href = "/setting" |
| 716 |
|
| 717 |
cmd_moveto = (offset) -> |
| 718 |
if offset >= 0 |
| 719 |
if offset == 1 |
| 720 |
notice2("次の頁") |
| 721 |
else |
| 722 |
notice2("#{offset}頁進む") |
| 723 |
else |
| 724 |
if offset == -1 |
| 725 |
notice2("前の頁") |
| 726 |
else |
| 727 |
notice2("#{-offset}頁戻る") |
| 728 |
move_page_relative(offset) |
| 729 |
|
| 730 |
cmd_pagelist = -> |
| 731 |
show_wait_circle() |
| 732 |
location.href = "/pagelist" |