Learn how to create a responsive dashboard with interactive sliders and a music player using HTML, CSS, and JavaScript. Step-by-step tutorial included.
Table of Contents
Creating a dashboard that combines interactive elements like sliders and a music player can enhance user experience significantly. This tutorial will guide you through building a responsive and feature-rich dashboard using HTML, CSS, and JavaScript. By the end of this guide, you'll have a functional dashboard that is both visually appealing and highly interactive.
Source Code
Step 1 (HTML Code):
Before we dive into coding, let's set up our project environment. Start by creating a new folder for your project. Inside this folder, create three files: index.html, styles.css, and script.js. These files will hold the HTML structure, CSS styling, and JavaScript functionality, respectively. Open your favorite code editor and load these files to begin.
To create the layout, open index.html and add the basic HTML structure. This includes the <!DOCTYPE html>
, <html>
, <head>
, and <body>
tags. Inside the <head>
, link the CSS and JavaScript files
Let's break down the structure and components of the HTML code:
1. HTML Document Setup:
<!DOCTYPE html>
: Defines the document as HTML5.<html lang="en">
: Sets the language of the document to English.
2. Head Section:
<meta charset="UTF-8">
: Sets the character encoding to UTF-8.<meta http-equiv="X-UA-Compatible" content="IE=edge">
: Ensures compatibility with Internet Explorer.<meta name="viewport" content="width=device-width, initial-scale=1.0">
: Ensures proper scaling on different devices.<title>
Dashboard with Sliders and Music Player</title>
: Sets the title of the web page.- Link tags to external stylesheets for Font Awesome icons and Swiper.js, as well as a local CSS file (styles.css).
3. Body Section:
Main Tag: <main>
contains the primary content of the page.
Navigation Menu:
<nav class="main-menu">
contains user information and navigation links.- User Info: Displays a user image and name.
- Menu Items: Includes links for Discover, Trending, Album, Playlist, Favorites, Profile, Settings, and Logout, each with a Font Awesome icon.
4. Content Section
Left Content:
- Slider for Playlists:
- Uses Swiper.js to create a slider.
- Each slide contains an image, overlay with playlist name, and a "Listen Now" button.
- Featured Artists: Displays a grid of featured artists with images and names.
- Recommended Albums: Displays a grid of recommended albums with images and titles.
Right Content:
- Recommended Songs: Displays a list of songs with images, titles, artists, and durations.
- Music Player:
- Album Cover: Displays a rotating album cover.
- Song Information: Displays the current song's title and artist.
- Audio Element:
<audio id="song">
contains the audio source. - Progress Bar:
<input type="range" value="0" id="progress" />
for the song's progress. - Controls: Includes buttons for play/pause, forward, and backward with corresponding icons.
5. External Resources:
- Font Awesome: Provides icons for navigation and controls.
- Swiper.js: A JavaScript library for creating modern sliders.
- Local CSS and JS files: For custom styling and functionality.
Step 2 (CSS Code):
With the HTML structure in place, move to styles.css to style the dashboard.
Let's break it down:
1. @import: This rule imports an external stylesheet from Google Fonts to include the Nunito and Roboto fonts for use in the webpage.
2. Universal Reset: The *, *::before, and *::after selectors are used to apply box-sizing and reset padding and margins to all elements on the page, ensuring consistent layout behavior.
3. Navigation Styling: Styles for the navigation bar, including disabling text selection and removing outlines from navigation items.
4. Image Styling: Ensures images fill their containers (width: 100%).
5. Font and Body Styling: Defines the default font family for the page and sets up the body to display as a flex container with centered content and a minimum height of the viewport. It also sets a background image with specific properties like no-repeat and cover.
6. Main Menu Styling: Styles the main menu container with a grid layout, background color, backdrop filter, border, border radius, and box-shadow.
7. Content Styling: Sets up grid layout for the main content area.
8. Left Content Styling: Styles for the left content area, including padding and text color.
9. Slider Styling: Styles for a slider container, slides, and pagination.
10. Containers for Artists and Albums: Styles for containers holding artist and album information, including flex layout, padding, and overflow behavior.
11. Artists and Albums Styling: Styles for individual artist and album elements, including image size, border radius, and text styling.
12. Scrollbar Styling: Custom styling for scrollbar appearance.
13. Right Content Styling: Styles for the right content area, including padding, color, and border.
14. Recommended Songs Styling: Styles for recommended songs section, including margin and text styling.
15. Song Styling: Styles for individual song elements, including grid layout and padding.
16. Music Player Styling: Styles for the music player section, including background, border radius, and padding.
17. Album Cover Styling: Styles for the album cover image, including border-radius, border, and box-shadow.
18. Point Styling: Styles for a point element within the album cover.
19. Music Player Controls Styling: Styles for the music player controls, including button appearance, margin, and hover effects.
20. Media Queries: Media queries are used to apply different styles based on the screen width, allowing the layout to adjust responsively for various devices.
@import url("https://fonts.googleapis.com/css2?family=Nunito:wght@200;300;400;500;600;700;800;900;1000&family=Roboto:wght@300;400;500;700&display=swap");
*,
*::before,
*::after {
box-sizing: border-box;
padding: 0;
margin: 0;
}
nav {
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
}
nav ul,
nav ul li {
outline: 0;
}
nav ul li a {
text-decoration: none;
}
img {
width: 100%;
}
h1 {
font-size: clamp(1.2rem, 3vw, 1.5rem);
}
body {
font-family: "Nunito", sans-serif;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background-image: url(https://github.com/ecemgo/mini-samples-great-tricks/assets/13468728/aa462558-0106-4268-9864-d34a4f35531f);
background-repeat: no-repeat;
background-size: cover;
}
/* MAIN MENU */
main {
display: grid;
grid-template-columns: 11% 89%;
width: 95%;
margin: 40px;
background: rgba(16, 21, 61, 0.5);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.5);
border-radius: 15px;
box-shadow: 0 0.5px 0 1px rgba(255, 255, 255, 0.23) inset,
0 1px 0 0 rgba(255, 255, 255, 0.6) inset, 0 4px 16px rgba(0, 0, 0, 0.12);
z-index: 10;
}
.main-menu {
display: flex;
flex-direction: column;
justify-content: space-between;
border-radius: 15px 0 0 15px;
border-right: 1px solid rgba(255, 255, 255, 0.5);
padding: 12px 0 20px;
overflow: hidden;
font-family: inherit;
}
.user-info img {
padding: 12px 24px 6px;
border-radius: 50%;
}
.user-info p {
color: #fff;
font-size: clamp(0.8rem, 3vw, 1rem);
font-weight: 500;
text-align: center;
line-height: 1;
padding: 0 6px 32px;
}
.nav-item {
display: block;
}
.nav-item a {
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 1rem;
padding: 12px 0;
margin: 0 8px;
border-radius: 5px;
}
.nav-item.active a {
background: rgba(106, 109, 155, 0.5);
text-decoration: none;
}
.nav-icon {
width: 40px;
height: 20px;
font-size: 1.1rem;
}
.nav-text {
display: block;
width: 70px;
height: 20px;
letter-spacing: 0;
}
/* CONTENT */
.content {
display: grid;
grid-template-columns: 75% 25%;
}
/* LEFT CONTENT */
.left-content {
padding: 30px 20px;
color: #e5e5e5;
}
/* SLIDER */
.slider-container {
margin: 0 auto;
width: 100%;
}
.swiper {
width: 100%;
padding: 16px 0 20px;
margin-bottom: 50px;
}
.swiper-slide {
position: relative;
width: 600px;
}
.swiper-slide img {
border-radius: 20px;
height: 300px;
object-fit: cover;
border: 2px solid rgba(159, 160, 168, 0.5);
}
.swiper-pagination {
--swiper-pagination-bottom: -4px;
}
.swiper-pagination-bullet {
width: 10px;
height: 10px;
background-color: #ffffffe7;
transition: all 0.3s ease-in-out;
}
.swiper-pagination-bullet-active {
background-color: #fff;
width: 18px;
border-radius: 8px;
}
.slide-overlay {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-end;
row-gap: 12px;
position: absolute;
inset: 0;
width: 100%;
height: 98%;
background: linear-gradient(
240deg,
transparent,
transparent,
rgba(38, 21, 149, 0.8)
);
border-radius: 20px;
padding: 30px;
}
.slide-overlay h2 {
font-size: clamp(1.2rem, 3vw, 2.2rem);
font-weight: 700;
}
.slide-overlay button {
display: flex;
align-items: center;
justify-content: center;
column-gap: 10px;
width: max-content;
padding: 12px 16px;
background: #e9e6eb2a;
color: #e8e5e5;
border: 1px solid rgba(159, 160, 168, 0.4);
border-radius: 12px;
outline: 0;
font-size: clamp(0.7rem, 3vw, 1rem);
font-weight: 500;
text-transform: uppercase;
box-shadow: rgba(0, 0, 0, 0.16) 0px 10px 36px 0px,
rgba(0, 0, 0, 0.06) 0px 0px 0px 1px;
transition: all 0.4s linear;
cursor: pointer;
}
.slide-overlay button:is(:hover, :focus-visible) {
background: #e9e6eb;
color: #000;
}
/* Containers of Artist and Albums */
.containers {
display: flex;
align-items: center;
padding: 0 0 12px;
overflow-x: auto;
cursor: grab;
}
/* ARTISTS */
.artists h1 {
margin-bottom: 24px;
}
.artist-container {
column-gap: 20px;
}
.artist {
display: grid;
grid-auto-flow: dense;
align-items: center;
grid-template-rows: 8fr 2fr;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
}
.artist img {
object-fit: cover;
border-radius: 50%;
border: 2px solid rgba(169, 150, 253, 0.5);
width: 140px;
aspect-ratio: 1/1;
margin-bottom: 8px;
box-shadow: rgba(221, 221, 221, 0.3) 0px 6px 18px -3px,
rgba(221, 221, 221, 0.2) 0px -3px 0px inset;
transition: all 0.2s;
}
.artist img:hover {
border: 4px solid rgba(169, 150, 253, 0.6);
}
.artist p {
font-size: clamp(0.9rem, 3vw, 1rem);
font-weight: 500;
text-align: center;
}
/* ALBUMS */
.albums h1 {
margin: 60px 0 14px;
}
.album-container {
column-gap: 24px;
}
.album {
display: grid;
grid-auto-flow: dense;
grid-template-rows: 5fr 2fr;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
}
.album-frame {
position: relative;
width: 180px;
aspect-ratio: 1/1;
border: 2px solid rgba(169, 150, 253, 0.5);
border-radius: 10px;
box-shadow: rgba(221, 221, 221, 0.3) 0px 8px 18px -3px,
rgba(221, 221, 221, 0.2) 0px -3px 0px inset;
margin-bottom: 15px;
overflow: hidden;
}
.album-frame img {
position: absolute;
inset: 0;
height: 100%;
object-fit: cover;
transition: transform 0.8s;
}
.album-frame img:hover {
transform: rotate(3deg) scale(1.2);
}
.album h2 {
font-size: clamp(0.9rem, 4vw, 1.1rem);
font-weight: 500;
line-height: 1.3;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
@supports (-webkit-line-clamp: 2) {
overflow: hidden;
text-overflow: ellipsis;
white-space: initial;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
}
.album p {
font-size: clamp(0.9rem, 4vw, 1rem);
opacity: 0.5;
}
/* Containers Scrollbar Style */
.artist-container::-webkit-scrollbar,
.album-container::-webkit-scrollbar {
height: 10px;
}
.artist-container::-webkit-scrollbar-track,
.album-container::-webkit-scrollbar-track {
box-shadow: inset 0 0 0.3rem rgb(79, 78, 78);
border-radius: 40px;
}
.artist-container::-webkit-scrollbar-thumb,
.album-container::-webkit-scrollbar-thumb {
box-shadow: inset 0 0 0.5rem rgb(116, 116, 116);
background-color: rgba(25, 43, 206, 0.2);
outline: none;
border-radius: 40px;
}
/* RIGHT CONTENT */
.right-content {
display: grid;
grid-template-rows: 60% 40%;
border-radius: 0 15px 15px 0;
border-left: 1px solid rgba(255, 255, 255, 0.5);
padding: 30px 20px;
color: #e5e5e5;
}
/* SONGS */
.recommended-songs h1 {
margin-bottom: 24px;
}
.song-container {
align-items: center;
}
.song {
display: grid;
grid-template-columns: 26% auto 10%;
align-items: center;
margin-bottom: 16px;
}
.song-img {
position: relative;
width: 60px;
border-radius: 6px;
}
.song-img img {
aspect-ratio: 4/3;
border-radius: inherit;
object-fit: cover;
border: 2px solid rgba(159, 160, 168, 0.5);
box-shadow: rgba(221, 221, 221, 0.3) 0px 6px 18px -3px,
rgba(221, 221, 221, 0.2) 0px -3px 0px inset;
}
.song-img .overlay {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
inset: 0;
width: 100%;
height: 92%;
background-color: rgba(169, 150, 253, 0.6);
border-radius: inherit;
font-size: 1.75rem;
opacity: 0;
transition: all 0.4s linear;
cursor: pointer;
}
.song-img:hover .overlay {
opacity: 1;
}
.song h2 {
font-size: 1rem;
}
.song p,
.song span {
font-size: 0.8rem;
font-weight: 300;
}
.song p {
opacity: 0.8;
}
/* MUSIC PLAYER */
.music-player {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #fff;
background: rgba(188, 184, 198, 0.2);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
box-shadow: inset 2px -2px 6px rgba(214, 214, 214, 0.2),
inset -3px 3px 3px rgba(255, 255, 255, 0.3);
border-radius: 16px;
padding: 30px 20px;
margin-top: 20px;
}
.album-cover {
position: relative;
}
.album-cover img {
border-radius: 50%;
border: 2px solid rgba(222, 215, 255, 0.9);
max-width: 120px;
aspect-ratio: 1/1;
object-fit: cover;
box-shadow: 0 10px 60px rgba(200, 187, 255, 01.75rem);
transition: transform 0.5s ease-out;
pointer-events: none;
user-select: none;
}
.point {
position: absolute;
top: 50%;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
width: 16px;
background-color: rgba(17, 6, 58, 0.7);
border: 2px solid rgba(222, 215, 255, 0.9);
aspect-ratio: 1/1;
border-radius: 50%;
z-index: 2;
}
.music-player h2 {
font-size: 1.2rem;
font-weight: 500;
margin: 16px 0 2px;
}
.music-player p {
font-size: 1rem;
font-weight: 300;
margin-bottom: 26px;
opacity: 0.8;
}
/* Music Player Controls */
#progress {
appearance: none;
-webkit-appearance: none;
width: 100%;
height: 6px;
background: rgba(200, 187, 255, 0.6);
border-radius: 4px;
margin-bottom: 16px;
cursor: pointer;
}
#progress::-webkit-slider-thumb {
appearance: none;
-webkit-appearance: none;
background: rgb(77, 58, 162);
width: 20px;
aspect-ratio: 1/1;
border-radius: 50%;
border: 4px solid rgb(234, 229, 255);
box-shadow: 0 6px 10px rgba(200, 187, 255, 0.4);
}
.controls {
display: flex;
justify-content: center;
align-items: center;
}
.controls button {
display: flex;
align-items: center;
justify-content: center;
width: 36px;
aspect-ratio: 1/1;
margin: 20px;
background: rgba(200, 187, 255, 0.6);
border-radius: 50%;
border: 0;
outline: 0;
color: #fff;
font-size: 1.1rem;
box-shadow: 0 4px 8px rgba(200, 187, 255, 0.3);
cursor: pointer;
transition: all 0.3s linear;
}
.controls button:is(:hover, :focus-visible) {
transform: scale(0.96);
}
.controls button:nth-child(2) {
transform: scale(1.3);
}
.controls button:nth-child(2):is(:hover, :focus-visible) {
transform: scale(1.25);
}
/* MEDIA QUERIES */
@media (max-width: 1500px) {
main {
grid-template-columns: 6% 94%;
}
.user-info img {
border-radius: 50%;
padding: 12px 12px 6px;
}
.nav-icon {
text-align: center;
transform: translateY(2px);
}
.nav-text {
display: none;
}
.content {
grid-template-columns: 70% 30%;
}
}
@media (max-width: 1310px) {
main {
grid-template-columns: 8% 92%;
margin: 30px;
}
}
@media (max-width: 1250px) {
.swiper-slide {
width: 500px;
}
.swiper-slide img {
border-radius: 16px;
height: 280px;
}
.artist {
grid-template-rows: 7fr 2fr;
}
.artist img {
width: 120px;
}
.album-frame {
width: 160px;
}
.song {
grid-template-columns: 29% auto 10%;
}
.controls button {
margin: 15px;
}
}
@media (max-width: 1100px) {
.content {
grid-template-columns: 60% 40%;
}
.left-content {
padding: 40px 20px 20px;
}
.swiper-slide {
width: 410px;
}
.swiper-slide img {
height: 220px;
}
.artist {
grid-template-rows: 5fr 2fr;
}
.artist img {
width: 90px;
}
.album {
grid-template-rows: 4fr 2fr;
}
.album-frame {
width: 130px;
}
.song {
grid-template-columns: 26% auto 10%;
}
.song:nth-child(8),
.song:nth-child(9) {
display: none;
}
}
@media (max-width: 910px) {
main {
grid-template-columns: 10% 90%;
margin: 20px;
}
.left-content {
padding: 30px 20px 20px;
}
.swiper-slide {
width: 350px;
}
.swiper-slide img {
height: 180px;
}
.artist {
grid-template-rows: 4fr 2fr;
}
.artist img {
width: 80px;
}
.album {
grid-template-rows: 3fr 2fr;
}
.album-frame {
width: 100px;
}
.right-content {
grid-template-rows: 55% 45%;
}
.song {
grid-template-columns: 30% auto 12%;
}
.song:nth-child(7) {
display: none;
}
}
@media (max-width: 825px) {
.content {
grid-template-columns: 52% 48%;
}
.swiper-slide {
width: 320px;
}
.swiper-slide img {
height: 200px;
}
.slide-overlay {
row-gap: 8px;
padding: 12px 36px;
}
.slide-overlay button {
padding: 8px 12px;
}
.song {
grid-template-columns: 28% auto 10%;
}
}
@media (max-width: 700px) {
main {
grid-template-columns: 15% 85%;
}
.content {
grid-template-columns: 100%;
grid-template-areas:
"leftContent"
"rightContent";
}
.left-content {
grid-area: leftContent;
}
.slide-overlay {
row-gap: 12px;
padding: 20px 30px;
}
.swiper-slide {
width: 420px;
}
.artist img {
width: 110px;
}
.album {
grid-template-rows: 3fr 2fr;
}
.album-frame {
width: 140px;
}
.right-content {
grid-area: rightContent;
border-left: unset;
grid-template-rows: 60% 40%;
row-gap: 16px;
}
.song {
grid-template-columns: 18% auto 8%;
}
.song:nth-child(7),
.song:nth-child(8),
.song:nth-child(9) {
display: grid;
}
.controls button {
margin: 20px;
}
}
@media (max-width: 580px) {
.swiper-slide {
width: 340px;
}
.swiper-slide img {
height: 180px;
}
.artist img {
width: 80px;
}
.album {
grid-template-rows: 3fr 2fr;
}
.album-frame {
width: 100px;
}
.song {
grid-template-columns: 23% auto 8%;
}
}
@media (max-width: 450px) {
.user-info img {
border-radius: 50%;
padding: 6px 6px 2px;
}
.swiper-slide {
width: 320px;
}
.slide-overlay {
row-gap: 8px;
padding: 12px 36px;
}
.song {
grid-template-columns: 25% auto 8%;
}
}
Step 3 (JavaScript Code):
Now it's time to add functionality using JavaScript. Open script.js and start by selecting the necessary elements. Then, implement the logic for the sliders and music player.
Let's break down this JavaScript code step by step.
1. Navigation Item Click Handling
const navItems = document.querySelectorAll(".nav-item"); navItems.forEach((navItem, i) => { navItem.addEventListener("click", () => { navItems.forEach((item, j) => { item.className = "nav-item"; }); navItem.className = "nav-item active"; }); });
Selection of Navigation Items: document.querySelectorAll(".nav-item") selects all elements with the class nav-item.
Adding Click Event Listeners: For each nav-item, an event listener is added that:
- Resets the class of all nav-item elements to "nav-item".
- Sets the clicked nav-item's class to "nav-item active".
2. Draggable Container Handling
const containers = document.querySelectorAll(".containers"); containers.forEach((container) => { let isDragging = false; let startX; let scrollLeft; container.addEventListener("mousedown", (e) => { isDragging = true; startX = e.pageX - container.offsetLeft; scrollLeft = container.scrollLeft; }); container.addEventListener("mousemove", (e) => { if (!isDragging) return; e.preventDefault(); const x = e.pageX - container.offsetLeft; const step = (x - startX) * 0.6; container.scrollLeft = scrollLeft - step; }); container.addEventListener("mouseup", () => { isDragging = false; }); container.addEventListener("mouseleave", () => { isDragging = false; }); });
Selection of Containers: document.querySelectorAll(".containers") selects all elements with the class containers.
Adding Mouse Event Listeners:
- mousedown: Initializes dragging, capturing the start position and scroll offset.
- mousemove: Handles the dragging, updating the scroll position based on mouse movement.
- mouseup and mouseleave: Ends dragging.
3. Music Player Controls
Variables and Song List
const progress = document.getElementById("progress"); const song = document.getElementById("song"); const controlIcon = document.getElementById("controlIcon"); const playPauseButton = document.querySelector(".play-pause-btn"); const forwardButton = document.querySelector(".controls button.forward"); const backwardButton = document.querySelector(".controls button.backward"); const rotatingImage = document.getElementById("rotatingImage"); const songName = document.querySelector(".music-player h2"); const artistName = document.querySelector(".music-player p"); let rotating = false; let currentRotation = 0; let rotationInterval; const songs = [ // List of songs with title, name, source URL, and cover image URL ];
- Element Selection: Various elements are selected for controlling the music player and displaying song information.
- Rotation Variables: Flags and variables for managing image rotation.
- Song List: An array of song objects with metadata.
5. Functions for Song Rotation and Info Update
function startRotation() { if (!rotating) { rotating = true; rotationInterval = setInterval(rotateImage, 50); } } function pauseRotation() { clearInterval(rotationInterval); rotating = false; } function rotateImage() { currentRotation += 1; rotatingImage.style.transform = `rotate(${currentRotation}deg)`; } function updateSongInfo() { songName.textContent = songs[currentSongIndex].title; artistName.textContent = songs[currentSongIndex].name; song.src = songs[currentSongIndex].source; rotatingImage.src = songs[currentSongIndex].cover; song.addEventListener("loadeddata", function () {}); }
- startRotation: Starts rotating the image at regular intervals.
- pauseRotation: Stops the image rotation.
- rotateImage: Updates the rotation angle of the image.
- updateSongInfo: Updates the song and artist information, as well as the song source and cover image.
6. Event Listeners for Song
song.addEventListener("loadedmetadata", function () { progress.max = song.duration; progress.value = song.currentTime; }); song.addEventListener("ended", function () { currentSongIndex = (currentSongIndex + 1) % songs.length; updateSongInfo(); playPause(); }); song.addEventListener("timeupdate", function () { if (!song.paused) { progress.value = song.currentTime; } });
- loadedmetadata: Updates the progress bar's maximum value and current value based on song duration and current time.
- ended: Plays the next song when the current song ends.
- timeupdate: Continuously updates the progress bar as the song plays.
7. Play/Pause and Control Button Event Listeners
function playPause() { if (song.paused) { song.play(); controlIcon.classList.add("fa-pause"); controlIcon.classList.remove("fa-play"); startRotation(); } else { song.pause(); controlIcon.classList.remove("fa-pause"); controlIcon.classList.add("fa-play"); pauseRotation(); } } playPauseButton.addEventListener("click", playPause); progress.addEventListener("input", function () { song.currentTime = progress.value; }); progress.addEventListener("change", function () { song.play(); controlIcon.classList.add("fa-pause"); controlIcon.classList.remove("fa-play"); startRotation(); }); forwardButton.addEventListener("click", function () { currentSongIndex = (currentSongIndex + 1) % songs.length; updateSongInfo(); playPause(); }); backwardButton.addEventListener("click", function () { currentSongIndex = (currentSongIndex - 1 + songs.length) % songs.length; updateSongInfo(); playPause(); }); updateSongInfo();
- playPause: Toggles play and pause states, updates the control icon, and manages image rotation.
- Progress Bar Input and Change Events: Updates song current time and starts playing the song if necessary.
- Forward and Backward Buttons: Change the current song and update the UI accordingly.
8. Swiper Initialization
var swiper = new Swiper(".swiper", { effect: "coverflow", grabCursor: true, centeredSlides: true, loop: true, speed: 600, slidesPerView: "auto", coverflowEffect: { rotate: 10, stretch: 120, depth: 200, modifier: 1, slideShadows: false, }, on: { click(event) { swiper.slideTo(this.clickedIndex); }, }, pagination: { el: ".swiper-pagination", }, });
- Swiper Initialization: Configures a Swiper instance with coverflow effect and various settings for appearance and behavior.
- Event Listener for Click: Allows slides to be navigated by clicking on them.
- Pagination: Adds pagination controls to the Swiper.
const navItems = document.querySelectorAll(".nav-item");
navItems.forEach((navItem, i) => {
navItem.addEventListener("click", () => {
navItems.forEach((item, j) => {
item.className = "nav-item";
});
navItem.className = "nav-item active";
});
});
const containers = document.querySelectorAll(".containers");
containers.forEach((container) => {
let isDragging = false;
let startX;
let scrollLeft;
container.addEventListener("mousedown", (e) => {
isDragging = true;
startX = e.pageX - container.offsetLeft;
scrollLeft = container.scrollLeft;
});
container.addEventListener("mousemove", (e) => {
if (!isDragging) return;
e.preventDefault();
const x = e.pageX - container.offsetLeft;
const step = (x - startX) * 0.6;
container.scrollLeft = scrollLeft - step;
});
container.addEventListener("mouseup", () => {
isDragging = false;
});
container.addEventListener("mouseleave", () => {
isDragging = false;
});
});
const progress = document.getElementById("progress");
const song = document.getElementById("song");
const controlIcon = document.getElementById("controlIcon");
const playPauseButton = document.querySelector(".play-pause-btn");
const forwardButton = document.querySelector(".controls button.forward");
const backwardButton = document.querySelector(".controls button.backward");
const rotatingImage = document.getElementById("rotatingImage");
const songName = document.querySelector(".music-player h2");
const artistName = document.querySelector(".music-player p");
let rotating = false;
let currentRotation = 0;
let rotationInterval;
const songs = [
{
title: "Redemption",
name: "Besomorph & Coopex",
source:
"https://github.com/ecemgo/mini-samples-great-tricks/raw/main/song-list/Besomorph-Coopex-Redemption.mp3",
cover:
"https://github.com/ecemgo/mini-samples-great-tricks/assets/13468728/398875d0-9b9e-494a-8906-210aa3f777e0",
},
{
title: "What's The Problem?",
name: "OSKI",
source:
"https://github.com/ecemgo/mini-samples-great-tricks/raw/main/song-list/OSKI-Whats-The-Problem.mp3",
cover:
"https://github.com/ecemgo/mini-samples-great-tricks/assets/13468728/810d1ddc-1168-4990-8d43-a0ffee21fb8c",
},
{
title: "Control",
name: "Unknown Brain x Rival",
source:
"https://github.com/ecemgo/mini-samples-great-tricks/raw/main/song-list/Unknown-BrainxRival-Control.mp3",
cover:
"https://github.com/ecemgo/mini-samples-great-tricks/assets/13468728/7bd23b84-d9b0-4604-a7e3-872157a37b61",
},
];
let currentSongIndex = 0;
function startRotation() {
if (!rotating) {
rotating = true;
rotationInterval = setInterval(rotateImage, 50);
}
}
function pauseRotation() {
clearInterval(rotationInterval);
rotating = false;
}
function rotateImage() {
currentRotation += 1;
rotatingImage.style.transform = `rotate(${currentRotation}deg)`;
}
function updateSongInfo() {
songName.textContent = songs[currentSongIndex].title;
artistName.textContent = songs[currentSongIndex].name;
song.src = songs[currentSongIndex].source;
rotatingImage.src = songs[currentSongIndex].cover;
song.addEventListener("loadeddata", function () {});
}
song.addEventListener("loadedmetadata", function () {
progress.max = song.duration;
progress.value = song.currentTime;
});
song.addEventListener("ended", function () {
currentSongIndex = (currentSongIndex + 1) % songs.length;
updateSongInfo();
playPause();
});
song.addEventListener("timeupdate", function () {
if (!song.paused) {
progress.value = song.currentTime;
}
});
function playPause() {
if (song.paused) {
song.play();
controlIcon.classList.add("fa-pause");
controlIcon.classList.remove("fa-play");
startRotation();
} else {
song.pause();
controlIcon.classList.remove("fa-pause");
controlIcon.classList.add("fa-play");
pauseRotation();
}
}
playPauseButton.addEventListener("click", playPause);
progress.addEventListener("input", function () {
song.currentTime = progress.value;
});
progress.addEventListener("change", function () {
song.play();
controlIcon.classList.add("fa-pause");
controlIcon.classList.remove("fa-play");
startRotation();
});
forwardButton.addEventListener("click", function () {
currentSongIndex = (currentSongIndex + 1) % songs.length;
updateSongInfo();
playPause();
});
backwardButton.addEventListener("click", function () {
currentSongIndex = (currentSongIndex - 1 + songs.length) % songs.length;
updateSongInfo();
playPause();
});
updateSongInfo();
var swiper = new Swiper(".swiper", {
effect: "coverflow",
grabCursor: true,
centeredSlides: true,
loop: true,
speed: 600,
slidesPerView: "auto",
coverflowEffect: {
rotate: 10,
stretch: 120,
depth: 200,
modifier: 1,
slideShadows: false,
},
on: {
click(event) {
swiper.slideTo(this.clickedIndex);
},
},
pagination: {
el: ".swiper-pagination",
},
});
Final Output:
Conclusion:
By following this guide, you've built a responsive dashboard with interactive sliders and a music player. This project demonstrates the power of combining HTML, CSS, and JavaScript to create dynamic web applications. Continue to experiment and expand your dashboard with additional features and enhancements.
Code by: Ecem Gokdogan
That’s a wrap!
I hope you enjoyed this post. Now, with these examples, you can create your own amazing page.
Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee
And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!
Thanks!
Faraz 😊