From c0ff02c334e457995e0b751e4980b43920ec839a Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Mon, 14 May 2018 13:52:30 +0200 Subject: [PATCH] Sozi library (js and css) --- README.md | 49 +++++++++++ src/sozi-ui.css | 75 ++++++++++++++++ src/sozi-ui.js | 225 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 349 insertions(+) create mode 100644 src/sozi-ui.css diff --git a/README.md b/README.md index e69de29..9ac5b1c 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,49 @@ +Sozi UI +======= + +Add controlers on embeded Sozi presentations. + +Usage +----- + +``` +var soziUi = new SoziUi(element, options); +soziUi.addControls(); +soziUi.addEvents(); +``` + +Example +------- + +``` + + +
+ +
+ + + + + +``` diff --git a/src/sozi-ui.css b/src/sozi-ui.css new file mode 100644 index 0000000..8af6cd1 --- /dev/null +++ b/src/sozi-ui.css @@ -0,0 +1,75 @@ +.sozi-container { + background: #fff; +} + +.sozi-ui-controls { + width: 100%; + background: #017499; + color: #fff; + font-family: Tahoma, Calibri, Verdana; + font-size: 13px; + line-height: 35px; +} + +.sozi-ui-controls:after { + content: '.'; + display: block; + height: 0; + width: 0; + clear: both; +} + +.sozi-ui-element { + display: inline-block; + padding: 3px 15px; + cursor: pointer; + border-right: 1px solid #008ab4; +} + +.sozi-ui-frame-current, .sozi-ui-frame-number, .sozi-ui-frame-current-title { + font-weight: bold; +} + +.sozi-ui-frame-current-title, .sozi-ui-summary { + border: 0; +} + +.sozi-ui-summary { + float: right; + border: 0; + height: 35px; + line-height: 35px; + background: none; + color: #fff; + margin-top: 4px; +} + +.sozi-ui-fullscreen { + border-left: 1px solid #008ab4; +} + +.sozi-ui-fullscreen-btn { + display: none; +} + +.sozi-ui-fullscreen-btn.active { + display: inline; +} + +.sozi-container.fullscreen iframe { + width: 100%; + height: calc(100% - 30px); +} + +.sozi-container.fullscreen .sozi-ui-controls { + width: 100%; +} + +.sozi-ui-controls.position-bottom { + position: absolute; + bottom: 0; +} + +.sozi-ui-controls.position-top { + top: 0; +} diff --git a/src/sozi-ui.js b/src/sozi-ui.js index e69de29..77cc4fd 100644 --- a/src/sozi-ui.js +++ b/src/sozi-ui.js @@ -0,0 +1,225 @@ +if (window.NodeList && !NodeList.prototype.forEach) { + NodeList.prototype.forEach = function(callback, thisArg) { + thisArg = thisArg || window; + for (var i = 0; i < this.length; i++) { + callback.call(thisArg, this[i], i, this); + } + }; +} + +if (!Array.prototype.forEach) { + Array.prototype.forEach = function(callback, thisArg) { + thisArg = thisArg || window; + for (var i = 0; i < this.length; i++) { + callback.call(thisArg, this[i], i, this); + } + }; +} + +(function(arr) { + arr.forEach(function(item) { + if (item.hasOwnProperty('prepend')) { + return; + } + Object.defineProperty(item, 'prepend', { + configurable: true, + enumerable: true, + writable: true, + value: function prepend() { + var argArr = Array.prototype.slice.call(arguments), + docFrag = document.createDocumentFragment(); + + argArr.forEach(function(argItem) { + var isNode = argItem instanceof Node; + docFrag.appendChild(isNode ? argItem : document.createTextNode(String(argItem))); + }); + + this.insertBefore(docFrag, this.firstChild); + } + }); + }); +})([Element.prototype, Document.prototype, DocumentFragment.prototype]); + +var SoziUi = function(element, options) { + this.element = element; + + this.options = Object.assign({ + summary: true, + position: 'bottom', + allowFullscreen: true + }, options || {}); + + this.options.lang = Object.assign({ + next: 'Suivant', + previous: 'Précédent', + fullscrenOn: 'Plein écran', + fullscrenOff: 'Réduire' + }, this.options.lang || {}); + + this.container = this.element.parentNode; + this.document = this.element.contentWindow; + this.sozi = this.document.sozi; + this.player = this.sozi.player; + this.document.document.querySelector('#sozi-framenumber').style.display = 'none'; +} + +SoziUi.prototype.addControls = function() { + var ui = ` +
${this.options.lang.previous}
+
+
+
${this.options.lang.next}
+
+`; + + if (this.options.allowFullscreen) { + var uiFullscreen = document.createElement('div'); + uiFullscreen.classList.add('sozi-ui-fullscreen'); + uiFullscreen.classList.add('sozi-ui-element'); + uiFullscreen.innerHTML = ` + ${this.options.lang.fullscrenOn} + ${this.options.lang.fullscrenOff} +` + + ui += uiFullscreen.outerHTML; + } + + if (this.options.summary) { + var summary = document.createElement('select'); + summary.classList.add('sozi-ui-summary'); + summary.classList.add('sozi-ui-element'); + + this.sozi.document.frames.forEach(function(frame, i) { + var item = document.createElement('option'); + item.classList.add('sozi-ui-summary-item'); + item.setAttribute('value', i); + item.textContent = frame.title; + + summary.appendChild(item); + }); + + ui += summary.outerHTML; + } + + + controls = document.createElement('div'); + controls.classList.add('sozi-ui-controls'); + controls.innerHTML = ui; + + if (this.options.position === 'bottom') { + controls.classList.add('position-bottom'); + this.container.append(controls); + } else { + controls.classList.add('position-top'); + this.container.prepend(controls); + } + + this.uiFrameCurrent = controls.querySelector('.sozi-ui-frame-current'); + this.uiFrameCurrentTitle = controls.querySelector('.sozi-ui-frame-current-title'); + this.uiFrameNumber = controls.querySelector('.sozi-ui-frame-number'); + this.uiSummaryItems = controls.querySelectorAll('.sozi-ui-summary-item'); + this.uiPlayerPrevious = controls.querySelector('.sozi-ui-player-previous'); + this.uiPlayerNext = controls.querySelector('.sozi-ui-player-next'); + this.uiFullscreenOn = controls.querySelector('.sozi-ui-fullscreen-on') + this.uiFullscreenOff = controls.querySelector('.sozi-ui-fullscreen-off') + + this.uiFrameCurrent.textContent = this.currentFrame(); + this.uiFrameNumber.textContent = this.frameNumber(); + this.uiFrameCurrentTitle.textContent = this.currentFrameTitle(); +} + +SoziUi.prototype.addEvents = function() { + var that = this; + + this.sozi.events.listen('framechange', function() { + that.onFrameChange(); + that.element.focus(); + }); + + this.uiPlayerPrevious.addEventListener('click', function() { + that.previousFrame(); + }, false); + + this.uiPlayerNext.addEventListener('click', function() { + that.nextFrame(); + }, false); + + this.container.addEventListener('mouseenter', function() { + that.element.focus(); + }, false) + + if (this.options.allowFullscreen) { + this.uiFullscreenOn.addEventListener('click', function() { + that.fullscreen(true); + }, false); + + this.uiFullscreenOff.addEventListener('click', function() { + that.fullscreen(false); + }, false); + + ['webkitfullscreenchange', 'mozfullscreenchange', 'fullscreenchange', 'MSFullscreenChange'].forEach(function(event) { + document.addEventListener(event, function() { + that.uiFullscreenOn.classList.toggle('active'); + that.uiFullscreenOff.classList.toggle('active'); + that.container.classList.toggle('fullscreen'); + that.element.focus(); + }, false); + }); + } + + if (this.options.summary) { + this.uiSummaryItems.forEach(function(item) { + item.addEventListener('click', function() { + var frame = parseInt(item.getAttribute('value')); + that.sozi.events.fire('framechange', frame); + that.player.moveToFrame(frame) + that.element.focus(); + }, false); + }); + } +} + +SoziUi.prototype.frameNumber = function() { + return this.sozi.document.frames.length; +} + +SoziUi.prototype.currentFrame = function() { + return this.sozi.location.getFrameIndex() + 1; +} + +SoziUi.prototype.currentFrameTitle = function() { + return this.sozi.document.frames[this.currentFrame() - 1].title; +} + +SoziUi.prototype.previousFrame = function() { + return this.player.moveToPrevious(); +} + +SoziUi.prototype.nextFrame = function() { + return this.player.moveToNext(); +} + +SoziUi.prototype.onFrameChange = function() { + this.uiFrameCurrent.textContent = this.currentFrame(); + this.uiFrameCurrentTitle.textContent = this.currentFrameTitle(); +} + +SoziUi.prototype.fullscreen = function(active) { + if (active) { + if (this.container.requestFullscreen) { + this.container.requestFullscreen(); + } else if (this.container.webkitRequestFullscreen) { + this.container.webkitRequestFullscreen(); + } else if (this.container.mozRequestFullScreen) { + this.container.mozRequestFullScreen(); + } + } else { + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (document.webkitExitFullscreen) { + document.webkitExitFullscreen(); + } else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen(); + } + } +}