I'm trying to replicate this audio player:
https://medium.com/s/story/the-law-of-least-effort-is-the-success-secret-nobody-talks-about-c713eeab8ade)
with a grey progress line, but I can't seem to figure out the following 4 things:
How to put the progress bar next to the play/pause button?
How to have 2 decimals for the total time digit? (The 48 seconds)
How to have 2 decimals for the currentTimer? (First 9 seconds)
How to place the timers at the beginning and the end?
var barSize = 640;
var bar = document.getElementById('defaultBar');
var progressBar = document.getElementById('progressBar');
mytrack.addEventListener("loadedmetadata", function() {
var minutes = parseInt(mytrack.duration / 60);
var seconds = parseInt(mytrack.duration % 60);
duration.innerHTML = minutes + ':' + seconds;
})
duration.innerHTML = mytrack.duration;
playButton.addEventListener('click', playOrPause, false);
bar.addEventListener('click', clickedBar, false);
#progressBar {
position: absolute;
height: 2px;
background-color: #C6C6C6;
width: 0px;
float: left;
}
#playButton {
background-color: #FFFFFF;
border: none;
outline: none;
height: 60px;
width: 60px;
background-image: url(../Desktop/Play%20button.png);
background-repeat: no-repeat;
background-position: center;
}
#player {
background-color: #FFFFFF;
width: 400px;
margin-left: 300px;
padding: 5px;
box-sizing: border-box;
}
<div id="wrapper">
<audio id="mytrack">
<source src="file:///Users/Pier/Desktop/Narrated%20Story%20-%20Example.m4a" type="audio/mp3"/>
</audio>
<nav>
<div id="defaultBar">
<div id="progressBar"></div>
</div>
<div id="buttons">
<button type="button" id="playButton"></button>
<span id="currentTime">0:00</span>
<span id="fullDuration">0:00</span>
</div>
</nav>
</div>
The page you referenced uses flexbox for layout. You might consider a similar approach.
Below, I restructured your HTML and made each control element a flexbox item.
I also centered all items vertically with align-items:center.
var myTrack = document.getElementById('myTrack');
var progressBar = document.getElementById('progressBar');
var currentTime = document.getElementById('currentTime');
var fullDuration = document.getElementById('fullDuration');
function zeroPad(s) {
return ('00' + s).slice(-2);
}
function formatTime(t) {
var m = Math.floor(t / 60);
var s = Math.floor(t % 60);
return zeroPad(m) + ':' + zeroPad(s);
}
function playOrPause() {
myTrack.paused ? myTrack.play() : myTrack.pause();
}
myTrack.addEventListener("loadedmetadata", function() {
fullDuration.innerHTML = formatTime(this.duration);
});
myTrack.addEventListener("timeupdate", function() {
var thisTime = this.currentTime;
var duration = this.duration;
progressBar.style.width = thisTime / duration * 100 + '%';
currentTime.innerHTML = formatTime(thisTime);
});
playButton.addEventListener('click', playOrPause, false);
#audioControls {
display: flex;
align-items: center;
}
.controlTime {
margin: 0 1em;
}
#progressWrap {
/* Allow this element to grow */
flex: 1 0 auto;
border: 1px solid #EEE;
border-radius: 0.5em;
overflow: hidden;
}
#progressBar {
height: 0.5em;
background-color: #55AA55;
width: 0;
}
#playButton {
background-color: #FFFFFF;
border: 1px solid #CCC;
border-radius: 3px;
padding: 0.7em 1em;
outline: none;
cursor: pointer;
}
#playButton:hover {
background-color: darkgray;
color: white;
}
<div id="wrapper">
<audio id="myTrack">
<source src="https://example-files.online-convert.com/audio/m4a/example.m4a" type="audio/mp3"/>
</audio>
<nav id="audioControls">
<button type="button" id="playButton">play</button>
<span class="controlTime" id="currentTime">00:00</span>
<div id="progressWrap">
<div id="progressBar"></div>
</div>
<span class="controlTime" id="fullDuration">00:00</span>
</nav>
</div>
Related
I want to make a website with HTML, JAvascript and CSS,
There will be a number showing in the screen. THe user can decrement or increment the preset value using buttons.Start /stop button will start counting down from the shown number to zero. The page shows an alertbox when the number reaches zero. I know only html and css basics can anybody helpThis is a rough sketch
This may help get you started:
var intvl;
var valueContainer = document.getElementById("value");
document.getElementById("decrement").addEventListener("click", function(e){
var value = +valueContainer.textContent;
if(value){
valueContainer.textContent = value - 1;
}
});
document.getElementById("increment").addEventListener("click", function(e){
var value = +valueContainer.textContent;
valueContainer.textContent = value + 1;
});
document.getElementById("toggle").addEventListener("click", function(e){
if(intvl){
clearInterval(intvl);
} else {
var curr = +valueContainer.textContent;
intvl = setInterval(function(){
if(curr){
valueContainer.textContent = --curr;
} else {
clearInterval(intvl);
document.getElementById("messages").innerHTML = "Alert<br/>----------------<br/>Count reached 0!";
}
}, 1000);
}
});
document.getElementById("reset").addEventListener("click", function(e){
clearInterval(intvl);
valueContainer.textContent = 25;
document.getElementById("messages").innerHTML = "";
});
#messages {
text-align: center;
border: 1px solid grey;
width: 80%;
margin-bottom: 50px;
}
#wrapper {
text-align: center;
border: 1px solid grey;
display: inline-block;
width: 40%;
padding: 2px;
}
#wrapper > div {
display: inline-block;
}
body {
text-align: center;
}
#main > button, #controls > button {
border: 1px solid grey;
border-radius: 5px;
background-color: inherit;
padding: 2px 10px;
}
#controls {
margin-top: 10px;
}
<div id="wrapper">
<div id="messages">
</div>
<div id="main">
<button id="decrement">-</button>
<span id="value">25</span>
<button id="increment">+</button>
</div><br/>
<div id="controls">
<button id="toggle">Start/Stop</button>
<button id="reset">Reset</button>
</div>
</div>
I have created an audio player using javascript,
with the below Javascript, html, css I am getting expected result for one audio file in the HTML, when i add another audio file in the html, its not working.
Can you please anyone suggest how this can be handled for multiple audio files in the HTML?
Javascript
function calculateTotalValue(length) {
var minutes = Math.floor(length / 60),
seconds_int = length - minutes * 60,
seconds_str = seconds_int.toString(),
seconds = seconds_str.substr(0, 2),
time = minutes + ':' + seconds
return time;
}
function calculateCurrentValue(currentTime) {
var current_hour = parseInt(currentTime / 3600) % 24,
current_minute = parseInt(currentTime / 60) % 60,
current_seconds_long = currentTime % 60,
current_seconds = current_seconds_long.toFixed(),
current_time = (current_minute < 10 ? "0" + current_minute : current_minute) + ":" + (current_seconds < 10 ? "0" + current_seconds : current_seconds);
return current_time;
}
function initProgressBar() {
var player = document.getElementById('player');
var length = player.duration
var current_time = player.currentTime;
// calculate total length of value
var totalLength = calculateTotalValue(length)
jQuery(".end-time").html(totalLength);
// calculate current value time
var currentTime = calculateCurrentValue(current_time);
jQuery(".start-time").html(currentTime);
var progressbar = document.getElementById('seekObj');
progressbar.value = (player.currentTime / player.duration);
progressbar.addEventListener("click", seek);
if (player.currentTime == player.duration) {
$('#play-btn').removeClass('pause');
}
function seek(evt) {
var percent = evt.offsetX / this.offsetWidth;
player.currentTime = percent * player.duration;
progressbar.value = percent / 100;
}
};
function initPlayers(num) {
for (var i = 0; i < num; i++) {
(function() {
var playerContainer = document.getElementById('player-container'),
player = document.getElementById('player'),
isPlaying = false,
playBtn = document.getElementById('play-btn');
if (playBtn != null) {
playBtn.addEventListener('click', function() {
togglePlay()
});
}
// Controls & Sounds Methods
// ----------------------------------------------------------
function togglePlay() {
if (player.paused === false) {
player.pause();
isPlaying = false;
$('#play-btn').removeClass('pause');
} else {
player.play();
$('#play-btn').addClass('pause');
isPlaying = true;
}
}
}());
}
}
function muteAud(){
if (player.muted === false) {
player.muted = true;
$('#btn_muteUnmute').addClass('mute');
}
else
{
player.muted = false;
$('#btn_muteUnmute').removeClass('mute');
}
}
initPlayers(jQuery('#player-container').length);
Here is the HTML:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
<head>
<meta charset="utf-8"/>
<link rel="stylesheet" href="css/style.css"/>
</head>
<body>
<div class="audio-player">
<div id="play-btn"></div>
<div class="audio-wrapper" id="player-container">
<audio id="player" ontimeupdate="initProgressBar()">
<source
src="mmc03-01-9780128023198.mp3" type="audio/mp3"/></audio>
</div>
<div class="player-controls scrubber">
<div id="seekObjContainer">
<progress id="seekObj" value="0" max="1"></progress>
</div>
<small style="float: left; position: relative; left: 15px;" class="start-time"></small>
<small style="float: right; position: relative; right: 20px;" class="end-time"></small>
<div id="btn_muteUnmute"></div>
</div>
</div>
<script src="js/jquery.min.js"></script>
<script src="js/index.js"></script>
</body>
</html>
CSS:
html {
height: 100%;
display: table;
margin: auto;
}
body {
height: 100%;
display: table-cell;
vertical-align: middle;
}
.start-time
{
margin: 0rem 0rem 0 0rem;
}
.end-time
{
margin: 0rem 15rem 0 0rem;
}
.audio-player {
background: white;
width: 50vw;
text-align: center;
display: flex;
flex-flow: row;
margin: 4rem 0 4rem 0;
}
.audio-player .player-controls {
align-items: center;
justify-content: center;
margin-top: 2.5rem;
flex: 3;
}
.audio-player .player-controls progress {
width: 70%;
margin-left: -15.5rem;
}
.audio-player .player-controls progress[value] {
-webkit-appearance: none;
appearance: none;
background-color: white;
color: grey;
height: 6px;
}
.audio-player .player-controls progress[value]::-webkit-progress-bar {
background-color: #d3d3d3;
border-radius: 2px;
border: 1px solid #dfdfdf;
color: grey;
}
.audio-player .player-controls progress::-webkit-progress-value {
background-color: grey;
}
.audio-player .player-controls p {
font-size: 1.6rem;
}
.audio-player #play-btn {
background-image: url("../img/play.png");
background-size: cover;
width: 25px;
height: 25px;
margin: 2.7rem 0 2rem 2rem;
}
.audio-player #play-btn.pause {
background-image: url("../img/pause.png");
}
.audio-player #btn_muteUnmute {
background-image: url("../img/unmute.png");
background-size: cover;
width: 25px;
height: 25px;
margin: -1.9rem 0 2rem 48rem;
}
.audio-player #btn_muteUnmute.mute {
background-image: url("../img/mute.png");
}
html{font-size:10px;)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}
Here you id instead of class:
Change some of your code like this:
var playerContainer = document.querySelectorAll('.player-container'),
player = document.querySelectorAll('.player'),
isPlaying = false,
playBtn = document.querySelectorAll('.play-btn');
Note: You should loop through the element playerContainer, player and playBtn variable because querySelectorAll returns a list of Node.
Advice: if you use jQuery, use it for the selector.
I'm converting a player in html into a Vue component.
Half of the component is already created, only the time control slider is missing.
Here is the html player code (Lines with multiple tabs are already implemented in the Vue component):
var audioPlayer = document.querySelector('.green-audio-player');
var playPause = audioPlayer.querySelector('#playPause');
var playpauseBtn = audioPlayer.querySelector('.play-pause-btn');
var loading = audioPlayer.querySelector('.loading');
var progress = audioPlayer.querySelector('.progress');
var sliders = audioPlayer.querySelectorAll('.slider');
var player = audioPlayer.querySelector('audio');
var currentTime = audioPlayer.querySelector('.current-time');
var totalTime = audioPlayer.querySelector('.total-time');
var speaker = audioPlayer.querySelector('#speaker');
var draggableClasses = ['pin'];
var currentlyDragged = null;
window.addEventListener('mousedown', function(event) {
if(!isDraggable(event.target)) return false;
currentlyDragged = event.target;
let handleMethod = currentlyDragged.dataset.method;
this.addEventListener('mousemove', window[handleMethod], false);
window.addEventListener('mouseup', () => {
currentlyDragged = false;
window.removeEventListener('mousemove', window[handleMethod], false);
}, false);
});
playpauseBtn.addEventListener('click', togglePlay);
player.addEventListener('timeupdate', updateProgress);
player.addEventListener('loadedmetadata', () => {
totalTime.textContent = formatTime(player.duration);
});
player.addEventListener('canplay', makePlay);
player.addEventListener('ended', function(){
playPause.attributes.d.value = "M18 12L0 24V0";
player.currentTime = 0;
});
sliders.forEach(slider => {
let pin = slider.querySelector('.pin');
slider.addEventListener('click', window[pin.dataset.method]);
});
function isDraggable(el) {
let canDrag = false;
let classes = Array.from(el.classList);
draggableClasses.forEach(draggable => {
if(classes.indexOf(draggable) !== -1)
canDrag = true;
})
return canDrag;
}
function inRange(event) {
let rangeBox = getRangeBox(event);
let rect = rangeBox.getBoundingClientRect();
let direction = rangeBox.dataset.direction;
if(direction == 'horizontal') {
var min = rangeBox.offsetLeft;
var max = min + rangeBox.offsetWidth;
if(event.clientX < min || event.clientX > max) return false;
} else {
var min = rect.top;
var max = min + rangeBox.offsetHeight;
if(event.clientY < min || event.clientY > max) return false;
}
return true;
}
function updateProgress() {
var current = player.currentTime;
var percent = (current / player.duration) * 100;
progress.style.width = percent + '%';
currentTime.textContent = formatTime(current);
}
function getRangeBox(event) {
let rangeBox = event.target;
let el = currentlyDragged;
if(event.type == 'click' && isDraggable(event.target)) {
rangeBox = event.target.parentElement.parentElement;
}
if(event.type == 'mousemove') {
rangeBox = el.parentElement.parentElement;
}
return rangeBox;
}
function getCoefficient(event) {
let slider = getRangeBox(event);
let rect = slider.getBoundingClientRect();
let K = 0;
if(slider.dataset.direction == 'horizontal') {
let offsetX = event.clientX - slider.offsetLeft;
let width = slider.clientWidth;
K = offsetX / width;
} else if(slider.dataset.direction == 'vertical') {
let height = slider.clientHeight;
var offsetY = event.clientY - rect.top;
K = 1 - offsetY / height;
}
return K;
}
function rewind(event) {
if(inRange(event)) {
player.currentTime = player.duration * getCoefficient(event);
}
}
function formatTime(time) {
var min = Math.floor(time / 60);
var sec = Math.floor(time % 60);
return min + ':' + ((sec<10) ? ('0' + sec) : sec);
}
function togglePlay() {
if(player.paused) {
playPause.attributes.d.value = "M0 0h6v24H0zM12 0h6v24h-6z";
player.play();
} else {
playPause.attributes.d.value = "M18 12L0 24V0";
player.pause();
}
}
function makePlay() {
playpauseBtn.style.display = 'block';
loading.style.display = 'none';
}
.audio.green-audio-player {
width: 400px;
min-width: 300px;
height: 56px;
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.07);
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 24px;
padding-right: 24px;
border-radius: 4px;
user-select: none;
-webkit-user-select: none;
background-color: #fff;
}
.audio.green-audio-player .play-pause-btn {
display: none;
cursor: pointer;
}
.audio.green-audio-player .spinner {
width: 18px;
height: 18px;
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/loading.png);
background-size: cover;
background-repeat: no-repeat;
animation: spin 0.4s linear infinite;
}
.audio.green-audio-player .slider {
flex-grow: 1;
background-color: #D8D8D8;
cursor: pointer;
position: relative;
}
.audio.green-audio-player .slider .progress {
background-color: #44BFA3;
border-radius: inherit;
position: absolute;
pointer-events: none;
}
.audio.green-audio-player .slider .progress .pin {
height: 16px;
width: 16px;
border-radius: 8px;
background-color: #44BFA3;
position: absolute;
pointer-events: all;
box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.32);
}
.audio.green-audio-player .controls {
font-family: 'Roboto', sans-serif;
font-size: 16px;
line-height: 18px;
color: #55606E;
display: flex;
flex-grow: 1;
justify-content: space-between;
align-items: center;
margin-left: 24px;
}
.audio.green-audio-player .controls .slider {
margin-left: 16px;
margin-right: 16px;
border-radius: 2px;
height: 4px;
}
.audio.green-audio-player .controls .slider .progress {
width: 0;
height: 100%;
}
.audio.green-audio-player .controls .slider .progress .pin {
right: -8px;
top: -6px;
}
.audio.green-audio-player .controls span {
cursor: default;
}
svg, img {
display: block;
}
#keyframes spin {
from {
transform: rotateZ(0);
}
to {
transform: rotateZ(1turn);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div class="audio green-audio-player">
<div class="loading">
<div class="spinner"></div>
</div>
<div class="play-pause-btn">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="24" viewBox="0 0 18 24">
<path fill="#566574" fill-rule="evenodd" d="M18 12L0 24V0" class="play-pause-icon" id="playPause"/>
</svg>
</div>
<div class="controls">
<span class="current-time">0:00</span>
<div class="slider" data-direction="horizontal">
<div class="progress">
<div class="pin" id="progress-pin" data-method="rewind"></div>
</div>
</div>
<span class="total-time">0:00</span>
</div>
<audio>
<source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/Swing_Jazz_Drum.mp3" type="audio/mpeg">
</audio>
</div>
Html Codepen: https://codepen.io/caiokawasaki/pen/JwVwry
Here is the Vue component:
Vue.component('audio-player', {
props: ['message'],
data: () => ({
audio: undefined,
loaded: false,
playing: false,
currentTime: '00:00',
totalTime: '00:00',
percent: '0%',
draggableClasses: ['pin'],
currentlyDragged: null
}),
computed: {},
methods: {
formatTime(time) {
var min = Math.floor(time / 60);
var sec = Math.floor(time % 60);
return min + ':' + ((sec < 10) ? ('0' + sec) : sec);
},
loadedMetaData() {
this.totalTime = this.formatTime(this.audio.duration)
},
canPlay() {
this.loaded = true
},
timeUpdate(){
var current = this.audio.currentTime;
var percent = (current / this.audio.duration) * 100;
this.percent = percent + '%';
this.currentTime = this.formatTime(current);
},
ended(){
this.playing = false
this.audio.currentTime = 0
},
isDraggable(el) {
let canDrag = false;
let classes = Array.from(el.classList);
this.draggableClasses.forEach(draggable => {
if (classes.indexOf(draggable) !== -1)
canDrag = true;
})
return canDrag;
},
inRange(event) {
let rangeBox = getRangeBox(event);
let rect = rangeBox.getBoundingClientRect();
let direction = rangeBox.dataset.direction;
if (direction == 'horizontal') {
var min = rangeBox.offsetLeft;
var max = min + rangeBox.offsetWidth;
if (event.clientX < min || event.clientX > max) return false;
} else {
var min = rect.top;
var max = min + rangeBox.offsetHeight;
if (event.clientY < min || event.clientY > max) return false;
}
return true;
},
togglePlay() {
if (this.audio.paused) {
this.audio.play();
this.playing = true;
} else {
this.audio.pause();
this.playing = false;
}
},
makePlay() {
playpauseBtn.style.display = 'block';
loading.style.display = 'none';
},
getRangeBox(event) {
let rangeBox = event.target;
let el = currentlyDragged;
if (event.type == 'click' && isDraggable(event.target)) {
rangeBox = event.target.parentElement.parentElement;
}
if (event.type == 'mousemove') {
rangeBox = el.parentElement.parentElement;
}
return rangeBox;
},
getCoefficient(event) {
let slider = getRangeBox(event);
let rect = slider.getBoundingClientRect();
let K = 0;
if (slider.dataset.direction == 'horizontal') {
let offsetX = event.clientX - slider.offsetLeft;
let width = slider.clientWidth;
K = offsetX / width;
} else if (slider.dataset.direction == 'vertical') {
let height = slider.clientHeight;
var offsetY = event.clientY - rect.top;
K = 1 - offsetY / height;
}
return K;
},
rewind(event) {
if (this.inRange(event)) {
this.audio.currentTime = this.audio.duration * getCoefficient(event);
}
}
},
mounted() {
this.audio = this.$refs.audio
},
template: `<div class="audio-message-content">
<a v-if="loaded" class="play-pause-btn" href="#" :title="playing ? 'Clique aqui para pausar o audio' : 'Clique aqui ouvir o audio'" #click.prevent="togglePlay">
<svg key="pause" v-if="playing" x="0px" y="0px" viewBox="0 0 18 20" style="width: 18px; height: 20px; margin-top: -10px">
<path d="M17.1,20c0.49,0,0.9-0.43,0.9-0.96V0.96C18,0.43,17.6,0,17.1,0h-5.39c-0.49,0-0.9,0.43-0.9,0.96v18.07c0,0.53,0.4,0.96,0.9,0.96H17.1z M17.1,20"/>
<path d="M6.29,20c0.49,0,0.9-0.43,0.9-0.96V0.96C7.19,0.43,6.78,0,6.29,0H0.9C0.4,0,0,0.43,0,0.96v18.07C0,19.57,0.4,20,0.9,20H6.29z M6.29,20"/>
</svg>
<svg key="play" v-else x="0px" y="0px" viewBox="0 0 18 22" style="width: 18px; height: 22px; margin-top: -11px">
<path d="M17.45,10.01L1.61,0.14c-0.65-0.4-1.46,0.11-1.46,0.91V20.8c0,0.81,0.81,1.32,1.46,0.91l15.84-9.87C18.1,11.43,18.1,10.41,17.45,10.01L17.45,10.01z M17.45,10.01"/>
</svg>
</a>
<div v-else class="loading">
<div class="spinner"></div>
</div>
<div class="controls">
<span class="current-time">{{ currentTime }}</span>
<div class="slider" data-direction="horizontal" #click="">
<div class="progress" :style="{width: percent}">
<div class="pin" id="progress-pin" data-method="rewind"></div>
</div>
</div>
<span class="total-time">{{ totalTime }}</span>
</div>
<audio ref="audio" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/Swing_Jazz_Drum.mp3" #loadedmetadata="loadedMetaData" #canplay="canPlay" #timeupdate="timeUpdate" #ended="ended"></audio>
</div>`
})
var app = new Vue({
el: '#app'
})
.audio-message-content {
width: 400px;
min-width: 300px;
height: 56px;
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.07);
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 24px;
padding-right: 24px;
border-radius: 4px;
user-select: none;
-webkit-user-select: none;
background-color: #fff;
}
.audio-message-content .play-pause-btn {
position: relative;
width: 18px;
height: 22px;
cursor: pointer;
}
.audio-message-content .play-pause-btn svg {
display: block;
position: absolute;
top: 50%;
left: 50%;
margin-left: -9px;
}
.audio-message-content .spinner {
width: 18px;
height: 18px;
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/loading.png);
background-size: cover;
background-repeat: no-repeat;
animation: spin 0.4s linear infinite;
}
.audio-message-content .slider {
flex-grow: 1;
background-color: #D8D8D8;
cursor: pointer;
position: relative;
}
.audio-message-content .slider .progress {
background-color: #44BFA3;
border-radius: inherit;
position: absolute;
pointer-events: none;
}
.audio-message-content .slider .progress .pin {
height: 16px;
width: 16px;
border-radius: 8px;
background-color: #44BFA3;
position: absolute;
pointer-events: all;
box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.32);
}
.audio-message-content .controls {
font-family: 'Roboto', sans-serif;
font-size: 16px;
line-height: 18px;
color: #55606E;
display: flex;
flex-grow: 1;
justify-content: space-between;
align-items: center;
margin-left: 24px;
}
.audio-message-content .controls .slider {
margin-left: 16px;
margin-right: 16px;
border-radius: 2px;
height: 4px;
}
.audio-message-content .controls .slider .progress {
width: 0;
height: 100%;
}
.audio-message-content .controls .slider .progress .pin {
right: -8px;
top: -6px;
}
.audio-message-content .controls span {
cursor: default;
}
svg, img {
display: block;
}
#keyframes spin {
from {
transform: rotateZ(0);
}
to {
transform: rotateZ(1turn);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<audio-player></audio-player>
</div>
Vue Component Codepen: https://codepen.io/caiokawasaki/pen/QzRMwz
Functions like the following I could not understand nor find anything on the internet:
window[handleMethod]
window[pin.dataset.method]
Can anyone help me finalize this component?
Edit
I've converted all of the html and javascript into a Vue component but anyway it still is not working properly.
The only thing that is not working properly is the progress bar. It needs to perform two functions:
Clicking it should go to the desired time.
When clicking on the pin and drag it should go to the desired time.
I use Vue Cli, neither of the above two work in the form of .vue files, but in Codepen normally written only function 2 works.
Codepen: https://codepen.io/caiokawasaki/pen/VqOqBQ
The function: window[handleMethod] is executed by deriving the name of the method off of the data- property from the pin element:
<div class="pin" id="progress-pin" data-method="rewind"></div>
So window[handleMethod] is equivalent to window.rewind()
The same is true for window[pin.dataset.method].
So in your case:
this[handleMethod](event)
and:
this[pin.dataset.method](event)
Should be suitable replacements.
I have a pomodoro clock and I'm having problems with listeners for minBreak and plusBreak respectively. the plusWork minWork jquery listener work just fine, but for some reason the listeners for minBreak and plusBreak do not work. Could someone tell me why? here's the code (don't mind the design too much.. is not finished)
$(document).ready(function() {
//variables
var workTime = 2; //working time
var breakTime = 10; //break time
var seconds = 00;
var minutes = workTime; //setting clock = to workTime
var clockDisplay = document.getElementById("display");
var counterId = 0;
var state = "on";
//start clock whenc button clicked
$("#start").click(function() {
console.log("started!");
setInterval(countDown, 1000);
$(this).hide(); //hide start button
$("#stop").show(); //show stop button
});
//stop clock when stop clicked
$("#stop").click(function() {
console.log("stopped!");
state = "off";
minutes = workTime;
seconds = 0;
clockDisplay.innerHTML = workTime + ":00";
$(this).hide(); //hiding stop
$("#start").show(); //showing start
});
//add work time
$('.plusWork').click(function() {
workTime++;
$('.work').text(workTime);
console.log(workTime);
});
//substract work time
$('.minWork').click(function() {
workTime--;
$('.work').text(workTime);
console.log(workTime);
});
//add break time
$('.plusBreak').click(function() {
breakTime++;
$('.break').text(breakTime);
console.log(breakTime);
});
//substract break time
$('.minBreak').click(function() {
breakTime--;
$('.break').text(breakTime);
console.log(breakTime);
});
//countdown function
function countDown() {
//if workTime = 0 reset counter and stop
if (minutes == 0 || state == 'off') {
clearTimeout(counterId);
return;
}
//when seconds < 0 substract a minute
else if (seconds < 0) {
minutes--;
seconds = 59;
clockDisplay.innerHTML = minutes + ":" + seconds;
} else {
//if second single digit add 0
if (seconds < 10) seconds = "0" + seconds;
clockDisplay.innerHTML = minutes + ":" + seconds;
seconds--;
}
}
});
body {
background-color: #22313f;
;
}
.title {
margin: auto;
text-align: center;
font-size: 30px;
}
.container {
text-align: center;
}
h2 {
font-size: 50px;
margin: 0 0 0 0;
}
.clockContainer {
position: relative;
text-align: center;
}
#display {}
/* .timer {
margin: 0 50px;
margin-top: 70px;
text-align: center;
border: solid black 1px;
font-size: 44px;
width: 500px;
height: 200px;
display: inline-block;
} */
.controlContainer {
position: absolute;
text-align: center;
width: 100px;
display: inline-block;
}
.control {
width: 100px;
height: 100px;
border-radius: 100px;
border: solid black 1px;
text-align: center;
margin-bottom: 20px;
}
.button {
margin-top: 30px;
}
.hide {
display: none;
}
.time {
margin-top: 5px;
margin-bottom: 5px;
font-size: 20px;
}
.ticker {
display: inline-block;
font-size: 30px;
margin-top: 0px;
}
.minus {
margin-right: 10px;
}
.plus {
margin-left: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container">
<!-- header title -->
<div class="title primary-text">
<h1>Pomodoro Clock</h1>
</div>
<!-- clock container -->
<div class="clockContainer">
<h2>Session</h2>
<!-- timer / clock -->
<div class="timer">
<h1 id="display">30:00</h1>
</div>
<!-- this section for controlling clock -->
<div class="controlContainer">
<div class="control">
<div id="start" class="button title">Start</div>
<div id="stop" class="button hide title">Stop</div>
</div>
<div class="control">
<h3 class="time work">30</h3>
<h3 class="title">Work</h3>
<h3 class="minWork ticker minus">-</h3>
<h3 class="plusWork ticker plus">+</h3>
</div>
<div class="control">
<h3 class="time break">10</h3>
<h3 class="title">Break</h3>
<h3 class="minBrake ticker minus">-</h3>
<h3 class="plusBrake ticker plus">+</h3>
</div>
</div>
</div>
</div>
You have typo in h3 class:
<h3 class="minBrake ticker minus">-</h3>
<h3 class="plusBrake ticker plus">+</h3>
Should be:
<h3 class="minBreak ticker minus">-</h3>
<h3 class="plusBreak ticker plus">+</h3>
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Click this link:
The first prt scr you can see play and mute buttons.
Click this link:
The second prt scr I can't see background image, but still javascript working!
Where is it gone my background image? How can I remove "element" property?
element {
background: transparent url("../images/unmute.png") repeat scroll 0% 0%;
}
button#mutebtn {
background: transparent url("../images/unmute.png") repeat scroll 0% 0%;
}
This is how you can remove an attribute by JQuery:
element.removeAttribute(attributename)
check this link for more info.
If you add inline style to #mutebtn in the HTML, it will appear as element{} in the inspector.
Check your HTML, and if you need to use the inline style like this:
<button id="mutebtn" style="background...."></button>
Be careful with the URL of the background attribute, which appears to be fine from the CSS file, but from the HTML file I suppose it should be a different path, usually without the initial "../".
In other words, remove the inline style in your HTML, or change the path there to: "images/unmute.png"
var vid, playbtn, seekslider, curtimetext, durtimetext, mutebtn, volumeslider, fullscreenbtn;
function intializePlayer(){
// Set object references
vid = document.getElementById("my_video");
playbtn = document.getElementById("playpausebtn");
seekslider = document.getElementById("seekslider");
curtimetext = document.getElementById("curtimetext");
durtimetext = document.getElementById("durtimetext");
mutebtn = document.getElementById("mutebtn");
volumeslider = document.getElementById("volumeslider");
fullscreenbtn = document.getElementById("fullscreenbtn");
// Add event listeners
vid.addEventListener("timeupdate",seektimeupdate,false);
playbtn.addEventListener("click",playPause,false);
mutebtn.addEventListener("click",vidmute,false);
fullscreenbtn.addEventListener("click",toggleFullScreen,false);
seekslider.addEventListener("change",vidSeek,false);
vid.addEventListener("timeupdate",seektimeupdate,false);
volumeslider.addEventListener("change",setvolume,false);
}
window.onload = intializePlayer;
function playPause(){
if(vid.paused){
vid.play();
playbtn.style.background = "url(../images/pause.png)";
} else {
vid.pause();
playbtn.style.background = "url(../images/play.png)";
}
}
function vidmute(){
if(vid.muted){
vid.muted = false;
mutebtn.style.background = "url(../images/mute.png)";
} else {
vid.muted = true;
mutebtn.style.background = "url(../images/unmute.png)";
}
}
function vidSeek(){
var seekto = vid.duration * (seekslider.value / 100);
vid.currentTime = seekto;
}
function seektimeupdate(){
var nt = vid.currentTime * (100 / vid.duration);
seekslider.value = nt;
var curmins = Math.floor(vid.currentTime / 60);
var cursecs = Math.floor(vid.currentTime - curmins * 60);
var durmins = Math.floor(vid.duration / 60);
var dursecs = Math.floor(vid.duration - durmins * 60);
if(cursecs < 10){ cursecs = "0"+cursecs; }
if(dursecs < 10){ dursecs = "0"+dursecs; }
if(curmins < 10){ curmins = "0"+curmins; }
if(durmins < 10){ durmins = "0"+durmins; }
curtimetext.innerHTML = curmins+":"+cursecs;
durtimetext.innerHTML = durmins+":"+dursecs;
}
function setvolume(){
vid.volume = volumeslider.value / 100;
}
function toggleFullScreen(){
if(vid.requestFullScreen){
vid.requestFullScreen();
} else if(vid.webkitRequestFullScreen){
vid.webkitRequestFullScreen();
} else if(vid.mozRequestFullScreen){
vid.mozRequestFullScreen();
}
}
playbtn.style.background = "url(../images/pause.png)";
playbtn.style.background = "url(../images/play.png)";
div#video_player_box {
width: 100%;
background: #000;
}
div#video_controls_bar {
padding: 10px;
color: #CCC;
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
width: 100%;
}
button#playpausebtn {
background: url(../images/pause.png);
width: 30px;
height: 30px;
display: inline-block;
border: 0px none;
cursor: pointer;
opacity: 0.5;
}
button#playpausebtn:hover {
opacity: 1;
}
input#seekslider {
display: inline-block;
width: 100%;
padding: 2px;
}
input#volumeslider {
display: inline-block;
width: 80px;
padding: 2px;
}
button#mutebtn {
background:url(../images/unmute.png);
width: 30px;
height: 30px;
border: 0px none;
cursor: pointer;
opacity: 0.5;
/*--style text button
font-weight: bold;
padding: 0.5em;
border-radius: 15px;
border: 1px solid #A7A7A7;
background-color: #068EA2;
background-image: -moz-linear-gradient(center bottom, #BABABA 1%, #FFF 20%);--*/
}
button#mutebtn:hover {
opacity: 1;
}
button#fullscreenbtn {
background: url(../images/fullscreen.png);
width: 30px;
height: 30px;
border: 0px none;
cursor: pointer;
opacity: 0.5;
float:right;
/*--style text button
font-weight: bold;
padding: 0.5em;
border-radius: 15px;
border: 1px solid #A7A7A7;
background-color: #068EA2;
background-image: -moz-linear-gradient(center bottom, #BABABA 1%, #FFF 20%);--*/
}
button#fullscreenbtn {
opacity: 1;
}
input[type='range'] {
-webkit-appearance: none !important;
background: #000;
border: #666 1px solid;
height: 2px;
}
input[type='range']::-webkit-slider-thumb {
-webkit-appearance: none !important;
background: #FFF;
height:10px;
width:10px;
border-radius:100%;
cursor:pointer;
}
<div id="video_player_box">
<video id="my_video" autoplay>
<source src="media/echo-hereweare.mp4">
</video>
<div id="video_controls_bar">
<input id="seekslider" type="range" min="0" max="100" value="0" step="1">
<button id="playpausebtn"></button>
<button id="mutebtn"></button>
<input id="volumeslider" type="range" min="0" max="100" value="50" step="1">
<span id="curtimetext"></span> / <span id="durtimetext">
</span><button id="fullscreenbtn">[ ]</button>
</div>
<!--end video_controls_bar -->
</div>
<!--end video_player_box -->
You have 2 options:
Make use of the !important in you css file:
button#mutebtn {
background: transparent url("../images/unmute.png") repeat scroll 0% 0% !important;
}
(It's considered best practice to avoid !important as much as possible.)
Or go to your html page, find the correct line and remove the css background there.
Note: you can't reach element in your stylesheet. This is css that is direct/inline implemented in your html file.
I made a example for you, check this fiddle!