diff --git a/cps/static/css/kthoom.css b/cps/static/css/kthoom.css index a6b41a32..061d171b 100644 --- a/cps/static/css/kthoom.css +++ b/cps/static/css/kthoom.css @@ -1,27 +1,58 @@ body { background: #444; - overflow: hidden; + overflow-x: hidden; + overflow-y: auto; color: white; font-family: sans-serif; margin: 0px; } -.main { - position: re; - left: 5px; - overflow: hidden; - right: 5px; +#main { text-align: center; - top: 5px; + z-index: 2; +} + +#sidebar a, +#sidebar ul, +#sidebar li, +#sidebar li img { + max-width: 100%; + text-align: center; +} + +#sidebar a { + display: inline-block; + position: relative; + cursor: pointer; +} + +#sidebar li img { + display: block; + max-height: 200px; +} + +#sidebar li img + span { + position: absolute; + bottom: 0; + right: 0; + padding: 2px; + min-width: 25px; + line-height: 25px; + background: #6b6b6b; + border-top-left-radius: 5px; +} + +#sidebar #panels { + z-index: 1; } #progress { position: absolute; display: inline; - left: 90px; - right: 160px; + left: 20%; + right: 20%; height: 20px; - margin-top: 1px; + margin-top: 4px; text-align: right; } @@ -29,6 +60,10 @@ body { display: none !important; } +#mainContent { + overflow: auto; +} + #mainText { text-align: left; width: 90%; @@ -42,29 +77,9 @@ body { word-wrap: break-word; } -#mainImage{ - margin-top: 32px; -} - -#titlebar.main { - opacity: 0; - position: absolute; - top: 0; - height: 30px; - left: 0; - right: 0; - background-color: black; - padding-bottom: 70px; - -webkit-transition: opacity 0.2s ease; - -moz-transition: opacity 0.2s ease; - transition: opacity 0.2s ease; - background: -moz-linear-gradient(top, rgba(0,2,34,1) 0%, rgba(0,1,24,1) 30%, rgba(0,0,0,0) 100%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(0,2,34,1)), color-stop(30%,rgba(0,1,24,1)), color-stop(100%,rgba(0,0,0,0))); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, rgba(0,2,34,1) 0%,rgba(0,1,24,1) 30%,rgba(0,0,0,0) 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, rgba(0,2,34,1) 0%,rgba(0,1,24,1) 30%,rgba(0,0,0,0) 100%); /* Opera11.10+ */ - background: -ms-linear-gradient(top, rgba(0,2,34,1) 0%,rgba(0,1,24,1) 30%,rgba(0,0,0,0) 100%); /* IE10+ */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#000222', endColorstr='#00000000',GradientType=0 ); /* IE6-9 */ - background: linear-gradient(top, rgba(0,2,34,1) 0%,rgba(0,1,24,1) 30%,rgba(0,0,0,0) 100%); /* W3C */ +#titlebar { + min-height: 25px; + height: auto; } #prev { @@ -100,6 +115,67 @@ body { color: #000; } +th, td { + padding: 5px; +} + +th { + text-align: right; + vertical-align: top; +} + +.modal { + /* Makes the modal responsive. Note sure if this should be moved to main.css */ + margin: 0; + max-width: 96%; + transform: translate(-50%, -50%); +} + +.md-content { + min-height: 320px; + height: auto; +} + +.md-content > div { + overflow: hidden; +} + +.md-content > div p { + padding: 5px 0; +} + +.settings-column { + float: left; + min-width: 35%; + padding-bottom: 10px; +} +.inputs { + margin: -5px; +} + +.inputs input { + vertical-align: middle; +} +.inputs label { + display: inline-block; + margin: 5px; + white-space: nowrap; +} + +.dark-theme #main { + background-color: #000; +} +.dark-theme #titlebar { + color: #DDD; +} + +.dark-theme #titlebar a:active { + color: #FFF; +} + +.dark-theme .overlay { + background-color: rgba(0,0,0,0.8); +} diff --git a/cps/static/js/kthoom.js b/cps/static/js/kthoom.js index 0dd41322..72c1d04d 100644 --- a/cps/static/js/kthoom.js +++ b/cps/static/js/kthoom.js @@ -55,9 +55,6 @@ kthoom.Key = { RIGHT_SQUARE_BRACKET: 221 }; -// The rotation orientation of the comic. -kthoom.rotateTimes = 0; - // global variables var unarchiver = null; var currentImage = 0; @@ -66,33 +63,45 @@ var imageFilenames = []; var totalImages = 0; var lastCompletion = 0; -var hflip = false, vflip = false, fitMode = kthoom.Key.B; +var settings = { + hflip: false, + vflip: false, + rotateTimes: 0, + fitMode: kthoom.Key.B, + theme: 'light' +}; + var canKeyNext = true, canKeyPrev = true; kthoom.saveSettings = function() { - localStorage.kthoomSettings = JSON.stringify({ - rotateTimes: kthoom.rotateTimes, - hflip: hflip, - vflip: vflip, - fitMode: fitMode - }); + localStorage.kthoomSettings = JSON.stringify(settings); }; kthoom.loadSettings = function() { try { - if (localStorage.kthoomSettings.length < 10){ + if (!localStorage.kthoomSettings){ return; } - var s = JSON.parse(localStorage.kthoomSettings); - kthoom.rotateTimes = s.rotateTimes; - hflip = s.hflip; - vflip = s.vflip; - fitMode = s.fitMode; + + $.extend(settings, JSON.parse(localStorage.kthoomSettings)); + + kthoom.setSettings(); } catch (err) { alert("Error load settings"); } }; +kthoom.setSettings = function() { + // Set settings control values + $.each(settings, function(key, value) { + if (typeof value === "boolean") { + $('input[name='+key+']').prop('checked', value); + } else { + $('input[name='+key+']').val([value]); + } + }); +}; + var createURLFromArray = function(array, mimeType) { var offset = array.byteOffset, len = array.byteLength; var url; @@ -279,6 +288,17 @@ function loadFromArrayBuffer(ab) { if (imageFilenames.indexOf(f.filename) === -1) { imageFilenames.push(f.filename); imageFiles.push(new kthoom.ImageFile(f)); + + // add thumbnails to the TOC list + $('#thumbnails').append( + "
  • \ + \ + \ + "+ imageFiles.length +" \ + \ +
  • " + ); + //} } var percentage = (ab.page+1) / (ab.last+1); totalImages = ab.last+1; @@ -304,6 +324,11 @@ function updatePage() { } else { setImage("loading"); } + + $('body').toggleClass('dark-theme', settings.theme === 'dark'); + + kthoom.setSettings(); + kthoom.saveSettings(); } function setImage(url) { @@ -359,22 +384,22 @@ function setImage(url) { w = img.width, sw = w, sh = h; - kthoom.rotateTimes = (4 + kthoom.rotateTimes) % 4; + settings.rotateTimes = (4 + settings.rotateTimes) % 4; x.save(); - if (kthoom.rotateTimes % 2 === 1) { + if (settings.rotateTimes % 2 === 1) { sh = w; sw = h; } canvas.height = sh; canvas.width = sw; x.translate(sw / 2, sh / 2); - x.rotate(Math.PI / 2 * kthoom.rotateTimes); + x.rotate(Math.PI / 2 * settings.rotateTimes); x.translate(-w / 2, -h / 2); - if (vflip) { + if (settings.vflip) { x.scale(1, -1); x.translate(0, -h); } - if (hflip) { + if (settings.hflip) { x.scale(-1, 1); x.translate(-w, 0); } @@ -418,19 +443,19 @@ function updateScale(clear) { mainImageStyle.height = ""; mainImageStyle.maxWidth = ""; mainImageStyle.maxHeight = ""; - var maxheight = innerHeight - 15; - if (!/main/.test(getElem("titlebar").className)) { - maxheight -= 25; - } - if (clear || fitMode === kthoom.Key.N) { - } else if (fitMode === kthoom.Key.B) { + var maxheight = innerHeight - 50; + + if (clear || settings.fitMode === kthoom.Key.N) { + } else if (settings.fitMode === kthoom.Key.B) { mainImageStyle.maxWidth = "100%"; mainImageStyle.maxHeight = maxheight + "px"; - } else if (fitMode === kthoom.Key.H) { + } else if (settings.fitMode === kthoom.Key.H) { mainImageStyle.height = maxheight + "px"; - } else if (fitMode === kthoom.Key.W) { + } else if (settings.fitMode === kthoom.Key.W) { mainImageStyle.width = "100%"; } + $('#mainContent').css({maxHeight: maxheight + 5}); + kthoom.setSettings(); kthoom.saveSettings(); } @@ -446,50 +471,53 @@ function keyHandler(evt) { if (evt.ctrlKey || evt.shiftKey || evt.metaKey) return; switch (code) { case kthoom.Key.LEFT: - if (canKeyPrev) showPrevPage(); + showPrevPage(); break; case kthoom.Key.RIGHT: - if (canKeyNext) showNextPage(); + showNextPage(); break; case kthoom.Key.L: - kthoom.rotateTimes--; - if (kthoom.rotateTimes < 0) { - kthoom.rotateTimes = 3; + settings.rotateTimes--; + if (settings.rotateTimes < 0) { + settings.rotateTimes = 3; } updatePage(); break; case kthoom.Key.R: - kthoom.rotateTimes++; - if (kthoom.rotateTimes > 3) { - kthoom.rotateTimes = 0; + settings.rotateTimes++; + if (settings.rotateTimes > 3) { + settings.rotateTimes = 0; } updatePage(); break; case kthoom.Key.F: - if (!hflip && !vflip) { - hflip = true; - } else if (hflip === true) { - vflip = true; - hflip = false; - } else if (vflip === true) { - vflip = false; + if (!settings.hflip && !settings.vflip) { + settings.hflip = true; + } else if (settings.hflip === true && settings.vflip === true) { + settings.vflip = false; + settings.hflip = false; + } else if (settings.hflip === true) { + settings.vflip = true; + settings.hflip = false; + } else if (settings.vflip === true) { + settings.hflip = true; } updatePage(); break; case kthoom.Key.W: - fitMode = kthoom.Key.W; + settings.fitMode = kthoom.Key.W; updateScale(); break; case kthoom.Key.H: - fitMode = kthoom.Key.H; + settings.fitMode = kthoom.Key.H; updateScale(); break; case kthoom.Key.B: - fitMode = kthoom.Key.B; + settings.fitMode = kthoom.Key.B; updateScale(); break; case kthoom.Key.N: - fitMode = kthoom.Key.N; + settings.fitMode = kthoom.Key.N; updateScale(); break; default: @@ -520,35 +548,70 @@ function init(fileid) { request.open("GET", fileid); request.responseType = "json"; request.fileid=fileid.substring(0,fileid.length - 2); - request.addEventListener("load",ImageLoadCallback);/* function(event) { - var jso=request.response; - if (jso.page!=jso.length) - { - // var secRequest = new XMLHttpRequest(); - request.open("GET", fileid + "/../"+(jso.page+1)); - request.send(); - //secRequest.responseType = "json"; - //finished; - } - loadFromArrayBuffer(jso); - - // var byteArray = new Uint8Array(request.response); - // if you want to access the bytes: - });*/ + request.addEventListener("load",ImageLoadCallback); request.send(); - kthoom.initProgressMeter(); document.body.className += /AppleWebKit/.test(navigator.userAgent) ? " webkit" : ""; - updateScale(true); kthoom.loadSettings(); + updateScale(true); $(document).keydown(keyHandler); $(window).resize(function() { - var f = (screen.width - innerWidth < 4 && screen.height - innerHeight < 4); - getElem("titlebar").className = f ? "main" : ""; updateScale(); }); + // Open TOC menu + $("#slider").click(function(evt) { + $('#sidebar').toggleClass('open'); + $('#main').toggleClass('closed'); + $(this).toggleClass('icon-menu icon-right'); + }); + + // Open Settings modal + $("#setting").click(function(evt) { + $("#settings-modal").toggleClass('md-show'); + }); + + // On Settings input change + $("#settings input").on("change", function(evt){ + // Get either the checked boolean or the assigned value + var value = this.type === 'checkbox' ? this.checked : this.value; + + // If it's purely numeric, parse it to an integer + value = /^\d+$/.test(value) ? parseInt(value) : value; + + settings[this.name] = value; + updatePage(); + updateScale(); + }); + + // Close modal + $(".closer, .overlay").click(function(evt) { + $(".md-show").removeClass('md-show'); + }); + + // TOC thumbnail pagination + $('#thumbnails').on("click", "a", function(evt) { + currentImage = $(this).data('page') - 1; + updatePage(); + }); + + // Fullscreen mode + if (typeof screenfull !== "undefined") { + $('#fullscreen').click(function(evt) { + screenfull.toggle($("#container")[0]) + }); + + if (screenfull.raw) { + var $button = $('#fullscreen'); + document.addEventListener(screenfull.raw.fullscreenchange,function(){ + screenfull.isFullscreen + ? $button.addClass("icon-resize-small").removeClass("icon-resize-full") + : $button.addClass("icon-resize-full").removeClass("icon-resize-small") + }); + } + } + $("#mainImage").click(function(evt) { // Firefox does not support offsetX/Y so we have to manually calculate // where the user clicked in the image. @@ -564,7 +627,7 @@ function init(fileid) { // Determine if the user clicked/tapped the left side or the // right side of the page. var clickedPrev = false; - switch (kthoom.rotateTimes) { + switch (settings.rotateTimes) { case 0: clickedPrev = clickX < (comicWidth / 2); break; diff --git a/cps/templates/readcbr.html b/cps/templates/readcbr.html index cf2753d2..59296a7a 100644 --- a/cps/templates/readcbr.html +++ b/cps/templates/readcbr.html @@ -7,13 +7,14 @@ + + + - - - + + - -
    -
    + + +
    +
    +
    + Menu +
    +
    + +   –   + +
    + +
    +
    @@ -40,5 +68,85 @@
    + + +
    +