Browse Source

the audio player is playing and displaying well

Bachir Soussi Chiadmi 7 years ago
parent
commit
2f806e39ab

+ 1 - 0
sites/all/themes/custom/edlptheme/assets/dist/img/audio-player-next.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="20" height="30" viewBox="0 0 5.2916665 7.9375002"><g transform="translate(0 -289.062)"><path d="M.472 289.197c1.81 1.044 4.71 3.049 4.71 3.815 0 .578-3.416 3.112-4.71 3.817-1.696.808 3.111-3.1 3.111-3.815 0-.92-4.673-4.435-3.113-3.817l.002 3.816z"/><rect style="isolation:auto;mix-blend-mode:normal" width="5.292" height="7.938" y="289.062" rx="1.197" ry=".826" color="#000" overflow="visible" fill="none"/></g></svg>

+ 1 - 0
sites/all/themes/custom/edlptheme/assets/dist/img/audio-player-pause.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="20" height="30" viewBox="0 0 5.2916665 7.9375002"><g transform="translate(0 -289.062)" fill="none"><rect style="isolation:auto;mix-blend-mode:normal" width="5.292" height="7.938" y="289.062" rx="1.197" ry=".826" color="#000" overflow="visible"/><g stroke="#000" stroke-width="1.058"><path d="M1.852 290.915v4.233M3.44 290.915v4.233"/></g></g></svg>

+ 1 - 0
sites/all/themes/custom/edlptheme/assets/dist/img/audio-player-play.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="20" height="30" viewBox="0 0 5.2916665 7.9375002"><g transform="translate(0 -289.062)" color="#000"><rect style="isolation:auto;mix-blend-mode:normal" width="5.292" height="7.938" y="289.062" rx="1.197" ry=".826" overflow="visible" fill="none"/><path style="isolation:auto;mix-blend-mode:normal" d="M1.317 291.38l2.776 1.68-2.776 1.622z" overflow="visible"/></g></svg>

+ 1 - 0
sites/all/themes/custom/edlptheme/assets/dist/img/audio-player-previous.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="20" height="30" viewBox="0 0 5.2916665 7.9375002"><g transform="translate(0 -289.062)"><path d="M4.82 296.866c-1.81-1.045-4.71-3.05-4.71-3.816 0-.577 3.415-3.111 4.709-3.816 1.697-.808-3.11 3.099-3.11 3.814 0 .921 4.672 4.435 3.113 3.818l-.002-3.816z"/><rect style="isolation:auto;mix-blend-mode:normal" width="5.292" height="7.938" y="289.062" rx="1.197" ry=".826" color="#000" overflow="visible" fill="none"/></g></svg>

+ 45 - 0
sites/all/themes/custom/edlptheme/assets/dist/img/edlp-loader-anim.svg

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+  width="40"
+  height="40"
+  fill="#ffffff"
+  xmlns:svg="http://www.w3.org/2000/svg"
+  xmlns="http://www.w3.org/2000/svg"
+  xmlns:xlink="http://www.w3.org/1999/xlink">
+  <rect
+    id="bg"
+    x="0" y="0"
+    width="40" height="40"
+    >
+  </rect>
+  <rect
+    id="blak-line"
+    x="0" y="19"
+    width="50" height="2"
+    fill="#000000"
+    transform="rotate(315 22 26)">
+  </rect>
+  <rect
+    id="red-line"
+    x="11" y="18"
+    width="18" height="4"
+    fill="#ff0004"
+    transform="rotate(45 20 20)">
+    <animate
+      xlink:href="#red-line"
+      attributeName="y"
+      from="1"
+      to="1"
+      dur="1.5s"
+      values="1;18;35;18;1"
+      keyTimes="0;0.25;0.5;0.75;1"
+      keySplines=".42 0 1 1;
+                  0 0 .59 1;
+                  .42 0 1 1"
+      fill="freeze"
+      begin="0s"
+      repeatCount="indefinite"
+      id="red-anim-one"/>
+
+  </rect>
+</svg>

+ 1 - 0
sites/all/themes/custom/edlptheme/assets/dist/img/edlp-loader.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 10.583333 10.583334"><path d="M10.16.14L.098 10.115c.131.104.262.318.394.354L10.533.517 10.16.14z"/><path d="M4.014 3.25c-.251.247-.502.495-.752.744L6.617 7.38l.752-.744L4.014 3.25z" fill="#ff0004"/></svg>

+ 1 - 0
sites/all/themes/custom/edlptheme/assets/dist/img/search.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 5.2916665 5.2916668" height="20" width="20"><path d="M2.506 2.725a1.039 1.039 0 0 1-.317-.76c0-.296.106-.55.317-.76a1.03 1.03 0 0 1 .76-.316c.295 0 .549.104.761.316.21.21.314.464.314.76s-.104.55-.314.76a1.041 1.041 0 0 1-.762.316c-.296 0-.548-.105-.76-.316zM.462 4.375a.3.3 0 0 0-.09.216c0 .084.03.156.093.215.059.062.13.093.216.093a.28.28 0 0 0 .215-.093l1.411-1.448c.287.198.605.298.958.298.229 0 .45-.044.659-.133.208-.09.388-.21.54-.36a1.676 1.676 0 0 0 .492-1.199A1.685 1.685 0 0 0 3.266.274c-.23 0-.449.045-.657.135a1.657 1.657 0 0 0-.901.9c-.09.209-.134.427-.134.657 0 .351.1.67.298.957z" fill="#000004"/></svg>

+ 1 - 0
sites/all/themes/custom/edlptheme/assets/dist/img/user.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 5.2916665 5.2916668" height="20" width="20"><path d="M4.468 4.043c0 .205-.06.383-.179.53a.524.524 0 0 1-.424.221H1.446a.534.534 0 0 1-.427-.222.822.822 0 0 1-.175-.529c0-.16.007-.311.022-.453.018-.144.047-.287.09-.43.045-.145.099-.269.165-.371a.795.795 0 0 1 .266-.252.74.74 0 0 1 .383-.1c.246.242.543.363.886.363.343 0 .64-.121.886-.362.143 0 .27.033.38.099a.75.75 0 0 1 .266.252c.068.102.123.226.167.37.043.144.073.287.088.43.017.143.025.294.025.454zM3.424.765c.213.21.32.467.32.766 0 .3-.107.558-.32.77a1.045 1.045 0 0 1-.768.319c-.3 0-.557-.107-.77-.319a1.055 1.055 0 0 1-.317-.77c0-.3.106-.556.317-.766a1.05 1.05 0 0 1 .77-.321c.3 0 .555.107.768.32z" fill="none" stroke="#000007" stroke-width=".5291699999999999"/></svg>

+ 118 - 82
sites/all/themes/custom/edlptheme/assets/dist/scripts/main.min.js

@@ -63,91 +63,127 @@ edlp_vars = {
       this.fid;
       this.audio = new Audio();
       // audio events
-      this.audio_events = ["loadedmetadata","progress","canplay","timeupdate","ended"];
+      this.audio_events = ["loadedmetadata","canplay","playing","pause","timeupdate","ended"];
 
       // UI dom objects
-      this.$container = $('<div id="audio-player">')
-        .appendTo('header[role="banner"] .region-header');
-      this.$timeline = $('<div>').addClass('time-line').appendTo(this.$container);
-      this.$loader = $('<div>').addClass('loader').appendTo(this.$timeline);
-      this.$cursor = $('<div>').addClass('cursor').appendTo(this.$timeline);
-      this.$duration = $('<div>').addClass('duration').appendTo(this.$container);
-      this.$currentTime = $('<div>').addClass('current-time').appendTo(this.$container);
-
-      if (typeof AudioPlayer.initialized == "undefined") {
-
-        AudioPlayer.prototype.init = function(){
-          // init audio events
-          var fn = '';
-          for (var i = 0; i < this.audio_events.length; i++) {
-            fn = this.audio_events[i];
-            // capitalize first letter of event (only cosmetic :p )
-            fn = 'on'+fn.charAt(0).toUpperCase()+fn.slice(1);
-            this.audio.addEventListener(
-              this.audio_events[i],
-              this[fn].bind(this),
-              true);
-          }
-        };
-
-        AudioPlayer.prototype.loadSound = function(url){
-          console.log('AudioPlayer loadSound : url', url);
-          this.audio.src = url;
-          // this.play();
-        };
-
-        AudioPlayer.prototype.play = function(){
-          console.log('AudioPlayer play()');
+      this.$container   = $('<div id="audio-player">');
+      // btns
+      this.$btns        = $('<div>').addClass('btns').appendTo(this.$container);
+      this.$previous    = $('<div>').addClass('previous').appendTo(this.$btns);
+      this.$playpause   = $('<div>').addClass('play-pause').appendTo(this.$btns);
+      this.$next        = $('<div>').addClass('next').appendTo(this.$btns);
+      // timeline
+      this.$timelinecont= $('<div>').addClass('time-line-container').appendTo(this.$container);
+      this.$timeline    = $('<div>').addClass('time-line').appendTo(this.$timelinecont);
+      this.$loader      = $('<div>').addClass('loader').appendTo(this.$timeline);
+      this.$cursor      = $('<div>').addClass('cursor').appendTo(this.$timeline);
+      // time
+      this.$time        = $('<div>').addClass('time').appendTo(this.$container);
+      this.$currentTime = $('<div>').addClass('current-time').html('00:00').appendTo(this.$time);
+      this.$duration    = $('<div>').addClass('duration').html('00:00').appendTo(this.$time);
+
+      // hiding
+      this.hideTimer = false;
+      this.hideTimeMS = 10000;
+
+      this.init();
+    };
+    AudioPlayer.prototype = {
+      init(){
+        // append ui to document
+        this.$container.appendTo('header[role="banner"] .region-header');
+        // record timeline width
+        this.timeline_w = parseInt(this.$timeline.width());
+        // init audio events
+        var fn = '';
+        for (var i = 0; i < this.audio_events.length; i++) {
+          fn = this.audio_events[i];
+          // capitalize first letter of event (only cosmetic :p )
+          fn = 'on'+fn.charAt(0).toUpperCase()+fn.slice(1);
+          this.audio.addEventListener(
+            this.audio_events[i],
+            this[fn].bind(this),
+            true);
+        }
+        // init btns events
+        this.$playpause.on('click', this.togglePlayPause.bind(this));
+        // TODO: previous and next btns
+      },
+      setSRC(url){
+        console.log('AudioPlayer setSRC : url', url);
+        this.clearTimeOutToHide();
+        this.audio.src = url;
+        this.show();
+      },
+      onLoadedmetadata(){
+        var rem = parseInt(this.audio.duration, 10),
+            mins = Math.floor(rem/60,10),
+            secs = rem - mins*60;
+        this.$duration.html('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');
+        this.updateLoadingBar();
+      },
+      updateLoadingBar(){
+        this.$loader.css({
+          'width':parseInt((100 * this.audio.buffered.end(0) / this.audio.duration), 10)+'%'
+        });
+        if( this.audio.buffered.end(0) < this.audio.duration ){
+          // loop through this function until file is fully loaded
+          var that = this;
+          window.requestAnimationFrame(that.updateLoadingBar.bind(that));
+        }else{
+          console.log('Audio fully loaded');
+        }
+      },
+      onCanplay(){
+        this.play();
+      },
+      play(){
+        this.audio.play();
+      },
+      togglePlayPause(){
+        if(this.audio.paused){
           this.audio.play();
-        };
-
-        AudioPlayer.prototype.onLoadedmetadata = function(){
-          var rem = parseInt(this.audio.duration, 10),
-              mins = Math.floor(rem/60,10),
-              secs = rem - mins*60;
-          this.$duration.html('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');
-        };
-
-        AudioPlayer.prototype.onProgress = function(){
-          // var myBuffered = this.audio.buffered;
-          // var mySeekable = this.audio.seekable;
-          if( this.audio.buffered.length ){
-            // var fromPercent = this.fromPercent;
-            // var value = percentLoad - fromPercent;
-            // if( value<0 ) value = 0;
-            // this.$loadingBar.css({width: value + '%',marginLeft:fromPercent + '%'});
-            this.$loader.css({
-              'width':parseInt(((this.audio.buffered.end(0) / this.audio.duration) * 100), 10)+'%'
-            });
-          }
-        };
-
-        AudioPlayer.prototype.onCanplay = function(){
-          this.play();
-        };
-
-        AudioPlayer.prototype.onTimeupdate = function(){
-          // console.log('Audio update()', this.audio.currentTime);
-
-          this.$cursor.css({
-            'left':(this.audio.currentTime/this.audio.duration * 50)+"px"
-          });
-
-          var rem = parseInt(this.audio.currentTime, 10),
-              mins = Math.floor(rem/60,10),
-              secs = rem - mins*60;
-          this.$currentTime.html('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');
-        };
-
-        AudioPlayer.prototype.onEnded = function(){
-          console.log('AudioPlayer onEnded');
-        };
-
-        AudioPlayer.initialized = true;
-        this.init();
+        }else{
+          this.audio.pause();
+        }
+      },
+      onPlaying(){
+        this.$container.addClass('is-playing');
+      },
+      onPause(){
+        this.$container.removeClass('is-playing');
+      },
+      onTimeupdate(){
+        // move cursor
+        this.$cursor.css({
+          'left':(this.audio.currentTime/this.audio.duration * this.timeline_w)+"px"
+        });
+        // update time text display
+        var rem = parseInt(this.audio.currentTime, 10),
+            mins = Math.floor(rem/60,10),
+            secs = rem - mins*60;
+        this.$currentTime.html('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');
+      },
+      onEnded(){
+        this.$container.removeClass('is-playing');
+        this.timeOutToHide();
+      },
+      show(){
+        this.$container.addClass('visible');
+      },
+      timeOutToHide(){
+        this.clearTimeOutToHide();
+        this.hideTimer = setTimeout(this.hide.bind(this), this.hideTimeMS);
+      },
+      clearTimeOutToHide(){
+        if(this.hideTimer){
+          clearTimeout(this.hideTimer);
+        }
+      },
+      hide(){
+        this.$container.removeClass('visible');
       }
-    };
-
+    }
     //  ___             _ _ ___
     // / __| __ _ _ ___| | | _ ) __ _ _ _ ___
     // \__ \/ _| '_/ _ \ | | _ \/ _` | '_(_-<
@@ -275,7 +311,7 @@ edlp_vars = {
         })
         .on('corpus-cliked-on-node', function(e) {
           console.log('theme : corpus-cliked-on-node', e);
-          _audio_player.loadSound(e.target_node.audio_url);
+          _audio_player.setSRC(e.target_node.audio_url);
         });
     }
 

+ 47 - 9
sites/all/themes/custom/edlptheme/assets/dist/styles/app.min.css

@@ -1285,7 +1285,7 @@ body.ajax-loading main[role="main"]:before {
   top: calc(50% - 30px);
   left: calc(50% - 30px);
   background-color: white;
-  background-image: url(../../img/edlp-loader-anim.svg);
+  background-image: url(../img/edlp-loader-anim.svg);
   background-size: 50%;
   background-repeat: no-repeat;
   background-position: center;
@@ -1297,31 +1297,69 @@ body.ajax-loading main[role="main"]:before {
   left: 0;
   background-color: white;
   height: 100%;
-  min-width: 300px;
-  max-width: 500px;
+  width: 300px;
   z-index: 20;
-  outline: 1px dotted green; }
-  #audio-player .time-line {
+  opacity: 0;
+  pointer-events: none;
+  -webkit-transition: opacity 0.7s ease-in-out;
+  transition: opacity 0.7s ease-in-out; }
+  #audio-player.visible {
+    opacity: 1;
+    pointer-events: all; }
+  #audio-player .btns, #audio-player .time-line-container, #audio-player .time {
+    display: inline-block;
+    vertical-align: middle;
+    padding: 0 1em 0 0; }
+  #audio-player .btns {
+    cursor: pointer; }
+    #audio-player .btns > * {
+      display: inline-block;
+      vertical-align: middle;
+      width: 20px;
+      height: 30px;
+      background-position: center;
+      background-size: contain; }
+    #audio-player .btns .previous {
+      background-image: url(../img/audio-player-previous.svg);
+      opacity: 0.3; }
+    #audio-player .btns .play-pause {
+      background-image: url(../img/audio-player-play.svg);
+      padding: 0 0.3em; }
+    #audio-player .btns .next {
+      background-image: url(../img/audio-player-next.svg);
+      opacity: 0.3; }
+  #audio-player .time-line-container .time-line {
     position: relative;
-    width: 50px;
+    width: 70px;
     height: 1px;
     background-color: #000;
     overflow: visible;
     -webkit-transform: rotateZ(-45deg);
     transform: rotateZ(-45deg); }
-    #audio-player .time-line .loader {
+    #audio-player .time-line-container .time-line .loader {
       width: 0;
       height: 100%;
       background-color: red;
       top: 0;
       left: 0; }
-    #audio-player .time-line .cursor {
+    #audio-player .time-line-container .time-line .cursor {
       height: 10px;
       width: 0;
       border-left: 2px solid red;
       position: absolute;
       left: 0;
       top: -5px; }
+  #audio-player .time > * {
+    width: 70px;
+    text-align: right; }
+  #audio-player .time .current-time {
+    font-size: 1.4em;
+    font-weight: 600; }
+  #audio-player .time .duration {
+    font-size: 0.75em;
+    font-weight: 400; }
+  #audio-player.is-playing .btns .play-pause {
+    background-image: url(../img/audio-player-pause.svg); }
 
 body.path-agenda main .col > .wrapper {
   height: 100%; }
@@ -1640,7 +1678,7 @@ footer {
       position: relative;
       width: 20px;
       height: 20px;
-      background-image: url(../../img/user.svg);
+      background-image: url(../img/user.svg);
       background-size: contain;
       text-indent: 40px;
       margin: 0;

+ 73 - 0
sites/all/themes/custom/edlptheme/assets/img/audio-player-next.svg

@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="20"
+   height="30"
+   viewBox="0 0 5.2916665 7.9375002"
+   version="1.1"
+   id="svg14218"
+   inkscape:version="0.92.2 5c3e80d, 2017-08-06"
+   sodipodi:docname="audio-player-next.svg">
+  <defs
+     id="defs14212" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="22.4"
+     inkscape:cx="8.1129039"
+     inkscape:cy="15.501426"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     units="px"
+     inkscape:window-width="1920"
+     inkscape:window-height="1025"
+     inkscape:window-x="0"
+     inkscape:window-y="28"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata14215">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Calque 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-289.06247)">
+    <path
+       sodipodi:nodetypes="cccsccc"
+       inkscape:connector-curvature="0"
+       id="path62692"
+       d="m 0.47175957,289.19663 c 1.80948023,1.04471 4.70972013,3.04891 4.70988013,3.81544 7e-5,0.57746 -3.4154,3.11186 -4.70887993,3.81663 -1.69683007,0.8079 3.11026993,-3.09909 3.11026993,-3.81425 0,-0.92127 -4.67257,-4.43532 -3.11327013,-3.81782 l 0.00201,3.81604 z"
+       style="display:inline;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.13613257;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;paint-order:normal" />
+    <rect
+       style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.05833328;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="rect14809"
+       width="5.2916665"
+       height="7.9375"
+       x="0"
+       y="289.06247"
+       rx="1.1972487"
+       ry="0.8259095" />
+  </g>
+</svg>

+ 84 - 0
sites/all/themes/custom/edlptheme/assets/img/audio-player-pause.svg

@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="20"
+   height="30"
+   viewBox="0 0 5.2916665 7.9375002"
+   version="1.1"
+   id="svg14218"
+   inkscape:version="0.92.2 5c3e80d, 2017-08-06"
+   sodipodi:docname="audio-player-pause.svg">
+  <defs
+     id="defs14212" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="22.4"
+     inkscape:cx="8.1129039"
+     inkscape:cy="15.501426"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     units="px"
+     inkscape:window-width="1920"
+     inkscape:window-height="1025"
+     inkscape:window-x="0"
+     inkscape:window-y="28"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata14215">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Calque 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-289.06247)">
+    <rect
+       style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.05833328;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="rect14809"
+       width="5.2916665"
+       height="7.9375"
+       x="0"
+       y="289.06247"
+       rx="1.1972487"
+       ry="0.8259095" />
+    <g
+       style="display:inline"
+       id="g62688"
+       transform="translate(-64.822915,248.58122)">
+      <path
+         sodipodi:nodetypes="cc"
+         inkscape:connector-curvature="0"
+         id="path62684"
+         d="m 66.674999,42.33333 v 4.233334"
+         style="fill:none;stroke:#000000;stroke-width:1.05833328;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <path
+         sodipodi:nodetypes="cc"
+         style="fill:none;stroke:#000000;stroke-width:1.05833328;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         d="m 68.262497,42.33333 v 4.233334"
+         id="path62686"
+         inkscape:connector-curvature="0" />
+    </g>
+  </g>
+</svg>

+ 73 - 0
sites/all/themes/custom/edlptheme/assets/img/audio-player-play.svg

@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="20"
+   height="30"
+   viewBox="0 0 5.2916665 7.9375002"
+   version="1.1"
+   id="svg14218"
+   inkscape:version="0.92.2 5c3e80d, 2017-08-06"
+   sodipodi:docname="audio-player-play.svg">
+  <defs
+     id="defs14212" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="22.4"
+     inkscape:cx="8.1129039"
+     inkscape:cy="15.501426"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     units="px"
+     inkscape:window-width="1920"
+     inkscape:window-height="1025"
+     inkscape:window-x="0"
+     inkscape:window-y="28"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata14215">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Calque 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-289.06247)">
+    <rect
+       style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.05833328;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="rect14809"
+       width="5.2916665"
+       height="7.9375"
+       x="0"
+       y="289.06247"
+       rx="1.1972487"
+       ry="0.8259095" />
+    <path
+       style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.05833328;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       d="m 1.3167571,291.38062 2.77627,1.67976 -2.77627,1.62143 z"
+       id="rect4506"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc" />
+  </g>
+</svg>

+ 73 - 0
sites/all/themes/custom/edlptheme/assets/img/audio-player-previous.svg

@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="20"
+   height="30"
+   viewBox="0 0 5.2916665 7.9375002"
+   version="1.1"
+   id="svg14218"
+   inkscape:version="0.92.2 5c3e80d, 2017-08-06"
+   sodipodi:docname="audio-player-previous.svg">
+  <defs
+     id="defs14212" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="22.4"
+     inkscape:cx="8.1129039"
+     inkscape:cy="15.501426"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     units="px"
+     inkscape:window-width="1920"
+     inkscape:window-height="1025"
+     inkscape:window-x="0"
+     inkscape:window-y="28"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata14215">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Calque 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-289.06247)">
+    <path
+       sodipodi:nodetypes="cccsccc"
+       inkscape:connector-curvature="0"
+       id="path62692"
+       d="m 4.8199069,296.86581 c -1.8094802,-1.04471 -4.70972012,-3.04891 -4.70988012,-3.81544 -7e-5,-0.57746 3.41540002,-3.11186 4.70887992,-3.81663 1.6968301,-0.8079 -3.1102699,3.09909 -3.1102699,3.81425 0,0.92127 4.67257,4.43532 3.1132701,3.81782 l -0.00201,-3.81604 z"
+       style="display:inline;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.13613257;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0;paint-order:normal" />
+    <rect
+       style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.05833328;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="rect14809"
+       width="5.2916665"
+       height="7.9375"
+       x="0"
+       y="289.06247"
+       rx="1.1972487"
+       ry="0.8259095" />
+  </g>
+</svg>

+ 16 - 15
sites/all/themes/custom/edlptheme/assets/img/edlp-loader-anim.svg

@@ -25,20 +25,21 @@
     width="18" height="4"
     fill="#ff0004"
     transform="rotate(45 20 20)">
+    <animate
+      xlink:href="#red-line"
+      attributeName="y"
+      from="1"
+      to="1"
+      dur="1.5s"
+      values="1;18;35;18;1"
+      keyTimes="0;0.25;0.5;0.75;1"
+      keySplines=".42 0 1 1;
+                  0 0 .59 1;
+                  .42 0 1 1"
+      fill="freeze"
+      begin="0s"
+      repeatCount="indefinite"
+      id="red-anim-one"/>
+
   </rect>
-  <animate
-    xlink:href="#red-line"
-    attributeName="y"
-    from="1"
-    to="1"
-    dur="1.5s"
-    values="1;18;35;18;1"
-    keyTimes="0;0.25;0.5;0.75;1"
-    keySplines=".42 0 1 1;
-                0 0 .59 1;
-                .42 0 1 1"
-    fill="freeze"
-    begin="0s"
-    repeatCount="indefinite"
-    id="red-anim-one"/>
 </svg>

+ 118 - 82
sites/all/themes/custom/edlptheme/assets/scripts/main.js

@@ -40,91 +40,127 @@
       this.fid;
       this.audio = new Audio();
       // audio events
-      this.audio_events = ["loadedmetadata","progress","canplay","timeupdate","ended"];
+      this.audio_events = ["loadedmetadata","canplay","playing","pause","timeupdate","ended"];
 
       // UI dom objects
-      this.$container = $('<div id="audio-player">')
-        .appendTo('header[role="banner"] .region-header');
-      this.$timeline = $('<div>').addClass('time-line').appendTo(this.$container);
-      this.$loader = $('<div>').addClass('loader').appendTo(this.$timeline);
-      this.$cursor = $('<div>').addClass('cursor').appendTo(this.$timeline);
-      this.$duration = $('<div>').addClass('duration').appendTo(this.$container);
-      this.$currentTime = $('<div>').addClass('current-time').appendTo(this.$container);
-
-      if (typeof AudioPlayer.initialized == "undefined") {
-
-        AudioPlayer.prototype.init = function(){
-          // init audio events
-          var fn = '';
-          for (var i = 0; i < this.audio_events.length; i++) {
-            fn = this.audio_events[i];
-            // capitalize first letter of event (only cosmetic :p )
-            fn = 'on'+fn.charAt(0).toUpperCase()+fn.slice(1);
-            this.audio.addEventListener(
-              this.audio_events[i],
-              this[fn].bind(this),
-              true);
-          }
-        };
-
-        AudioPlayer.prototype.loadSound = function(url){
-          console.log('AudioPlayer loadSound : url', url);
-          this.audio.src = url;
-          // this.play();
-        };
-
-        AudioPlayer.prototype.play = function(){
-          console.log('AudioPlayer play()');
+      this.$container   = $('<div id="audio-player">');
+      // btns
+      this.$btns        = $('<div>').addClass('btns').appendTo(this.$container);
+      this.$previous    = $('<div>').addClass('previous').appendTo(this.$btns);
+      this.$playpause   = $('<div>').addClass('play-pause').appendTo(this.$btns);
+      this.$next        = $('<div>').addClass('next').appendTo(this.$btns);
+      // timeline
+      this.$timelinecont= $('<div>').addClass('time-line-container').appendTo(this.$container);
+      this.$timeline    = $('<div>').addClass('time-line').appendTo(this.$timelinecont);
+      this.$loader      = $('<div>').addClass('loader').appendTo(this.$timeline);
+      this.$cursor      = $('<div>').addClass('cursor').appendTo(this.$timeline);
+      // time
+      this.$time        = $('<div>').addClass('time').appendTo(this.$container);
+      this.$currentTime = $('<div>').addClass('current-time').html('00:00').appendTo(this.$time);
+      this.$duration    = $('<div>').addClass('duration').html('00:00').appendTo(this.$time);
+
+      // hiding
+      this.hideTimer = false;
+      this.hideTimeMS = 10000;
+
+      this.init();
+    };
+    AudioPlayer.prototype = {
+      init(){
+        // append ui to document
+        this.$container.appendTo('header[role="banner"] .region-header');
+        // record timeline width
+        this.timeline_w = parseInt(this.$timeline.width());
+        // init audio events
+        var fn = '';
+        for (var i = 0; i < this.audio_events.length; i++) {
+          fn = this.audio_events[i];
+          // capitalize first letter of event (only cosmetic :p )
+          fn = 'on'+fn.charAt(0).toUpperCase()+fn.slice(1);
+          this.audio.addEventListener(
+            this.audio_events[i],
+            this[fn].bind(this),
+            true);
+        }
+        // init btns events
+        this.$playpause.on('click', this.togglePlayPause.bind(this));
+        // TODO: previous and next btns
+      },
+      setSRC(url){
+        console.log('AudioPlayer setSRC : url', url);
+        this.clearTimeOutToHide();
+        this.audio.src = url;
+        this.show();
+      },
+      onLoadedmetadata(){
+        var rem = parseInt(this.audio.duration, 10),
+            mins = Math.floor(rem/60,10),
+            secs = rem - mins*60;
+        this.$duration.html('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');
+        this.updateLoadingBar();
+      },
+      updateLoadingBar(){
+        this.$loader.css({
+          'width':parseInt((100 * this.audio.buffered.end(0) / this.audio.duration), 10)+'%'
+        });
+        if( this.audio.buffered.end(0) < this.audio.duration ){
+          // loop through this function until file is fully loaded
+          var that = this;
+          window.requestAnimationFrame(that.updateLoadingBar.bind(that));
+        }else{
+          console.log('Audio fully loaded');
+        }
+      },
+      onCanplay(){
+        this.play();
+      },
+      play(){
+        this.audio.play();
+      },
+      togglePlayPause(){
+        if(this.audio.paused){
           this.audio.play();
-        };
-
-        AudioPlayer.prototype.onLoadedmetadata = function(){
-          var rem = parseInt(this.audio.duration, 10),
-              mins = Math.floor(rem/60,10),
-              secs = rem - mins*60;
-          this.$duration.html('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');
-        };
-
-        AudioPlayer.prototype.onProgress = function(){
-          // var myBuffered = this.audio.buffered;
-          // var mySeekable = this.audio.seekable;
-          if( this.audio.buffered.length ){
-            // var fromPercent = this.fromPercent;
-            // var value = percentLoad - fromPercent;
-            // if( value<0 ) value = 0;
-            // this.$loadingBar.css({width: value + '%',marginLeft:fromPercent + '%'});
-            this.$loader.css({
-              'width':parseInt(((this.audio.buffered.end(0) / this.audio.duration) * 100), 10)+'%'
-            });
-          }
-        };
-
-        AudioPlayer.prototype.onCanplay = function(){
-          this.play();
-        };
-
-        AudioPlayer.prototype.onTimeupdate = function(){
-          // console.log('Audio update()', this.audio.currentTime);
-
-          this.$cursor.css({
-            'left':(this.audio.currentTime/this.audio.duration * 50)+"px"
-          });
-
-          var rem = parseInt(this.audio.currentTime, 10),
-              mins = Math.floor(rem/60,10),
-              secs = rem - mins*60;
-          this.$currentTime.html('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');
-        };
-
-        AudioPlayer.prototype.onEnded = function(){
-          console.log('AudioPlayer onEnded');
-        };
-
-        AudioPlayer.initialized = true;
-        this.init();
+        }else{
+          this.audio.pause();
+        }
+      },
+      onPlaying(){
+        this.$container.addClass('is-playing');
+      },
+      onPause(){
+        this.$container.removeClass('is-playing');
+      },
+      onTimeupdate(){
+        // move cursor
+        this.$cursor.css({
+          'left':(this.audio.currentTime/this.audio.duration * this.timeline_w)+"px"
+        });
+        // update time text display
+        var rem = parseInt(this.audio.currentTime, 10),
+            mins = Math.floor(rem/60,10),
+            secs = rem - mins*60;
+        this.$currentTime.html('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');
+      },
+      onEnded(){
+        this.$container.removeClass('is-playing');
+        this.timeOutToHide();
+      },
+      show(){
+        this.$container.addClass('visible');
+      },
+      timeOutToHide(){
+        this.clearTimeOutToHide();
+        this.hideTimer = setTimeout(this.hide.bind(this), this.hideTimeMS);
+      },
+      clearTimeOutToHide(){
+        if(this.hideTimer){
+          clearTimeout(this.hideTimer);
+        }
+      },
+      hide(){
+        this.$container.removeClass('visible');
       }
-    };
-
+    }
     //  ___             _ _ ___
     // / __| __ _ _ ___| | | _ ) __ _ _ _ ___
     // \__ \/ _| '_/ _ \ | | _ \/ _` | '_(_-<
@@ -252,7 +288,7 @@
         })
         .on('corpus-cliked-on-node', function(e) {
           console.log('theme : corpus-cliked-on-node', e);
-          _audio_player.loadSound(e.target_node.audio_url);
+          _audio_player.setSRC(e.target_node.audio_url);
         });
     }
 

+ 74 - 20
sites/all/themes/custom/edlptheme/assets/styles/app.scss

@@ -173,7 +173,7 @@ main[role="main"]{
       width:$s; height:$s;
       top:calc(50% - #{$s/2}); left:calc(50% - #{$s/2});
       background-color: white;
-      background-image: url(../../img/edlp-loader-anim.svg);
+      background-image: url(../img/edlp-loader-anim.svg);
       background-size: 50%;
       background-repeat: no-repeat;
       background-position: center;
@@ -192,28 +192,82 @@ main[role="main"]{
   position: absolute;
   top:0; left:0;
   background-color: white;
-  height:100%; min-width: 300px; max-width:500px;
+  height:100%; width:300px;
   z-index: 20;
-  outline: 1px dotted green;
-  .time-line{
-    position: relative;
-    width:50px; height:1px;
-    background-color: #000;
-    overflow: visible;
-    // border-top: 1px solid #000;
-    transform: rotateZ(-45deg);
-    .loader{
-      width:0; height:100%;
-      background-color: red;
-      top:0;left:0;
+  opacity: 0;
+  pointer-events: none;
+  transition: opacity 0.7s ease-in-out;
+  &.visible{
+    opacity: 1;
+    pointer-events:all;
+  }
+  .btns, .time-line-container, .time{
+    display: inline-block;
+    vertical-align: middle;
+    padding:0 1em 0 0;
+  }
+  .btns{
+    // outline: 1px dotted orange;
+    &>*{
+      display: inline-block;
+      vertical-align: middle;
+      width:20px;height:30px;
+      background-position: center;
+      background-size: contain;
     }
-    .cursor{
-      height:10px;width:0;
-      border-left: 2px solid red;
-      position:absolute;
-      left:0; top:-5px;
+    .previous{
+      background-image: url(../img/audio-player-previous.svg);
+      opacity: 0.3;}
+    .play-pause{
+      background-image: url(../img/audio-player-play.svg);
+      padding:0 0.3em;}
+      cursor: pointer;
+    .next{
+      background-image: url(../img/audio-player-next.svg);
+      opacity: 0.3;}
+  }
+  .time-line-container{
+    // outline: 1px dotted purple;
+    .time-line{
+      position: relative;
+      width:70px; height:1px;
+      background-color: #000;
+      overflow: visible;
+      // border-top: 1px solid #000;
+      transform: rotateZ(-45deg);
+      .loader{
+        width:0; height:100%;
+        background-color: red;
+        top:0;left:0;
+      }
+      .cursor{
+        height:10px;width:0;
+        border-left: 2px solid red;
+        position:absolute;
+        left:0; top:-5px;
+      }
     }
   }
+  .time{
+    // outline: 1px dotted brown;
+    &>*{
+      width:70px;
+      text-align: right;
+      // outline: 1px dotted red;
+    }
+    .current-time{
+      font-size: 1.4em;
+      font-weight: 600;
+    }
+    .duration{
+      font-size: 0.75em;
+      font-weight: 400;
+    }
+  }
+
+  &.is-playing{
+    .btns .play-pause{background-image: url(../img/audio-player-pause.svg);}
+  }
 }
 
  //    _    _            _  _         _
@@ -616,7 +670,7 @@ footer{
     h2{
       position: relative;
       width:$wh; height:$wh;
-      background-image: url(../../img/user.svg);
+      background-image: url(../img/user.svg);
       // background-color: red;
       background-size: contain;
       text-indent: $wh*2;