first commit with existing project files
This commit is contained in:
50
1-HTMLMediaElement V2/Playlist.js
Normal file
50
1-HTMLMediaElement V2/Playlist.js
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
export class Playlist {
|
||||||
|
constructor() {
|
||||||
|
this._tracks = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
get tracks() {
|
||||||
|
return this._tracks;
|
||||||
|
}
|
||||||
|
|
||||||
|
addTrack(track) {
|
||||||
|
this._tracks.push(track);
|
||||||
|
|
||||||
|
const div = document.createElement('div');
|
||||||
|
|
||||||
|
div.classList.add('d-flex');
|
||||||
|
div.classList.add('align-items-center');
|
||||||
|
div.classList.add('justify-content-between');
|
||||||
|
|
||||||
|
const deleteBtn = document.createElement('button');
|
||||||
|
deleteBtn.innerHTML = `<i class="bi bi-trash"></i>`;
|
||||||
|
deleteBtn.classList.add("btn");
|
||||||
|
deleteBtn.classList.add("btn-danger");
|
||||||
|
deleteBtn.classList.add("col-md-1");
|
||||||
|
deleteBtn.style.marginRight = "10px";
|
||||||
|
deleteBtn.addEventListener('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
this._tracks.splice(this._tracks.indexOf(track), 1);
|
||||||
|
div.remove();
|
||||||
|
});
|
||||||
|
div.appendChild(deleteBtn);
|
||||||
|
const li = document.createElement('li');
|
||||||
|
li.classList.add("card");
|
||||||
|
li.classList.add("shadow-sm");
|
||||||
|
li.classList.add("p-4");
|
||||||
|
li.classList.add("col-md-11");
|
||||||
|
li.textContent = track.name;
|
||||||
|
li.style.margin = "5px 0";
|
||||||
|
|
||||||
|
div.appendChild(li);
|
||||||
|
|
||||||
|
div.setAttribute('id', this._tracks.indexOf(track).toString());
|
||||||
|
div.setAttribute('draggable', 'true');
|
||||||
|
|
||||||
|
div.addEventListener('dragstart', (e) => {
|
||||||
|
e.dataTransfer.setData('text/plain', e.target.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
return div;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
1-HTMLMediaElement V2/Track.js
Normal file
22
1-HTMLMediaElement V2/Track.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
export class Track {
|
||||||
|
constructor(name, url) {
|
||||||
|
this.name = name;
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return this._name;
|
||||||
|
}
|
||||||
|
|
||||||
|
set name(value) {
|
||||||
|
this._name = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get url() {
|
||||||
|
return this._url;
|
||||||
|
}
|
||||||
|
|
||||||
|
set url(value) {
|
||||||
|
this._url = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
102
1-HTMLMediaElement V2/app.js
Normal file
102
1-HTMLMediaElement V2/app.js
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
import { Track } from './Track.js';
|
||||||
|
import { Playlist } from './Playlist.js';
|
||||||
|
|
||||||
|
const audio = document.getElementById('audioPlayer');
|
||||||
|
|
||||||
|
const playBtn = document.getElementById('playBtn');
|
||||||
|
const pauseBtn = document.getElementById('pauseBtn');
|
||||||
|
const resetBtn = document.getElementById('resetBtn');
|
||||||
|
|
||||||
|
const currentTimeSpan = document.getElementById('currentTime');
|
||||||
|
const totalTimeSpan = document.getElementById('totalTime');
|
||||||
|
|
||||||
|
const fileInput = document.getElementById('fileInput');
|
||||||
|
const loadFileBtn = document.getElementById('loadFileBtn');
|
||||||
|
|
||||||
|
const volume = document.getElementById('volume-slider');
|
||||||
|
|
||||||
|
const mediaInfo = document.querySelector('.media-info');
|
||||||
|
|
||||||
|
let timer = null;
|
||||||
|
|
||||||
|
let fileName;
|
||||||
|
let audioSrc;
|
||||||
|
|
||||||
|
let playlistElement = document.getElementById('playlist');
|
||||||
|
|
||||||
|
let playlist = new Playlist();
|
||||||
|
|
||||||
|
/* Functions */
|
||||||
|
|
||||||
|
function toReadableTime(seconds) {
|
||||||
|
return new Date(seconds * 1000).toISOString().substring(14, 19);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTime() {
|
||||||
|
currentTimeSpan.textContent = toReadableTime(audio.currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileInput.addEventListener('change', (event) => {
|
||||||
|
const file = event.target.files[0];
|
||||||
|
if (file) {
|
||||||
|
audioSrc = URL.createObjectURL(file);
|
||||||
|
fileName = file.name.split('.mp3')[0];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Events */
|
||||||
|
|
||||||
|
loadFileBtn.addEventListener('click', () => {
|
||||||
|
const track = new Track(fileName, audioSrc);
|
||||||
|
playlistElement.appendChild(playlist.addTrack(track, playlistElement));
|
||||||
|
});
|
||||||
|
|
||||||
|
audio.addEventListener('loadedmetadata', () => {
|
||||||
|
totalTimeSpan.textContent = toReadableTime(audio.duration);
|
||||||
|
});
|
||||||
|
|
||||||
|
playBtn.addEventListener('click', () => {
|
||||||
|
|
||||||
|
audio.src = audioSrc;
|
||||||
|
audio.load();
|
||||||
|
mediaInfo.innerText = fileName;
|
||||||
|
updateTime();
|
||||||
|
|
||||||
|
audio.play();
|
||||||
|
if (!timer) {
|
||||||
|
timer = setInterval(updateTime, 500);
|
||||||
|
}
|
||||||
|
document.title = `Playing ${fileName}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
pauseBtn.addEventListener('click', () => {
|
||||||
|
audio.pause();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (audio.play()) {
|
||||||
|
|
||||||
|
resetBtn.addEventListener('click', () => {
|
||||||
|
audio.pause();
|
||||||
|
audio.currentTime = 0;
|
||||||
|
updateTime();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
audio.addEventListener('ended', () => {
|
||||||
|
clearInterval(timer);
|
||||||
|
timer = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
audio.addEventListener('pause', () => {
|
||||||
|
clearInterval(timer);
|
||||||
|
timer = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
volume.addEventListener("input", function (e) {
|
||||||
|
audio.volume = e.currentTarget.value / 100;
|
||||||
|
});
|
||||||
|
|
||||||
|
volume.addEventListener("dblclick", function (e) {
|
||||||
|
audio.volume = 0.5;
|
||||||
|
e.currentTarget.value = 50;
|
||||||
|
});
|
||||||
55
1-HTMLMediaElement V2/index.html
Normal file
55
1-HTMLMediaElement V2/index.html
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Lecteur Audio HTML5</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.1/font/bootstrap-icons.min.css">
|
||||||
|
<script type="module" src="app.js" defer></script>
|
||||||
|
</head>
|
||||||
|
<body class="bg-light py-5">
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="mb-4 text-center">Lecteur Audio</h1>
|
||||||
|
|
||||||
|
<div class="card shadow-sm p-4">
|
||||||
|
<audio id="audioPlayer" src=""></audio>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-center align-items-center">
|
||||||
|
<h4 class="media-info">Aucun fichier chargé</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-center gap-3 mb-3">
|
||||||
|
<button id="playBtn" class="btn btn-primary"><i class="bi bi-play-circle"></i></button>
|
||||||
|
<button id="pauseBtn" class="btn btn-warning"><i class="bi bi-pause-circle"></i></button>
|
||||||
|
<button id="resetBtn" class="btn btn-danger"><i class="bi bi-arrow-counterclockwise"></i></button>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex justify-content-center align-items-center mb-3">
|
||||||
|
<input type="range" id="volume-slider">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
Temps écoulé : <span id="currentTime">00.00</span> / <span id="totalTime">00.00</span> sec
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="card shadow-sm p-4">
|
||||||
|
<input type="file" id="fileInput" accept="audio/*" class="form-control mb-3">
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<button id="loadFileBtn" class="btn btn-secondary">Ajouter à la playlist</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="card shadow-sm p-4">
|
||||||
|
<h4 class="mb-3">Playlist</h4>
|
||||||
|
<ul id="playlist">
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
88
1-HTMLMediaElement/app.js
Normal file
88
1-HTMLMediaElement/app.js
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
const audio = document.getElementById('audioPlayer');
|
||||||
|
|
||||||
|
const playBtn = document.getElementById('playBtn');
|
||||||
|
const pauseBtn = document.getElementById('pauseBtn');
|
||||||
|
const resetBtn = document.getElementById('resetBtn');
|
||||||
|
|
||||||
|
const currentTimeSpan = document.getElementById('currentTime');
|
||||||
|
const totalTimeSpan = document.getElementById('totalTime');
|
||||||
|
|
||||||
|
const fileInput = document.getElementById('fileInput');
|
||||||
|
const loadFileBtn = document.getElementById('loadFileBtn');
|
||||||
|
|
||||||
|
const volume = document.getElementById('volume-slider');
|
||||||
|
|
||||||
|
const mediaInfo = document.querySelector('.media-info');
|
||||||
|
|
||||||
|
let timer = null;
|
||||||
|
|
||||||
|
let fileName;
|
||||||
|
let audioSrc;
|
||||||
|
|
||||||
|
/* Functions */
|
||||||
|
|
||||||
|
function toReadableTime(seconds) {
|
||||||
|
return new Date(seconds * 1000).toISOString().substring(14, 19);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTime() {
|
||||||
|
currentTimeSpan.textContent = toReadableTime(audio.currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileInput.addEventListener('change', (event) => {
|
||||||
|
const file = event.target.files[0];
|
||||||
|
if (file) {
|
||||||
|
audioSrc = URL.createObjectURL(file);
|
||||||
|
fileName = file.name.split('.mp3')[0];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Events */
|
||||||
|
|
||||||
|
loadFileBtn.addEventListener('click', () => {
|
||||||
|
audio.src = audioSrc;
|
||||||
|
audio.load();
|
||||||
|
mediaInfo.innerText = fileName;
|
||||||
|
updateTime();
|
||||||
|
});
|
||||||
|
|
||||||
|
audio.addEventListener('loadedmetadata', () => {
|
||||||
|
totalTimeSpan.textContent = toReadableTime(audio.duration);
|
||||||
|
});
|
||||||
|
|
||||||
|
playBtn.addEventListener('click', () => {
|
||||||
|
audio.play();
|
||||||
|
if (!timer) {
|
||||||
|
timer = setInterval(updateTime, 500);
|
||||||
|
}
|
||||||
|
document.title = `Playing ${fileName}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
pauseBtn.addEventListener('click', () => {
|
||||||
|
audio.pause();
|
||||||
|
});
|
||||||
|
|
||||||
|
resetBtn.addEventListener('click', () => {
|
||||||
|
audio.pause();
|
||||||
|
audio.currentTime = 0;
|
||||||
|
updateTime();
|
||||||
|
});
|
||||||
|
|
||||||
|
audio.addEventListener('ended', () => {
|
||||||
|
clearInterval(timer);
|
||||||
|
timer = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
audio.addEventListener('pause', () => {
|
||||||
|
clearInterval(timer);
|
||||||
|
timer = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
volume.addEventListener("input", function (e) {
|
||||||
|
audio.volume = e.currentTarget.value / 100;
|
||||||
|
});
|
||||||
|
|
||||||
|
volume.addEventListener("dblclick", function (e) {
|
||||||
|
audio.volume = 0.5;
|
||||||
|
e.currentTarget.value = 50;
|
||||||
|
});
|
||||||
47
1-HTMLMediaElement/index.html
Normal file
47
1-HTMLMediaElement/index.html
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Lecteur Audio HTML5</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.1/font/bootstrap-icons.min.css">
|
||||||
|
<script src="app.js" defer></script>
|
||||||
|
</head>
|
||||||
|
<body class="bg-light py-5">
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="mb-4 text-center">Lecteur Audio</h1>
|
||||||
|
|
||||||
|
<div class="card shadow-sm p-4">
|
||||||
|
<audio id="audioPlayer" src=""></audio>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-center align-items-center">
|
||||||
|
<h4 class="media-info">Aucun fichier chargé</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-center gap-3 mb-3">
|
||||||
|
<button id="playBtn" class="btn btn-primary"><i class="bi bi-play-circle"></i></button>
|
||||||
|
<button id="pauseBtn" class="btn btn-warning"><i class="bi bi-pause-circle"></i></button>
|
||||||
|
<button id="resetBtn" class="btn btn-danger"><i class="bi bi-arrow-counterclockwise"></i></button>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex justify-content-center align-items-center mb-3">
|
||||||
|
<input type="range" id="volume-slider">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
Temps écoulé : <span id="currentTime">00.00</span> / <span id="totalTime">00.00</span> sec
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="card shadow-sm p-4">
|
||||||
|
<input type="file" id="fileInput" accept="audio/*" class="form-control mb-3">
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<button id="loadFileBtn" class="btn btn-secondary">Charger un fichier audio</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
33
4-Geolocation/app.js
Normal file
33
4-Geolocation/app.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
const options = {
|
||||||
|
enableHighAccuracy: true,
|
||||||
|
timeout: 5000,
|
||||||
|
maximumAge: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
function success(pos) {
|
||||||
|
localStorage.setItem('position',
|
||||||
|
JSON.stringify(pos.coords)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function error(err) {
|
||||||
|
console.warn(`ERROR(${err.code}): ${err.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
navigator.geolocation.getCurrentPosition(success, error, options);
|
||||||
|
|
||||||
|
const getCoordinates = () => {
|
||||||
|
const parsed = JSON.parse(localStorage.getItem('position'));
|
||||||
|
return {
|
||||||
|
latitude: parsed.latitude,
|
||||||
|
longitude: parsed.longitude,
|
||||||
|
accuracy: parsed.accuracy,
|
||||||
|
altitude: parsed.altitude,
|
||||||
|
altitudeAccuracy: parsed.altitudeAccuracy,
|
||||||
|
heading: parsed.heading,
|
||||||
|
speed: parsed.speed
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Latitude: ${getCoordinates().latitude}, Longitude: ${getCoordinates().longitude}
|
||||||
|
Accuracy: ${getCoordinates().accuracy.toFixed()} meters`);
|
||||||
15
4-Geolocation/index.html
Normal file
15
4-Geolocation/index.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<script src="app.js" defer></script>
|
||||||
|
<title>Document</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user