diff --git a/eslint/eslintrc.json b/eslint/eslintrc.json index 77aaba5..5fd6db2 100644 --- a/eslint/eslintrc.json +++ b/eslint/eslintrc.json @@ -31,9 +31,6 @@ "function-paren-newline": ["warn", "consistent"], "no-magic-numbers": ["error", {"ignore": [0,1,2,100]}], "quote-props": ["warn", "as-needed"], - "no-unused-vars": ["error", {"argsIgnorePattern": "^_"}], - "max-len" : ["warn", {"code": 88}], - "capitalized-comments": "off", - "operator-linebreak": ["warn", "before"] + "no-unused-vars": ["error", {"argsIgnorePattern": "^_"}] } } diff --git a/melpomene.js b/melpomene.js index 8572c8c..8689592 100644 --- a/melpomene.js +++ b/melpomene.js @@ -45,7 +45,7 @@ const VERSION_DISPLAY = document.getElementById("melpomene-version"); var PAGES_ZOOMS; // The variable ZOOMS can either be defined by another JS file or contructed at init -if (typeof PAGES_ZOOMS === "undefined") +if (typeof PAGES_ZOOMS === 'undefined') { PAGES_ZOOMS = null; } @@ -64,6 +64,109 @@ var MOUSEWHELL_WAIT = false; // UTILITIES // ============= +// Zooms utilites +// -------------- + +function globalZoomScale() +{ + if (READER_PAGES.dataset.globalZoomScale !== undefined) + { + return parseFloat(READER_PAGES.dataset.globalZoomScale); + } + + return 1.0; +} + +function globalZoomOffsetX() +{ + if (READER_PAGES.dataset.globalZoomOffset !== undefined) + { + return parseFloat(READER_PAGES.dataset.globalZoomOffset.split(',')[0]); + } + + return 0.0; +} + +function globalZoomOffsetY() +{ + if (READER_PAGES.dataset.globalZoomOffset !== undefined) + { + return parseFloat(READER_PAGES.dataset.globalZoomOffset.split(',')[1]); + } + + return 0.0; +} + +function loadZoomsFromImgTagsIfRequired() +{ + // Zooms may be defined by another JS file + if (PAGES_ZOOMS === null) + { + PAGES_ZOOMS = []; + + // parse the data-zooms of each img and and the page number info + for (let idx = 0; idx < READER_PAGES.children.length; idx += 1) + { + const zoomsRawData = READER_PAGES.children[idx].dataset.zooms; + + // ';' separates zooms data, ',' separates values + // We add the page number (adding 1 because of indexing) + const zooms = zoomsRawData.split(";").map( + zoom => [idx + 1].concat( + zoom.split(',').map( + value => parseFloat(value) + ) + ) + ); + + PAGES_ZOOMS = PAGES_ZOOMS.concat(zooms); + } + } +} + +function getFirstZoomOfPage(pageNumber) +{ + for (let zoomIdx = 0; zoomIdx < PAGES_ZOOMS.length; zoomIdx += 1) + { + if (PAGES_ZOOMS[zoomIdx][0] === pageNumber) + { + return zoomIdx; + } + } +} + +function getZoomCountForPage(pageNumber) +{ + return PAGES_ZOOMS.filter(zoom => zoom[0] === pageNumber).length; +} + +function getCurrentZoomIndexForPage() +{ + const previousZoomsCount = PAGES_ZOOMS.filter(zoom => zoom[0] < CURRENT_PAGE).length; + return CURRENT_ZOOM - previousZoomsCount + 1; +} + +function getReadingProgressPercent() +{ + const progressPerPage = 1 / getPagesCount(); + + if (IS_PAGE_MODE) + { + return 100 * progressPerPage * CURRENT_PAGE; + } + + const progressPerZoom = progressPerPage / getZoomCountForPage(CURRENT_PAGE); + + const readingProgress = (CURRENT_PAGE - 1) * progressPerPage + getCurrentZoomIndexForPage() * progressPerZoom; + + return 100 * readingProgress; +} + +function updateProgressBar() +{ + PROGRESS_BAR.style.width = getReadingProgressPercent() + "%"; +} + // Dimensions utilites // ------------------- @@ -91,11 +194,11 @@ function pageMaxHeight() { let maxHeight = 0; - for (let pageIdx = 0; pageIdx < READER_PAGES.children.length; pageIdx += 1) + for (let i = 0; i < READER_PAGES.children.length; i += 1) { - if (READER_PAGES.children[pageIdx].naturalHeight > maxHeight) + if(READER_PAGES.children[i].naturalHeight > maxHeight) { - maxHeight = READER_PAGES.children[pageIdx].naturalHeight; + maxHeight = READER_PAGES.children[i].naturalHeight; } } @@ -104,7 +207,7 @@ function pageMaxHeight() function pageVerticalOffset(pageNumber) { - return (pageMaxHeight() - pageOriginalHeight(pageNumber)) / 2; + return ( pageMaxHeight() - pageOriginalHeight(pageNumber) ) / 2; } function previousPagesWidth(pageNumber) @@ -121,128 +224,64 @@ function previousPagesWidth(pageNumber) return totalWidth; } -// Zooms utilites -// -------------- - -function globalZoomScale() -{ - if (READER_PAGES.dataset.globalZoomScale !== undefined) - { - return parseFloat(READER_PAGES.dataset.globalZoomScale); - } - - return 1.0; -} - -function globalZoomOffsetX() -{ - if (READER_PAGES.dataset.globalZoomOffset !== undefined) - { - return parseFloat(READER_PAGES.dataset.globalZoomOffset.split(",")[0]); - } - - return 0.0; -} - -function globalZoomOffsetY() -{ - if (READER_PAGES.dataset.globalZoomOffset !== undefined) - { - return parseFloat(READER_PAGES.dataset.globalZoomOffset.split(",")[1]); - } - - return 0.0; -} - -function loadZoomsFromImgTagsIfRequired() -{ - // Zooms may be defined by another JS file - if (PAGES_ZOOMS === null) - { - PAGES_ZOOMS = []; - - // parse the data-zooms of each img and and the page number info - for (let idx = 0; idx < READER_PAGES.children.length; idx += 1) - { - const zoomsRawData = READER_PAGES.children[idx].dataset.zooms; - - // ";" separates zooms data, "," separates values - // We add the page number (adding 1 because of indexing) - const zooms = zoomsRawData.split(";").map( - (zoom) => [idx + 1].concat( - zoom.split(",").map( - (value) => parseFloat(value) - ) - ) - ); - - PAGES_ZOOMS = PAGES_ZOOMS.concat(zooms); - } - } -} - -function getFirstZoomOfPage(pageNumber) -{ - for (let zoomIdx = 0; zoomIdx < PAGES_ZOOMS.length; zoomIdx += 1) - { - if (PAGES_ZOOMS[zoomIdx][0] === pageNumber) - { - return zoomIdx; - } - } - - return undefined; -} - -function getZoomCountForPage(pageNumber) -{ - return PAGES_ZOOMS.filter((zoom) => zoom[0] === pageNumber).length; -} - -function getCurrentZoomIndexForPage() -{ - const previousZoomsCount = PAGES_ZOOMS.filter((zoom) => zoom[0] < CURRENT_PAGE).length; - return CURRENT_ZOOM - previousZoomsCount + 1; -} - -function getReadingProgressPercent() -{ - const progressPerPage = 1 / getPagesCount(); - - if (IS_PAGE_MODE) - { - return 100 * progressPerPage * CURRENT_PAGE; - } - - const progressPerZoom = progressPerPage / getZoomCountForPage(CURRENT_PAGE); - - - let readingProgress = (CURRENT_PAGE - 1) * progressPerPage; - readingProgress += getCurrentZoomIndexForPage() * progressPerZoom; - - return 100 * readingProgress; -} - -function updateProgressBar() -{ - PROGRESS_BAR.style.width = `${getReadingProgressPercent()}%`; -} - // ========= // ACTIONS // ========= -function updateFocusByWidth(width) +function initReader() { - FOCUS_OVERLAY_WIDTH.style.width = `${width / READER_CONTENT_FRAME.clientWidth * 100}%`; - FOCUS_OVERLAY_HEIGHT.style.height = "100%"; + VERSION_DISPLAY.innerText = VERSION_DISPLAY.innerText.replace("Unknown version", MELPOMENE_VERSION); + + loadZoomsFromImgTagsIfRequired(); + moveReaderDisplayToZoom(0); + + // Smoothly show pictures when they intersect with the viewport + const visibilityObserver = new IntersectionObserver( + (entries, _observer) => + { + entries.forEach((entry) => + { + if (entry.isIntersecting) + { + entry.target.style.opacity = 1; + entry.target.style.visibility = "visible"; + } + + else + { + entry.target.style.opacity = 0; + entry.target.style.visibility = "hidden"; + } + }); + }, + { root: READER_CONTENT_FRAME, rootMargin: "-10px" } + ); + + for (let i = 0; i < READER_PAGES.children.length; i += 1) + { + const img = READER_PAGES.children[i]; + visibilityObserver.observe(img); + + PROGRESS_BAR_PAGES.appendChild(document.createElement("div")); + } + + READER_PAGES.style.display = "flex"; + + setTimeout( + () => { READER_PAGES.hidden = false }, + "300" + ); + + setTimeout( + () => + { + HELP_CONTROLS.style.opacity = null; + HELP_CONTROLS.style.transform = null; + }, + DELAY_BEFORE_HIDDING_CONTROLS + ); } -function updateFocusByHeight(height) -{ - FOCUS_OVERLAY_WIDTH.style.width = "100%"; - FOCUS_OVERLAY_HEIGHT.style.height = `${height / READER_CONTENT_FRAME.clientHeight * 100}%`; -} function moveReaderDisplayToArea(pageNumber, oWidth, oHeight, oPosx, oPosy) { @@ -268,8 +307,8 @@ function moveReaderDisplayToArea(pageNumber, oWidth, oHeight, oPosx, oPosy) width = width + posx; posx = 0; } - - if (posx + width > pageOriginalWidth(pageNumber)) + + if ((posx + width) > pageOriginalWidth(pageNumber)) { width = pageOriginalWidth(pageNumber) - posx; } @@ -280,18 +319,18 @@ function moveReaderDisplayToArea(pageNumber, oWidth, oHeight, oPosx, oPosy) height = height + posy; posy = 0; } - - if (posy + height > pageOriginalHeight(pageNumber)) + + if ((posy + height) > pageOriginalHeight(pageNumber)) { height = pageOriginalHeight(pageNumber) - posy; } // Align the top-left corner of the frame with the page - READER_PAGES.style.transform = `translate(-${previousPagesWidth(pageNumber)}px, -${pageVerticalOffset(pageNumber)}px)`; + READER_PAGES.style.transform = "translate(-" + previousPagesWidth(pageNumber) + "px, -" + pageVerticalOffset(pageNumber) + "px )"; // Then move so the top-left point of the zoom match the frame top-left - READER_PAGES.style.transform = `translate(${-posx}px, ${-posy}px) ${READER_PAGES.style.transform}`; + READER_PAGES.style.transform = "translate(" + (- posx) + "px, " + (-posy) + "px )" + READER_PAGES.style.transform; // Then, scale so the zoom would fit the frame, and center the zoom if (width === 0) @@ -311,27 +350,27 @@ function moveReaderDisplayToArea(pageNumber, oWidth, oHeight, oPosx, oPosy) // Frame wider than zoom => scale so heights are the same, offset on x const zoomToFrameScaleFactor = READER_CONTENT_FRAME.clientHeight / height; - READER_PAGES.style.transform = `scale(${zoomToFrameScaleFactor}) ${READER_PAGES.style.transform}`; + READER_PAGES.style.transform = "scale(" + zoomToFrameScaleFactor + ")" + READER_PAGES.style.transform; const scaledWidth = width * zoomToFrameScaleFactor; const offset = (READER_CONTENT_FRAME.clientWidth - scaledWidth) / 2; - READER_PAGES.style.transform = `translateX(${offset}px) ${READER_PAGES.style.transform}`; + READER_PAGES.style.transform = "translateX(" + offset + "px)" + READER_PAGES.style.transform; updateFocusByWidth(scaledWidth); } - + else { // Frame narower than zoom => scale so left/right match, offset on y const zoomToFrameScaleFactor = READER_CONTENT_FRAME.clientWidth / width; - READER_PAGES.style.transform = `scale(${zoomToFrameScaleFactor}) ${READER_PAGES.style.transform}`; + READER_PAGES.style.transform = "scale(" + zoomToFrameScaleFactor + ")" + READER_PAGES.style.transform; const scaledHeight = height * zoomToFrameScaleFactor; const offset = (READER_CONTENT_FRAME.clientHeight - scaledHeight) / 2; - READER_PAGES.style.transform = `translateY(${offset}px) ${READER_PAGES.style.transform}"`; + READER_PAGES.style.transform = "translateY(" + offset + "px)" + READER_PAGES.style.transform; updateFocusByHeight(scaledHeight); } @@ -346,13 +385,7 @@ function moveReaderDisplayToArea(pageNumber, oWidth, oHeight, oPosx, oPosy) function refreshReaderDisplay() { - moveReaderDisplayToArea( - CURRENT_PAGE, - CURRENT_WIDTH, - CURRENT_HEIGHT, - CURRENT_X, - CURRENT_Y - ); + moveReaderDisplayToArea(CURRENT_PAGE, CURRENT_WIDTH, CURRENT_HEIGHT, CURRENT_X, CURRENT_Y); } function moveReaderDisplayToPage(pageNumber) @@ -362,34 +395,40 @@ function moveReaderDisplayToPage(pageNumber) function moveReaderDisplayToZoom(index) { - moveReaderDisplayToArea( - PAGES_ZOOMS[index][0], - PAGES_ZOOMS[index][1], - PAGES_ZOOMS[index][2], - PAGES_ZOOMS[index][3], - PAGES_ZOOMS[index][4] - ); + moveReaderDisplayToArea(PAGES_ZOOMS[index][0], PAGES_ZOOMS[index][1], PAGES_ZOOMS[index][2], PAGES_ZOOMS[index][3], PAGES_ZOOMS[index][4]); CURRENT_ZOOM = index; } +function updateFocusByWidth(width) +{ + FOCUS_OVERLAY_WIDTH.style.width = (width / READER_CONTENT_FRAME.clientWidth * 100) + "%"; + FOCUS_OVERLAY_HEIGHT.style.height = "100%"; +} + +function updateFocusByHeight(height) +{ + FOCUS_OVERLAY_WIDTH.style.width = "100%"; + FOCUS_OVERLAY_HEIGHT.style.height = (height / READER_CONTENT_FRAME.clientHeight * 100) + "%"; +} + function toggleViewMode() { if (IS_PAGE_MODE) { - if (CURRENT_ZOOM === null) - { - moveReaderDisplayToZoom(getFirstZoomOfPage(CURRENT_PAGE)); - } - - else + if (CURRENT_ZOOM !== null) { moveReaderDisplayToZoom(CURRENT_ZOOM); } - + + else + { + moveReaderDisplayToZoom(getFirstZoomOfPage(CURRENT_PAGE)); + } + IS_PAGE_MODE = false; } - + else { moveReaderDisplayToPage(CURRENT_PAGE); @@ -414,11 +453,8 @@ function moveReader(toNext) moveReaderDisplayToPage(CURRENT_PAGE - 1); CURRENT_ZOOM = null; } - - updateProgressBar(); } - - // Zoom mode + else { if (toNext && CURRENT_ZOOM < PAGES_ZOOMS.length - 1) @@ -430,66 +466,9 @@ function moveReader(toNext) { moveReaderDisplayToZoom(CURRENT_ZOOM - 1); } - - updateProgressBar(); - } -} - -function initReader() -{ - VERSION_DISPLAY.innerText = VERSION_DISPLAY.innerText.replace("Unknown version", MELPOMENE_VERSION); - - loadZoomsFromImgTagsIfRequired(); - moveReaderDisplayToZoom(0); - - // Smoothly show pictures when they intersect with the viewport - const visibilityObserver = new IntersectionObserver( - (entries, _observer) => - { - entries.forEach((entry) => - { - if (entry.isIntersecting) - { - entry.target.style.opacity = 1; - entry.target.style.visibility = "visible"; - } - - else - { - entry.target.style.opacity = 0; - entry.target.style.visibility = "hidden"; - } - }); - }, - { - root: READER_CONTENT_FRAME, - rootMargin: "-10px" - } - ); - - for (let pageIndex = 0; pageIndex < READER_PAGES.children.length; pageIndex += 1) - { - const img = READER_PAGES.children[pageIndex]; - visibilityObserver.observe(img); - - PROGRESS_BAR_PAGES.appendChild(document.createElement("div")); } - READER_PAGES.style.display = "flex"; - - setTimeout( - () => { READER_PAGES.hidden = false; }, - "300" - ); - - setTimeout( - () => - { - HELP_CONTROLS.style.opacity = null; - HELP_CONTROLS.style.transform = null; - }, - DELAY_BEFORE_HIDDING_CONTROLS - ); + updateProgressBar(); } @@ -515,7 +494,7 @@ function handleKeyPress(key) { READER_FRAME.requestFullscreen(); } - + else { document.exitFullscreen(); @@ -528,12 +507,12 @@ function handleKeyPress(key) { PROGRESS_BAR_CONTAINER.hidden = false; } - + else { PROGRESS_BAR_CONTAINER.hidden = true; } - + refreshReaderDisplay(); } @@ -550,7 +529,7 @@ function handleMouseWhell(event) // Do disable page scrolling when we do prev/next, though - if (!READER_FRAME.contains(event.target)) + if (! READER_FRAME.contains(event.target)) { return; } @@ -562,12 +541,15 @@ function handleMouseWhell(event) { return; } - - MOUSEWHELL_WAIT = true; - setTimeout( - () => { MOUSEWHELL_WAIT = false; }, - MOUSEWHELL_MIN_DELAY - ); + + else + { + MOUSEWHELL_WAIT = true; + setTimeout( + () => { MOUSEWHELL_WAIT = false; }, + MOUSEWHELL_MIN_DELAY + ); + } if (event.deltaY > 0) {