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.
 
 
 
 
 

375 lines
11 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. data: function () {
  40. return {
  41. switcher : null,
  42. collapsed: true,
  43. playing: false,
  44. audioPosition: 0,
  45. audio : null,
  46. startTimeInfo: "00:00",
  47. endTimeInfo: "00:00",
  48. playerImage: '../assets/images/play.png'
  49. }
  50. },
  51. updated() {
  52. //this.bindAudioTags();
  53. },
  54. mounted(){
  55. this.switcher = document.getElementsByClassName('player-switch')[0];
  56. document.body.append(this.switcher);
  57. // this.currentAudio = null;
  58. // this.playing = false;
  59. // this.playerContainer = document.createElement("div");
  60. // this.container = document.querySelector('#player')
  61. // this.playerContainer.classList.add('dd-player');
  62. // this.switcher = document.createElement("div");
  63. // this.switcher.classList.add('dd-player-switch');
  64. // this.playerContainer.classList.add('collapsed');
  65. // document.body.appendChild(this.switcher);
  66. //
  67. // this.switcher.addEventListener('click', () => {
  68. // this.playerContainer.classList.toggle('collapsed');
  69. // this.switcher.classList.toggle('opened');
  70. // });
  71. //
  72. //
  73. // this.addProgressBar();
  74. // this.bindAudioTags();
  75. // this.addPlayButton();
  76. //
  77. // let wrap = document.createElement("div");
  78. // wrap.setAttribute('id', 'wrap-playlist')
  79. // this.container.parentElement.appendChild(this.playerContainer);
  80. // this.playerContainer.appendChild(wrap);
  81. // wrap.appendChild(this.container);
  82. },
  83. methods: {
  84. toggle : function(){
  85. // this.playerContainer.classList.toggle('collapsed');
  86. this.collapsed = !this.collapsed;
  87. this.switcher.classList.toggle('opened');
  88. },
  89. play: function(){
  90. if(!this.audio)
  91. this.audio = document.querySelectorAll('audio')[0];
  92. this.playing = true;
  93. this.audio.play();
  94. // if(this.playing){
  95. // this.audio.play();
  96. // // this.currentAudio.parentElement.classList.add('playing');
  97. // // self.progressBar.setAttribute('max', Math.floor(self.currentAudio.duration));
  98. // // self.endTimeInfo.innerHTML = self.formatDuration(self.currentAudio.duration);
  99. // // this.playButton.setAttribute('src','./images/pause.png');
  100. // }
  101. // else{
  102. // this.audio.pause();
  103. // // self.currentAudio.parentElement.classList.remove('playing');
  104. // // this.playButton.setAttribute('src','./images/play.png');
  105. // }
  106. },
  107. pause: function(){
  108. this.playing = false;
  109. this.audio.pause();
  110. },
  111. trackClicked: function(audioId){
  112. //let track = document.getElementById(audioId);
  113. if(this.playing){
  114. this.pause();
  115. this.audio = document.getElementById(audioId);
  116. }
  117. else{
  118. this.audio = document.getElementById(audioId);
  119. }
  120. this.playing = true;
  121. this.audio.play();
  122. },
  123. updateAudioPosition: function(){
  124. this.audioPosition = Math.floor(this.audio.currentTime);
  125. },
  126. // addProgressBar: function(){
  127. // this.progressBar = document.createElement("progress");
  128. // this.progressBar.setAttribute('value', 0);
  129. // this.startTimeInfo = document.createElement('div');
  130. // this.endTimeInfo = document.createElement('div');
  131. // let progressWrap = document.createElement("div");
  132. // this.startTimeInfo.innerHTML = "00:00";
  133. // this.endTimeInfo.innerHTML = "00:00";
  134. // progressWrap.appendChild(this.startTimeInfo);
  135. // progressWrap.appendChild(this.progressBar);
  136. // progressWrap.appendChild(this.endTimeInfo);
  137. // this.startTimeInfo.classList.add('time-info');
  138. // this.endTimeInfo.classList.add('time-info');
  139. // progressWrap.classList.add('progress-wrap');
  140. // this.playerContainer.append(progressWrap);
  141. // let self = this;
  142. // this.progressBar.addEventListener('click', (e) => {
  143. // if(self.currentAudio){
  144. // self.currentAudio.currentTime = Math.floor(((e.layerX - self.progressBar.offsetLeft) * self.currentAudio.duration) / self.progressBar.offsetWidth);
  145. // self.progressBar.value = Math.floor(self.currentAudio.currentTime );
  146. // }
  147. // });
  148. //
  149. // },
  150. // addPlayButton: function(){
  151. // this.playButton = document.createElement("img");
  152. // this.playButton.setAttribute('src','./images/play.png');
  153. // this.playButton.setAttribute('id','play-button');
  154. // let wrap = document.createElement("div");
  155. // wrap.append(this.playButton);
  156. // this.container.append(wrap);
  157. // let self = this;
  158. // this.playButton.addEventListener('click', () => {
  159. // self.playing = !self.playing;
  160. // if(self.playing){
  161. // self.currentAudio.play();
  162. // self.currentAudio.parentElement.classList.add('playing');
  163. // self.progressBar.setAttribute('max', Math.floor(self.currentAudio.duration));
  164. // self.endTimeInfo.innerHTML = self.formatDuration(self.currentAudio.duration);
  165. // this.playButton.setAttribute('src','./images/pause.png');
  166. // }
  167. // else{
  168. // self.currentAudio.pause();
  169. // self.currentAudio.parentElement.classList.remove('playing');
  170. // this.playButton.setAttribute('src','./images/play.png');
  171. // }
  172. // })
  173. // },
  174. // bindAudioTags: function(){
  175. // let liTags = this.container.querySelectorAll('li')
  176. // let self = this;
  177. // let i = 0;
  178. // liTags.forEach(function(itemElement){
  179. // let audioTag = itemElement.querySelector('audio')
  180. // if(audioTag){
  181. // audioTag.addEventListener('timeupdate', () => {
  182. // self.audioTimeUpdate(audioTag);
  183. // });
  184. // audioTag.addEventListener('ended', () => {
  185. // self.audioEnded(i);
  186. // })
  187. //
  188. // //itemElement.appendChild(audioElement);
  189. // audioTag.setAttribute('id','track-'+i);
  190. // if(i === 0)
  191. // self.currentAudio = audioTag;
  192. // itemElement.addEventListener('click', () => {
  193. // let items = self.container.getElementsByTagName('li');
  194. // for(let i = 0; i < items.length; i++){
  195. // items[i].classList.remove('playing');
  196. // }
  197. // if(self.currentAudio)
  198. // self.currentAudio.pause();
  199. // audioTag.play();
  200. // self.playButton.setAttribute('src','./images/pause.png');
  201. // self.playing = true;
  202. // itemElement.classList.add('playing');
  203. // self.currentAudio = audioTag;
  204. // self.progressBar.setAttribute('max', Math.floor(self.currentAudio.duration));
  205. // self.endTimeInfo.innerHTML = self.formatDuration(self.currentAudio.duration);
  206. // self.progressBar.setAttribute('value', 0);
  207. // });
  208. //
  209. // i++;
  210. // }
  211. // });
  212. // },
  213. // audioTimeUpdate: function(audioElt){
  214. // this.progressBar.value = Math.floor(audioElt.currentTime);
  215. // this.startTimeInfo.innerHTML = this.formatDuration(audioElt.currentTime);
  216. // },
  217. //
  218. // audioEnded: function(n){
  219. // let audios = document.getElementsByTagName('audio');
  220. // let next = n == audios.length - 1 ? 0 : n + 1;
  221. // this.currentAudio.pause();
  222. // this.currentAudio.currentTime = 0;
  223. // this.currentAudio = document.getElementsByTagName('audio')[next];
  224. // this.currentAudio.parentElement.click();
  225. // },
  226. formatDuration: function(time){
  227. let s = parseInt(time% 60);
  228. let m = parseInt((time / 60) % 60);
  229. return (m < 10 ? ('0'+m) : m) + ':' + (s < 10 ? ('0'+s) : s);
  230. }
  231. }
  232. }
  233. </script>
  234. <style>
  235. *{
  236. --one-dpi: 72px;
  237. --dd-blue: rgb(0,42,255);
  238. }
  239. .player{
  240. width: 25vw;
  241. height: 100vh;
  242. position:fixed;
  243. top: 0px;
  244. background-color: white;
  245. right:0px;
  246. color: black;
  247. padding-top: var(--one-dpi);
  248. padding-bottom: var(--one-dpi);
  249. display: flex;
  250. flex-direction: column;
  251. /* justify-content: space-between; */
  252. }
  253. .collapsed{
  254. display: none;
  255. }
  256. .player-switch{
  257. position :fixed;
  258. bottom: 0;
  259. right: 0;
  260. width: var(--one-dpi);
  261. height:var(--one-dpi);
  262. background-color: white;
  263. cursor: pointer;
  264. z-index:10;
  265. }
  266. .player-switch.opened{
  267. background-color: var(--dd-blue);
  268. }
  269. li.active{
  270. font-weight: bold;
  271. }
  272. .player h3 {
  273. font-size: 1rem;
  274. margin: calc(var(--one-dpi) / 2);
  275. }
  276. .player ul {
  277. margin-left : calc(var(--one-dpi) / 2);
  278. color: var(--dd-blue);
  279. font-size: 1.5rem;
  280. list-style-type : none;
  281. }
  282. /*
  283. .dd-player ul li img{
  284. width:24px;
  285. height:24px;
  286. margin-right: 12px;
  287. }
  288. .playing{
  289. font-weight: bold;
  290. color : black;
  291. }
  292. */
  293. .progress-wrap{
  294. display:flex;
  295. width: 100%;
  296. justify-content: space-around;
  297. }
  298. .progress-wrap .time-info{
  299. font-size:0.66rem;
  300. display: flex;
  301. justify-content: center;
  302. }
  303. progress{
  304. display: inline;
  305. height: 10px;
  306. width:66%;
  307. }
  308. /*
  309. #play-button{
  310. max-width: calc(var(--one-dpi) / 2);
  311. max-height: calc(var(--one-dpi) / 2);
  312. margin: calc(var(--one-dpi) / 2);
  313. }
  314. */
  315. progress::-moz-progress-bar{
  316. background-color: black;
  317. }
  318. progress{
  319. background-color: #rgba(200,200,200,0.5);
  320. }
  321. .button-wrap{
  322. margin-top: 100px;
  323. }
  324. /*
  325. .dd-player ul li, #play-button{
  326. cursor : pointer;
  327. }
  328. #wrap-playlist{
  329. flex: 1;
  330. }
  331. */
  332. span.track-number{
  333. width: 25px;
  334. display: inline-block;
  335. }
  336. span.track-title:before{
  337. content: " - ";
  338. }
  339. </style>