Часто делаю на сайтах текстовые отзывы, намного реже фото / видео или подключаю со сторонних источников. На днях на одном сайте впервые увидел аудио-отзывы, обычные блоке с элементом <audio>
, и стало интересно попробовать их оформить.
Пример:
00:00
00:00
HTML:
Все аудио-файлы и описание к ним указываются в JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
<audio id="myAudio" ontimeupdate="onTimeUpdate()"> <source id="source-audio" src="" type="audio/mpeg"> </audio> <div class="player-ctn"> <div class="infos-ctn"> <div class="timer">00:00</div> <div class="player-title"></div> <div class="duration">00:00</div> </div> <div id="myProgress"> <div id="myBar"></div> </div> <div class="btn-ctn"> <div class="btn-action first-btn" onclick="previous()"> <div id="btn-faws-back"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M64 468V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12v176.4l195.5-181C352.1 22.3 384 36.6 384 64v384c0 27.4-31.9 41.7-52.5 24.6L136 292.7V468c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12z"/></svg> </div> </div> <div class="btn-action" onclick="rewind()"> <div id="btn-faws-rewind"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M11.5 280.6l192 160c20.6 17.2 52.5 2.8 52.5-24.6V96c0-27.4-31.9-41.8-52.5-24.6l-192 160c-15.3 12.8-15.3 36.4 0 49.2zm256 0l192 160c20.6 17.2 52.5 2.8 52.5-24.6V96c0-27.4-31.9-41.8-52.5-24.6l-192 160c-15.3 12.8-15.3 36.4 0 49.2z"/></svg> </div> </div> <div class="btn-action" onclick="toggleAudio()"> <div id="btn-faws-play-pause"> <span id="icon-play"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z"/></svg> </span> <span id="icon-pause" style="display: none"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M144 479H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h96c26.5 0 48 21.5 48 48v352c0 26.5-21.5 48-48 48zm304-48V79c0-26.5-21.5-48-48-48h-96c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h96c26.5 0 48-21.5 48-48z"/></svg> </span> </div> </div> <div class="btn-action" onclick="forward()"> <div id="btn-faws-forward"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M500.5 231.4l-192-160C287.9 54.3 256 68.6 256 96v320c0 27.4 31.9 41.8 52.5 24.6l192-160c15.3-12.8 15.3-36.4 0-49.2zm-256 0l-192-160C31.9 54.3 0 68.6 0 96v320c0 27.4 31.9 41.8 52.5 24.6l192-160c15.3-12.8 15.3-36.4 0-49.2z"/></svg> </div> </div> <div class="btn-action" onclick="next()"> <div id="btn-faws-next"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M384 44v424c0 6.6-5.4 12-12 12h-48c-6.6 0-12-5.4-12-12V291.6l-195.5 181C95.9 489.7 64 475.4 64 448V64c0-27.4 31.9-41.7 52.5-24.6L312 219.3V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12z"/></svg> </div> </div> <div class="btn-action btn-mute" id="toggleMute" onclick="toggleMute()"> <div id="btn-faws-volume"> <span id="icon-vol-up"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M215.03 71.05L126.06 160H24c-13.26 0-24 10.74-24 24v144c0 13.25 10.74 24 24 24h102.06l88.97 88.95c15.03 15.03 40.97 4.47 40.97-16.97V88.02c0-21.46-25.96-31.98-40.97-16.97zm233.32-51.08c-11.17-7.33-26.18-4.24-33.51 6.95-7.34 11.17-4.22 26.18 6.95 33.51 66.27 43.49 105.82 116.6 105.82 195.58 0 78.98-39.55 152.09-105.82 195.58-11.17 7.32-14.29 22.34-6.95 33.5 7.04 10.71 21.93 14.56 33.51 6.95C528.27 439.58 576 351.33 576 256S528.27 72.43 448.35 19.97zM480 256c0-63.53-32.06-121.94-85.77-156.24-11.19-7.14-26.03-3.82-33.12 7.46s-3.78 26.21 7.41 33.36C408.27 165.97 432 209.11 432 256s-23.73 90.03-63.48 115.42c-11.19 7.14-14.5 22.07-7.41 33.36 6.51 10.36 21.12 15.14 33.12 7.46C447.94 377.94 480 319.54 480 256zm-141.77-76.87c-11.58-6.33-26.19-2.16-32.61 9.45-6.39 11.61-2.16 26.2 9.45 32.61C327.98 228.28 336 241.63 336 256c0 14.38-8.02 27.72-20.92 34.81-11.61 6.41-15.84 21-9.45 32.61 6.43 11.66 21.05 15.8 32.61 9.45 28.23-15.55 45.77-45 45.77-76.88s-17.54-61.32-45.78-76.86z"/></svg> </span> <span id="icon-vol-mute" style="display: none"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M215.03 71.05L126.06 160H24c-13.26 0-24 10.74-24 24v144c0 13.25 10.74 24 24 24h102.06l88.97 88.95c15.03 15.03 40.97 4.47 40.97-16.97V88.02c0-21.46-25.96-31.98-40.97-16.97zM461.64 256l45.64-45.64c6.3-6.3 6.3-16.52 0-22.82l-22.82-22.82c-6.3-6.3-16.52-6.3-22.82 0L416 210.36l-45.64-45.64c-6.3-6.3-16.52-6.3-22.82 0l-22.82 22.82c-6.3 6.3-6.3 16.52 0 22.82L370.36 256l-45.63 45.63c-6.3 6.3-6.3 16.52 0 22.82l22.82 22.82c6.3 6.3 16.52 6.3 22.82 0L416 301.64l45.64 45.64c6.3 6.3 16.52 6.3 22.82 0l22.82-22.82c6.3-6.3 6.3-16.52 0-22.82L461.64 256z"/></svg> </span> </div> </div> </div> <div class="playlist-ctn"></div> </div> |
CSS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
.player-ctn { border-radius: 15px; border: 4px solid #BFE2FF; padding: 10px 16px; background-color: #337AB7; margin: 20px auto; max-width: 400px; font-size: 13px; line-height: 1.3; font-family: Verdana, sans-serif; box-shadow: 0 4px 12px rgba(0,0,0,0.2), 0 16px 20px rgba(0,0,0,0.1); position: relative; } .player-ctn:before, .player-ctn:after { position: absolute; color: #337AB7; font-size: 300px; font-family: 'Verdana', sans-serif; line-height: 100px; z-index: -1; text-shadow: 0 4px 12px rgba(0,0,0,0.2), 0 16px 20px rgba(0,0,0,0.1); } .player-ctn:before { content: '“'; left: -80px; top: 40px; } .player-ctn:after { content: '”'; right: -80px; top: 100%; } @media (max-width:767px){ .player-ctn:before, .player-ctn:after { display: none; } } .player-ctn .player-title { text-align: center; font-size: 16px; font-weight: 500; color: #FFF; font-family: 'Roboto', sans-serif; } .player-ctn .player-title span { display: block; font-size: 13px; } .btn-ctn, .infos-ctn { display: flex; align-items: center; justify-content: space-between; } .btn-ctn { justify-content: center; } #myProgress { background-color: #77abd9; cursor: pointer; border-radius: 10px; } #myBar { width: 0; height: 5px; background-color: #fff; border-radius: 10px; } .btn-action { cursor: pointer; padding-top: 10px; width: 30px; text-align: center; } .btn-action svg { fill: #BFE2FF; transition: 0.3s; width: 20px; height: 20px; } .btn-action:hover svg { fill: #fff; } .btn-ctn > div { padding: 5px; margin: 10px 0 2px; } .infos-ctn > div { margin-bottom: 8px; color: #BFE2FF; } .playlist-track-ctn { display: flex; background-color: #BFE2FF; margin: 6px 0; border-radius: 12px; cursor: pointer; justify-content: space-between; align-items: center; } .playlist-track-ctn > div { margin: 0 12px; } .playlist-info-track, .playlist-duration { padding: 7px 0; font-size: 14px; pointer-events: none; } .playlist-info-track span { display: block; font-size: 11px; } .active-track { background: #fff; } |
JS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
var listAudio = [ { name:"Жанна Григорьевна", desc: "г.Красноярск", file:"otz-1.mp3", duration:"01:36" }, { name:"Тамара Владимировна", desc: "Новосибирская обл. г. Куйбышев", file:"otz-2.mp3", duration:"02:09" }, { name:"Анастасия Геннадьевна", desc: "г.Иркутск", file:"otz-3.mp3", duration:"00:56" }, { name:"Анна Викторовна", desc: "г. Надым", file:"otz-4.mp3", duration:"1:45" } ] function createTrackItem(index,name,desc,duration){ var trackItem = document.createElement('div'); trackItem.setAttribute("class", "playlist-track-ctn"); trackItem.setAttribute("id", "ptc-"+index); trackItem.setAttribute("data-index", index); document.querySelector(".playlist-ctn").appendChild(trackItem); var trackInfoItem = document.createElement('div'); trackInfoItem.setAttribute("class", "playlist-info-track"); trackInfoItem.innerHTML = name; trackInfoItem.setAttribute("id", "p-img-"+index); document.querySelector("#ptc-"+index).appendChild(trackInfoItem); var trackDescItem = document.createElement('span'); trackDescItem.innerHTML = desc; document.querySelector("#p-img-"+index).appendChild(trackDescItem); var trackDurationItem = document.createElement('div'); trackDurationItem.setAttribute("class", "playlist-duration"); trackDurationItem.innerHTML = duration document.querySelector("#ptc-"+index).appendChild(trackDurationItem); document.querySelector("#ptc-0").classList.add("active-track"); } for (var i = 0; i < listAudio.length; i++) { createTrackItem(i,listAudio[i].name,listAudio[i].desc,listAudio[i].duration); } var indexAudio = 0; function loadNewTrack(index){ var player = document.querySelector('#source-audio') player.src = listAudio[index].file document.querySelector('.player-title').innerHTML = listAudio[index].name var descTitle = document.createElement('span'); descTitle.innerHTML = listAudio[index].desc; document.querySelector('.player-title').appendChild(descTitle); this.currentAudio = document.getElementById("myAudio"); this.currentAudio.load() this.toggleAudio() this.updateStylePlaylist(this.indexAudio,index) this.indexAudio = index; } var playListItems = document.querySelectorAll(".playlist-track-ctn"); for (let i = 0; i < playListItems.length; i++){ playListItems[i].addEventListener("click", getClickedElement.bind(this)); } function getClickedElement(event) { for (let i = 0; i < playListItems.length; i++){ if(playListItems[i] == event.target){ var clickedIndex = event.target.getAttribute("data-index") if (clickedIndex == this.indexAudio ) { this.toggleAudio() } else { loadNewTrack(clickedIndex); } } } } document.querySelector('#source-audio').src = listAudio[indexAudio].file document.querySelector('.player-title').innerHTML = listAudio[indexAudio].name var descTitle = document.createElement('span'); descTitle.innerHTML = listAudio[indexAudio].desc; document.querySelector('.player-title').appendChild(descTitle); var currentAudio = document.getElementById("myAudio"); currentAudio.load() currentAudio.onloadedmetadata = function() { document.getElementsByClassName('duration')[0].innerHTML = this.getMinutes(this.currentAudio.duration) }.bind(this); var interval1; function toggleAudio() { if (this.currentAudio.paused) { document.querySelector('#icon-play').style.display = 'none'; document.querySelector('#icon-pause').style.display = 'block'; document.querySelector('#ptc-'+this.indexAudio).classList.add("active-track"); this.currentAudio.play(); } else { document.querySelector('#icon-play').style.display = 'block'; document.querySelector('#icon-pause').style.display = 'none'; this.currentAudio.pause(); } } function pauseAudio() { this.currentAudio.pause(); clearInterval(interval1); } var timer = document.getElementsByClassName('timer')[0] var barProgress = document.getElementById("myBar"); var width = 0; function onTimeUpdate() { var t = this.currentAudio.currentTime timer.innerHTML = this.getMinutes(t); this.setBarProgress(); if ((this.currentAudio.ended) && (this.indexAudio < listAudio.length-1)) { var index = parseInt(this.indexAudio)+1 this.loadNewTrack(index) } } function setBarProgress(){ var progress = (this.currentAudio.currentTime/this.currentAudio.duration)*100; document.getElementById("myBar").style.width = progress + "%"; } function getMinutes(t){ var min = parseInt(parseInt(t)/60); var sec = parseInt(t%60); if (sec < 10) { sec = "0"+sec } if (min < 10) { min = "0"+min } return min+":"+sec } var progressbar = document.querySelector('#myProgress') progressbar.addEventListener("click", seek.bind(this)); function seek(event) { var percent = event.offsetX / progressbar.offsetWidth; this.currentAudio.currentTime = percent * this.currentAudio.duration; barProgress.style.width = percent*100 + "%"; } function forward(){ this.currentAudio.currentTime = this.currentAudio.currentTime + 5 this.setBarProgress(); } function rewind(){ this.currentAudio.currentTime = this.currentAudio.currentTime - 5 this.setBarProgress(); } function next(){ if (this.indexAudio <listAudio.length-1) { var oldIndex = this.indexAudio this.indexAudio++; updateStylePlaylist(oldIndex,this.indexAudio) this.loadNewTrack(this.indexAudio); } } function previous(){ if (this.indexAudio>0) { var oldIndex = this.indexAudio this.indexAudio--; updateStylePlaylist(oldIndex,this.indexAudio) this.loadNewTrack(this.indexAudio); } } function updateStylePlaylist(oldIndex,newIndex){ document.querySelector('#ptc-'+oldIndex).classList.remove("active-track"); document.querySelector('#ptc-'+newIndex).classList.add("active-track"); } function toggleMute(){ var btnMute = document.querySelector('#toggleMute'); var volUp = document.querySelector('#icon-vol-up'); var volMute = document.querySelector('#icon-vol-mute'); if (this.currentAudio.muted == false) { this.currentAudio.muted = true volUp.style.display = "none" volMute.style.display = "block" }else{ this.currentAudio.muted = false volMute.style.display = "none" volUp.style.display = "block" } } |
За основу взят плеер, найденный на codepen.io у пользователя Zakari Abdessamad
Отзывы с сайта kartiny-rus.ru
Нахватало ползунка громкости. Нейросетка мне доработала теперь красота. Как родной встал
Потоковое аудио играет: aacp, aac, mp3
На Tilda установится?