diff --git a/README.md b/README.md index 7110efd..810ec9e 100644 --- a/README.md +++ b/README.md @@ -272,6 +272,8 @@ To navigate the slideshow: * **forward**: K, L, UP, RIGHT, PgDn, and Space * **reverse**: H, J, LEFT, DOWN, PgUp, and Backspace +* **first slide**: Home +* **last slide**: End The toggle fullscreen mode, press the **ENTER** key. diff --git a/docs/options.md b/docs/options.md index 08fdcef..c072442 100644 --- a/docs/options.md +++ b/docs/options.md @@ -82,6 +82,13 @@ Displays a small progress bar at the top of your document. **Default**: true +### loop + +Allows looping from the last slide to the first, or backwards from the first to +the last. + +**Default**: true + ### encoding Content encoding to use on the rendered document. diff --git a/lib/index.js b/lib/index.js index 723b7bb..ea8bf7b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -211,6 +211,7 @@ Cleaver.prototype.loadStaticAssets = function () { Cleaver.prototype.renderSlideshow = function () { var putControls = this.options.controls || (this.options.controls === undefined); var putProgress = this.options.progress || (this.options.progress === undefined); + var allowLooping = this.options.loop || (this.options.loop === undefined); var style, script, output; // Render the slides in a template (maybe as specified by the user) @@ -253,6 +254,7 @@ Cleaver.prototype.renderSlideshow = function () { style: style, author: this.options.author, script: script, + allowLooping: allowLooping, options: this.options }; diff --git a/resources/script.js b/resources/script.js index 49384dc..706fdbf 100644 --- a/resources/script.js +++ b/resources/script.js @@ -5,6 +5,23 @@ function currentPosition() { return parseInt(document.querySelector('.slide:not(.hidden)').id.slice(6)); } +/** + * If passed to navigate, will move to the first slide, independent of the + * current location, rather than a relative amount. + */ +var FIRST_SLIDE = -9999999; + +/** + * If passed to navigate, will move to the last slide, independent of the + * current location, rather than a relative amount. + */ +var LAST_SLIDE = 9999999; + +/** + * Whether to allow looping from the last back to the first or backwards from + * the first to the last. + */ +var ALLOW_LOOPING = true; /** * Navigates forward n pages @@ -13,12 +30,27 @@ function currentPosition() { function navigate(n) { var position = currentPosition(); var numSlides = document.getElementsByClassName('slide').length; + var nextPosition; + if (n === FIRST_SLIDE) { + nextPosition = 1; + } else if (n === LAST_SLIDE) { + nextPosition = numSlides; + } else { + if (! ALLOW_LOOPING) { + if (n < 0 && position <= 1) { + return; + } + if (n > 0 && position >= numSlides) { + return; + } + } - /* Positions are 1-indexed, so we need to add and subtract 1 */ - var nextPosition = (position - 1 + n) % numSlides + 1; + /* Positions are 1-indexed, so we need to add and subtract 1 */ + nextPosition = (position - 1 + n) % numSlides + 1; - /* Normalize nextPosition in-case of a negative modulo result */ - nextPosition = (nextPosition - 1 + numSlides) % numSlides + 1; + /* Normalize nextPosition in-case of a negative modulo result */ + nextPosition = (nextPosition - 1 + numSlides) % numSlides + 1; + } document.getElementById('slide-' + position).classList.add('hidden'); document.getElementById('slide-' + nextPosition).classList.remove('hidden'); @@ -130,6 +162,10 @@ document.addEventListener('DOMContentLoaded', function () { navigate(-1); } else if (kc === 38 || kc === 39 || kc === 32 || kc === 75 || kc === 76 || kc === 34) { navigate(1); + } else if (kc === 36) { + navigate(FIRST_SLIDE); + } else if (kc === 35) { + navigate(LAST_SLIDE); } else if (kc === 13) { toggleFullScreen(); } diff --git a/templates/layout.mustache b/templates/layout.mustache index 3b841fc..c61e702 100644 --- a/templates/layout.mustache +++ b/templates/layout.mustache @@ -16,6 +16,7 @@