├── README.md
├── app.js
├── index.html
├── sounds
├── beach.mp3
└── rain.mp3
├── style.css
├── svg
├── beach.svg
├── moving-outline.svg
├── pause.svg
├── play.svg
├── rain.svg
├── replay.svg
└── track-outline.svg
└── video
├── beach.mp4
└── rain.mp4
/README.md:
--------------------------------------------------------------------------------
1 | # meditation-app
2 | Meditation app tutorial
3 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | const song = document.querySelector(".song");
2 | const play = document.querySelector(".play");
3 | const replay = document.querySelector(".replay");
4 | const outline = document.querySelector(".moving-outline circle");
5 | const video = document.querySelector(".vid-container video");
6 | //Sounds
7 | const sounds = document.querySelectorAll(".sound-picker button");
8 | //Time Display
9 | const timeDisplay = document.querySelector(".time-display");
10 | const outlineLength = outline.getTotalLength();
11 | //Duration
12 | const timeSelect = document.querySelectorAll(".time-select button");
13 | let fakeDuration = 600;
14 |
15 | outline.style.strokeDashoffset = outlineLength;
16 | outline.style.strokeDasharray = outlineLength;
17 | timeDisplay.textContent = `${Math.floor(fakeDuration / 60)}:${Math.floor(
18 | fakeDuration % 60
19 | )}`;
20 |
21 | sounds.forEach(sound => {
22 | sound.addEventListener("click", function() {
23 | song.src = this.getAttribute("data-sound");
24 | video.src = this.getAttribute("data-video");
25 | checkPlaying(song);
26 | });
27 | });
28 |
29 | play.addEventListener("click", function() {
30 | checkPlaying(song);
31 | });
32 |
33 | replay.addEventListener("click", function() {
34 | restartSong(song);
35 |
36 | });
37 |
38 |
39 | const restartSong = song =>{
40 | let currentTime = song.currentTime;
41 | song.currentTime = 0;
42 | console.log("ciao")
43 |
44 | }
45 |
46 | timeSelect.forEach(option => {
47 | option.addEventListener("click", function() {
48 | fakeDuration = this.getAttribute("data-time");
49 | timeDisplay.textContent = `${Math.floor(fakeDuration / 60)}:${Math.floor(
50 | fakeDuration % 60
51 | )}`;
52 | });
53 | });
54 |
55 | const checkPlaying = song => {
56 | if (song.paused) {
57 | song.play();
58 | video.play();
59 | play.src = "./svg/pause.svg";
60 | } else {
61 | song.pause();
62 | video.pause();
63 | play.src = "./svg/play.svg";
64 | }
65 | };
66 |
67 | song.ontimeupdate = function() {
68 | let currentTime = song.currentTime;
69 | let elapsed = fakeDuration - currentTime;
70 | let seconds = Math.floor(elapsed % 60);
71 | let minutes = Math.floor(elapsed / 60);
72 | timeDisplay.textContent = `${minutes}:${seconds}`;
73 | let progress = outlineLength - (currentTime / fakeDuration) * outlineLength;
74 | outline.style.strokeDashoffset = progress;
75 |
76 | if (currentTime >= fakeDuration) {
77 | song.pause();
78 | song.currentTime = 0;
79 | play.src = "./svg/play.svg";
80 | video.pause();
81 | }
82 | };
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Audio App
10 |
11 |
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
27 |

28 |
31 |
34 |

35 |
36 |
0:00
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/sounds/beach.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/developedbyed/meditation-app/ecac767b7b2bf4c11249a32748093cc373a218bb/sounds/beach.mp3
--------------------------------------------------------------------------------
/sounds/rain.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/developedbyed/meditation-app/ecac767b7b2bf4c11249a32748093cc373a218bb/sounds/rain.mp3
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | box-sizing: border-box;
5 | }
6 |
7 | .app {
8 | height: 100vh;
9 | display: flex;
10 | justify-content: space-evenly;
11 | align-items: center;
12 | font-family: "Montserrat", sans-serif;
13 | }
14 |
15 | .time-select,
16 | .sound-picker {
17 | height: 80%;
18 | display: flex;
19 | justify-content: space-evenly;
20 | align-items: center;
21 | flex-direction: column;
22 | flex: 1;
23 | }
24 | .time-select button,
25 | .sound-picker button {
26 | color: white;
27 | width: 30%;
28 | height: 10%;
29 | background: none;
30 | font-size: 20px;
31 | border-radius: 5px;
32 | cursor: pointer;
33 | border: 2px solid white;
34 | transition: all 0.5s ease;
35 | }
36 |
37 | .sound-picker button {
38 | border: none;
39 | height: 120px;
40 | width: 120px;
41 | padding: 30px;
42 | border-radius: 50%;
43 | }
44 | .sound-picker button:nth-child(1) {
45 | background: #4972a1;
46 | }
47 | .sound-picker button:nth-child(2) {
48 | background: #a14f49;
49 | }
50 | .sound-picker button img {
51 | height: 100%;
52 | }
53 |
54 | .time-select button:hover {
55 | background: white;
56 | color: black;
57 | }
58 |
59 | .player-container {
60 | position: relative;
61 | height: 80%;
62 | display: flex;
63 | justify-content: space-evenly;
64 | align-items: center;
65 | flex-direction: column;
66 | flex: 1;
67 | }
68 |
69 | .player-container svg {
70 | position: absolute;
71 | height: 50%;
72 | top: 50%;
73 | left: 50%;
74 | transform: translate(-50%, -50%) rotate(-90deg);
75 | pointer-events: none;
76 | }
77 | .player-container svg circle {
78 | transition: all 0.2s ease-in-out;
79 | }
80 | .time-display {
81 | color: white;
82 | position: absolute;
83 | font-size: 50px;
84 | bottom: 10%;
85 | }
86 |
87 | video {
88 | position: fixed;
89 | top: 0%;
90 | left: 0%;
91 | width: 100%;
92 | z-index: -10;
93 | }
94 |
--------------------------------------------------------------------------------
/svg/beach.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/svg/moving-outline.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/svg/pause.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/svg/play.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/svg/rain.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/svg/replay.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/svg/track-outline.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/video/beach.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/developedbyed/meditation-app/ecac767b7b2bf4c11249a32748093cc373a218bb/video/beach.mp4
--------------------------------------------------------------------------------
/video/rain.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/developedbyed/meditation-app/ecac767b7b2bf4c11249a32748093cc373a218bb/video/rain.mp4
--------------------------------------------------------------------------------