diff --git a/image-slider.css b/image-slider.css
index d0bd8a3..36e273e 100644
--- a/image-slider.css
+++ b/image-slider.css
@@ -26,6 +26,10 @@
margin-bottom: 2.5em;
}
+.h5p-image-slider-slides-holder.h5p-image-slider-no-navigation {
+ margin-bottom: 0;
+}
+
.h5p-image-slider-button {
position: absolute;
top: 0;
@@ -59,9 +63,13 @@
-moz-osx-font-smoothing: grayscale;
}
+.h5p-image-slider-button-text.h5p-image-slider-no-navigation {
+ display: none;
+}
+
.h5p-image-slider-left-button .h5p-image-slider-button-text {
left: calc(20% - 0.2em);
-
+
}
.h5p-image-slider-left-button .h5p-image-slider-button-text:before {
content: "\e901";
@@ -84,7 +92,7 @@
transition: opacity 0.3s;
}
-.h5p-image-slider-button:hover .h5p-image-slider-button-background {
+.h5p-image-slider-button:hover .h5p-image-slider-button-background {
opacity: 1;
}
diff --git a/image-slider.js b/image-slider.js
index 52aaa74..ac45d28 100644
--- a/image-slider.js
+++ b/image-slider.js
@@ -21,10 +21,15 @@ H5P.ImageSlider = (function ($) {
prevSlide: 'Previous Image',
gotoSlide: 'Go to image %slide'
},
- aspectRatioMode: 'auto',
- aspectRatio: {
- aspectWidth: 4,
- aspectHeight: 3
+ behaviour: {
+ aspectRatioMode: 'auto',
+ aspectRatio: {
+ aspectWidth: 4,
+ aspectHeight: 3
+ },
+ loop: false,
+ progressionTime: 0,
+ hideNavigation: false
}
}, options);
@@ -61,7 +66,8 @@ H5P.ImageSlider = (function ($) {
var fullScreenOn = self.$container.hasClass('h5p-fullscreen') || self.$container.hasClass('h5p-semi-fullscreen');
if (fullScreenOn) {
self.$slides.css('height', '');
- var newAspectRatio = window.innerWidth / (window.innerHeight - self.$progressBar.outerHeight());
+ const heightProgressBar = self.$progressBar ? self.$progressBar.outerHeight() : 0;
+ var newAspectRatio = window.innerWidth / (window.innerHeight - heightProgressBar);
for (var i = 0; i < self.imageSlides.length; i++) {
self.imageSlides[i].setAspectRatio(newAspectRatio);
}
@@ -87,7 +93,7 @@ H5P.ImageSlider = (function ($) {
this.aspectRatio = 4/3;
// Try to identify aspectRatio according to settings
- switch (this.options.aspectRatioMode) {
+ switch (this.options.behaviour.aspectRatioMode) {
case 'auto':
var imageRatios = [];
for (var i = 0; i < this.options.imageSlides.length; i++) {
@@ -102,8 +108,8 @@ H5P.ImageSlider = (function ($) {
break;
case 'custom':
- if (this.options.aspectRatio.aspectWidth && this.options.aspectRatio.aspectHeight) {
- this.aspectRatio = this.options.aspectRatio.aspectWidth / this.options.aspectRatio.aspectHeight;
+ if (this.options.behaviour.aspectRatio.aspectWidth && this.options.behaviour.aspectRatio.aspectHeight) {
+ this.aspectRatio = this.options.behaviour.aspectRatio.aspectWidth / this.options.behaviour.aspectRatio.aspectHeight;
}
break;
@@ -139,6 +145,10 @@ H5P.ImageSlider = (function ($) {
class: 'h5p-image-slider-slides-holder'
}).appendTo($container);
+ if (this.options.behaviour.hideNavigation) {
+ this.$slidesHolder.addClass('h5p-image-slider-no-navigation');
+ }
+
this.$screenReaderAnnouncement = $('
', {
class: 'h5p-image-slider-sr-only',
'aria-atomic': 'true',
@@ -154,6 +164,37 @@ H5P.ImageSlider = (function ($) {
this.$currentSlide = this.imageSlideHolders[0].addClass('h5p-image-slider-current');
this.attachControls();
+
+ // Auto progression
+ this.options.behaviour.progressionTime = this.options.behaviour.autoProgress ? this.options.behaviour.progressionTime : 0;
+ this.autoProgress(this.options.behaviour.progressionTime);
+ };
+
+ /**
+ * Auto progress after a certain time period.
+ *
+ * @param {number} seconds Time period in seconds, at least 1.
+ */
+ C.prototype.autoProgress = function(seconds) {
+ if (!(seconds > 0)) {
+ return;
+ }
+
+ const self = this;
+
+ // Reset timer if running already
+ if (this.progressionTimer) {
+ clearTimeout(this.progressionTimer);
+ }
+
+ this.progressionTimer = setTimeout(function() {
+ const success = self.gotoSlide(self.currentSlideId + 1);
+
+ // Stop progression if we can't continue.
+ if (success) {
+ self.autoProgress(seconds);
+ }
+ }, seconds * 1000);
};
/**
@@ -213,8 +254,8 @@ H5P.ImageSlider = (function ($) {
*/
C.prototype.attachControls = function() {
var self = this;
- this.$leftButton = this.createControlButton(this.options.a11y.prevSlide, 'left');
- this.$rightButton = this.createControlButton(this.options.a11y.nextSlide, 'right');
+ this.$leftButton = this.createControlButton(this.options.a11y.prevSlide, 'left', this.options.behaviour.hideNavigation);
+ this.$rightButton = this.createControlButton(this.options.a11y.nextSlide, 'right', this.options.behaviour.hideNavigation);
C.handleButtonClick(this.$leftButton, function () {
if (!self.dragging) {
self.gotoSlide(self.currentSlideId - 1);
@@ -230,7 +271,9 @@ H5P.ImageSlider = (function ($) {
this.$slidesHolder.append(this.$leftButton);
this.$slidesHolder.append(this.$rightButton);
this.updateNavButtons();
- this.attachProgressBar();
+ if (!this.options.behaviour.hideNavigation) {
+ this.attachProgressBar();
+ }
this.initDragging();
this.initKeyEvents();
};
@@ -278,9 +321,10 @@ H5P.ImageSlider = (function ($) {
*
* @param {string} text - label for the button
* @param {string} dir - next or prev
+ * @param {boolean} hidden - hide text
* @return {jQuery} control button
*/
- C.prototype.createControlButton = function(text, dir) {
+ C.prototype.createControlButton = function(text, dir, hidden) {
var $controlButton = $('
', {
class: 'h5p-image-slider-button ' + 'h5p-image-slider-' + dir + '-button',
});
@@ -296,6 +340,11 @@ H5P.ImageSlider = (function ($) {
'role': 'button',
'tabindex': 0
});
+
+ if (hidden) {
+ $controlText.addClass('h5p-image-slider-no-navigation');
+ }
+
$controlButton.append($controlText);
return $controlButton;
@@ -308,9 +357,18 @@ H5P.ImageSlider = (function ($) {
* @return {Boolean} false if failed(typically the slide didn't exist), true if not
*/
C.prototype.gotoSlide = function(slideId) {
- if (slideId < 0 || slideId >= this.imageSlideHolders.length) {
+ if ((slideId < 0 || slideId >= this.imageSlideHolders.length) && !this.options.behaviour.loop) {
return false;
}
+
+ // Loop to first/last slide
+ if (slideId < 0) {
+ slideId = this.imageSlideHolders.length - 1;
+ }
+ else if (slideId >= this.imageSlideHolders.length) {
+ slideId = 0;
+ }
+
$('.h5p-image-slider-removing', this.$container).removeClass('.h5p-image-slider-removing');
var nextSlideDirection = (this.currentSlideId < slideId) ? 'future' : 'past';
var prevSlideDirection = nextSlideDirection === 'past' ? 'future' : 'past';
@@ -339,6 +397,10 @@ H5P.ImageSlider = (function ($) {
this.announceCurrentSlide();
this.updateNavButtons();
this.updateProgressBar();
+
+ // Reset auto progress timer
+ this.autoProgress(this.options.behaviour.progressionTime);
+
return true;
};
@@ -359,13 +421,13 @@ H5P.ImageSlider = (function ($) {
* Updates all navigation buttons, typically toggling and positioning
*/
C.prototype.updateNavButtons = function() {
- if (this.currentSlideId >= this.imageSlides.length - 1) {
+ if (this.currentSlideId >= this.imageSlides.length - 1 && !this.options.behaviour.loop) {
this.$rightButton.hide();
}
else {
this.$rightButton.show();
}
- if (this.currentSlideId <= 0) {
+ if (this.currentSlideId <= 0 && !this.options.behaviour.loop) {
this.$leftButton.hide();
}
else {
diff --git a/language/.en.json b/language/.en.json
index 6b909ba..64b55be 100644
--- a/language/.en.json
+++ b/language/.en.json
@@ -12,30 +12,63 @@
}
},
{
- "label": "Aspect ratio",
- "description": "Automatic means fixed aspect ratio automatically determined based on the images",
- "options": [
+ "label": "Behavioural settings",
+ "description": "These options will let you control how the task behaves.",
+ "fields": [
{
- "label": "Automatic"
+ "label": "Aspect ratio",
+ "description": "Automatic means fixed aspect ratio automatically determined based on the images",
+ "default": "auto",
+ "options": [
+ {
+ "label": "Automatic"
+ },
+ {
+ "label": "Custom"
+ },
+ {
+ "label": "Not fixed"
+ }
+ ]
},
{
- "label": "Custom"
+ "label": "Aspect Ratio Settings",
+ "showWhen": {
+ "rules": [
+ {}
+ ]
+ },
+ "fields": [
+ {
+ "label": "Aspect ratio width",
+ "description": "If you use 4 here, and 3 for the height the aspect ratio will be 4:3"
+ },
+ {
+ "label": "Aspect ratio height",
+ "description": "If you use 3 here, and 4 for the width the aspect ratio will be 4:3"
+ }
+ ]
},
{
- "label": "Not fixed"
- }
- ]
- },
- {
- "label": "Aspect Ratio Settings",
- "fields": [
+ "label": "Loop",
+ "description": "If set, slider will progress from last image to first image and vice versa"
+ },
{
- "label": "Aspect ratio width",
- "description": "If you use 4 here, and 3 for the height the aspect ratio will be 4:3"
+ "label": "Automatic progression",
+ "description": "If set, slider will progress to next slide automatically after a configurable time period"
+ },
+ {
+ "label": "Progression time",
+ "description": "If a time period is set (in seconds), the slider will progress to the next slide automatically after that time period.",
+ "showWhen": {
+ "rules": [
+ {}
+ ]
+ }
},
{
- "label": "Aspect ratio height",
- "description": "If you use 3 here, and 4 for the width the aspect ratio will be 4:3"
+ "label": "Hide navigation",
+ "description": "If set, navigation will work, but items used for navigation are hidden."
}
]
},
@@ -60,4 +93,4 @@
]
}
]
-}
\ No newline at end of file
+}
diff --git a/language/nb.json b/language/nb.json
index 509d861..c403397 100644
--- a/language/nb.json
+++ b/language/nb.json
@@ -12,30 +12,63 @@
}
},
{
- "label": "Aspect ratio",
- "description": "Automatic means fixed aspect ratio automatically determined based on the images",
- "options": [
+ "label": "Behavioural settings",
+ "description": "These options will let you control how the task behaves.",
+ "fields": [
{
- "label": "Automatic"
+ "label": "Aspect ratio",
+ "description": "Automatic means fixed aspect ratio automatically determined based on the images",
+ "default": "auto",
+ "options": [
+ {
+ "label": "Automatic"
+ },
+ {
+ "label": "Custom"
+ },
+ {
+ "label": "Not fixed"
+ }
+ ]
},
{
- "label": "Custom"
+ "label": "Aspect Ratio Settings",
+ "showWhen": {
+ "rules": [
+ {}
+ ]
+ },
+ "fields": [
+ {
+ "label": "Aspect ratio width",
+ "description": "If you use 4 here, and 3 for the height the aspect ratio will be 4:3"
+ },
+ {
+ "label": "Aspect ratio height",
+ "description": "If you use 3 here, and 4 for the width the aspect ratio will be 4:3"
+ }
+ ]
},
{
- "label": "Not fixed"
- }
- ]
- },
- {
- "label": "Aspect Ratio Settings",
- "fields": [
+ "label": "Loop",
+ "description": "If set, slider will progress from last image to first image and vice versa"
+ },
{
- "label": "Aspect ratio width",
- "description": "If you use 4 here, and 3 for the height the aspect ratio will be 4:3"
+ "label": "Automatic progression",
+ "description": "If set, slider will progress to next slide automatically after a configurable time period"
+ },
+ {
+ "label": "Progression time",
+ "description": "If a time period is set (in seconds), the slider will progress to the next slide automatically after that time period.",
+ "showWhen": {
+ "rules": [
+ {}
+ ]
+ }
},
{
- "label": "Aspect ratio height",
- "description": "If you use 3 here, and 4 for the width the aspect ratio will be 4:3"
+ "label": "Hide navigation",
+ "description": "If set, navigation will work, but items used for navigation are hidden."
}
]
},
diff --git a/semantics.json b/semantics.json
index d074699..92ed90b 100644
--- a/semantics.json
+++ b/semantics.json
@@ -20,54 +20,101 @@
}
},
{
- "label": "Aspect ratio",
- "name": "aspectRatioMode",
- "type": "select",
- "description": "Automatic means fixed aspect ratio automatically determined based on the images",
- "default": "auto",
- "options": [
- {
- "value": "auto",
- "label": "Automatic"
+ "name": "behaviour",
+ "type": "group",
+ "label": "Behavioural settings",
+ "importance": "low",
+ "description": "These options will let you control how the task behaves.",
+ "fields": [
+ {
+ "label": "Aspect ratio",
+ "name": "aspectRatioMode",
+ "type": "select",
+ "description": "Automatic means fixed aspect ratio automatically determined based on the images",
+ "default": "auto",
+ "options": [
+ {
+ "value": "auto",
+ "label": "Automatic"
+ },
+ {
+ "value": "custom",
+ "label": "Custom"
+ },
+ {
+ "value": "notFixed",
+ "label": "Not fixed"
+ }
+ ]
+ },
+ {
+ "label": "Aspect Ratio Settings",
+ "name": "aspectRatio",
+ "type": "group",
+ "widget": "showWhen",
+ "expanded": true,
+ "showWhen": {
+ "rules": [
+ {
+ "field": "aspectRatioMode",
+ "equals": "custom"
+ }
+ ]
+ },
+ "fields": [
+ {
+ "label": "Aspect ratio width",
+ "name": "aspectWidth",
+ "type": "number",
+ "default": 4,
+ "description": "If you use 4 here, and 3 for the height the aspect ratio will be 4:3"
+ },
+ {
+ "label": "Aspect ratio height",
+ "name": "aspectHeight",
+ "type": "number",
+ "default": 3,
+ "description": "If you use 3 here, and 4 for the width the aspect ratio will be 4:3"
+ }
+ ]
+ },
+ {
+ "name": "loop",
+ "type": "boolean",
+ "label": "Loop",
+ "description": "If set, slider will progress from last image to first image and vice versa",
+ "default": false
},
{
- "value": "custom",
- "label": "Custom"
+ "name": "autoProgress",
+ "type": "boolean",
+ "label": "Automatic progression",
+ "description": "If set, slider will progress to next slide automatically after a configurable time period",
+ "default": false
},
{
- "value": "notFixed",
- "label": "Not fixed"
- }
- ]
- },
- {
- "label": "Aspect Ratio Settings",
- "name": "aspectRatio",
- "type": "group",
- "widget": "showWhen",
- "expanded": true,
- "showWhen": {
- "rules": [
- {
- "field": "aspectRatioMode",
- "equals": "custom"
- }
- ]
- },
- "fields": [
- {
- "label": "Aspect ratio width",
- "name": "aspectWidth",
+ "name": "progressionTime",
"type": "number",
- "default": 4,
- "description": "If you use 4 here, and 3 for the height the aspect ratio will be 4:3"
+ "label": "Progression time",
+ "description": "If a time period is set (in seconds), the slider will progress to the next slide automatically after that time period.",
+ "default": 5,
+ "min": 1,
+ "widget": "showWhen",
+ "showWhen": {
+ "rules": [
+ {
+ "field": "autoProgress",
+ "equals": true
+ }
+ ]
+ }
},
{
- "label": "Aspect ratio height",
- "name": "aspectHeight",
- "type": "number",
- "default": 3,
- "description": "If you use 3 here, and 4 for the width the aspect ratio will be 4:3"
+ "name": "hideNavigation",
+ "type": "boolean",
+ "label": "Hide navigation",
+ "description": "If set, navigation will work, but items used for navigation are hidden.",
+ "default": false
}
]
},
@@ -104,4 +151,4 @@
}
]
}
-]
\ No newline at end of file
+]
diff --git a/upgrades.js b/upgrades.js
new file mode 100644
index 0000000..4a61c57
--- /dev/null
+++ b/upgrades.js
@@ -0,0 +1,33 @@
+var H5PUpgrades = H5PUpgrades || {};
+
+H5PUpgrades['H5P.ImageSlider'] = (function () {
+ return {
+ 1: {
+ /**
+ * Asynchronous content upgrade hook.
+ *
+ * Move aspect settings to behavioural settings group
+ *
+ * @param {Object} parameters
+ * @param {function} finished
+ */
+ 1: function (parameters, finished, extras) {
+ // Copy aspect settings to behaviour group and set new defaults
+ parameters.behaviour = {
+ aspectRatioMode: parameters.aspectRatioMode,
+ aspectRatio: parameters.aspectRatio,
+ loop: false,
+ autoProgress: false,
+ progressionTime: 5,
+ hideNavigation: false
+ }
+
+ // Delete old aspect settings
+ delete parameters.aspectRatioMode;
+ delete parameters.aspectRatio;
+
+ finished(null, parameters, extras);
+ }
+ }
+ };
+})();