You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

224 lines
4.6 KiB

  1. <template>
  2. <div v-if="!collapsed" class="player">
  3. <div class="progress-wrap">
  4. <div class="time-info">
  5. {{audio ? formatDuration(audio.currentTime) : "00:00"}}
  6. </div>
  7. <progress :value="audioPosition" :max="audio ? Math.floor(audio.duration): 0"></progress>
  8. <div class="time-info">
  9. {{audio ? formatDuration(audio.duration) : "00:00"}}
  10. </div>
  11. </div>
  12. <h3>{{album.title}}</h3>
  13. <ul>
  14. <li
  15. v-for="(track, index) in album.tracks"
  16. v-on:click="trackClicked('track-'+index)"
  17. v-bind:key="index+'-'+track.title"
  18. v-bind:class="{ active: audio && audio.getAttribute('id') === 'track-'+index }">
  19. <span class="track-number">{{index + 1}}</span>
  20. <span class="track-title">{{track.title.trim()}}</span>
  21. <audio v-on:timeupdate="updateAudioPosition()" v-bind:src="track.file" v-bind:id="'track-'+ index"></audio>
  22. </li>
  23. </ul>
  24. <div class="button-wrap">
  25. <img v-if="playing" v-on:click="pause()" src="../assets/images/pause.png" id="play-button">
  26. <img v-else v-on:click="play()" src="../assets/images/play.png" id="play-button">
  27. </div>
  28. <div class="player-switch opened" v-on:click="toggle()"></div>
  29. </div>
  30. <div v-else class="player-switch" v-on:click="toggle()">
  31. </div>
  32. </template>
  33. <script>
  34. export default {
  35. name: 'Player',
  36. props: {
  37. album: Object,
  38. },
  39. watch: {
  40. // whenever question changes, this function will run
  41. album: function (newAlbum, oldAlbum) {
  42. if(newAlbum !== oldAlbum)
  43. this.collapsed = false;
  44. }
  45. },
  46. data: function () {
  47. return {
  48. switcher : null,
  49. collapsed: true,
  50. playing: false,
  51. audioPosition: 0,
  52. audio : null,
  53. startTimeInfo: "00:00",
  54. endTimeInfo: "00:00",
  55. playerImage: '../assets/images/play.png'
  56. }
  57. },
  58. updated() {
  59. //this.bindAudioTags();
  60. },
  61. mounted(){
  62. this.switcher = document.getElementsByClassName('player-switch')[0];
  63. document.body.append(this.switcher);
  64. },
  65. methods: {
  66. toggle : function(){
  67. // this.playerContainer.classList.toggle('collapsed');
  68. this.collapsed = !this.collapsed;
  69. this.switcher.classList.toggle('opened');
  70. },
  71. play: function(){
  72. if(!this.audio)
  73. this.audio = document.querySelectorAll('audio')[0];
  74. this.playing = true;
  75. this.audio.play();
  76. },
  77. pause: function(){
  78. this.playing = false;
  79. this.audio.pause();
  80. },
  81. trackClicked: function(audioId){
  82. if(this.playing){
  83. this.pause();
  84. this.audio = document.getElementById(audioId);
  85. }
  86. else{
  87. this.audio = document.getElementById(audioId);
  88. }
  89. this.playing = true;
  90. this.audio.play();
  91. },
  92. updateAudioPosition: function(){
  93. this.audioPosition = Math.floor(this.audio.currentTime);
  94. },
  95. formatDuration: function(time){
  96. let s = parseInt(time% 60);
  97. let m = parseInt((time / 60) % 60);
  98. return (m < 10 ? ('0'+m) : m) + ':' + (s < 10 ? ('0'+s) : s);
  99. }
  100. }
  101. }
  102. </script>
  103. <style>
  104. *{
  105. --one-dpi: 72px;
  106. --dd-blue: rgb(0,42,255);
  107. }
  108. .player{
  109. width: 25vw;
  110. height: 100vh;
  111. position:fixed;
  112. top: 0px;
  113. background-color: var(--player-bg-color);/*rgba(var(--secondary-color), 0.8);*/
  114. right:0px;
  115. color: black;
  116. padding-top: var(--one-dpi);
  117. padding-bottom: var(--one-dpi);
  118. display: flex;
  119. flex-direction: column;
  120. /* justify-content: space-between; */
  121. }
  122. .collapsed{
  123. display: none;
  124. }
  125. .player-switch{
  126. position :fixed;
  127. bottom: 0;
  128. right: 0;
  129. width: var(--one-dpi);
  130. height:var(--one-dpi);
  131. background-color: white;
  132. cursor: pointer;
  133. z-index:10;
  134. }
  135. .player-switch.opened{
  136. background-color: var(--dd-blue);
  137. }
  138. li{
  139. cursor: pointer;
  140. }
  141. li:hover{
  142. color: var(--main-color);
  143. }
  144. li.active{
  145. font-weight: bold;
  146. }
  147. .player h3 {
  148. font-size: 1rem;
  149. margin: calc(var(--one-dpi) / 2);
  150. }
  151. .player ul {
  152. margin-left : calc(var(--one-dpi) / 2);
  153. color: var(--dd-blue);
  154. font-size: 1.5rem;
  155. list-style-type : none;
  156. }
  157. .progress-wrap{
  158. display:flex;
  159. width: 100%;
  160. justify-content: space-around;
  161. }
  162. .progress-wrap .time-info{
  163. font-size:0.66rem;
  164. display: flex;
  165. justify-content: center;
  166. }
  167. progress{
  168. display: inline;
  169. height: 10px;
  170. width:66%;
  171. }
  172. progress::-moz-progress-bar{
  173. background-color: black;
  174. }
  175. progress{
  176. background-color: #rgba(200,200,200,0.5);
  177. }
  178. .button-wrap{
  179. margin-top: 100px;
  180. margin-left: calc(var(--one-dpi) / 2);
  181. }
  182. .button-wrap img{
  183. cursor: pointer;
  184. }
  185. span.track-number{
  186. width: 25px;
  187. display: inline-block;
  188. }
  189. span.track-title:before{
  190. content: " - ";
  191. }
  192. </style>