generated from com-480-data-visualization/com-480-project-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f379d80
commit cce4617
Showing
1 changed file
with
348 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,348 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>Interactive DJ Booth</title> | ||
<style> | ||
:root { | ||
--primary-color: #00c3ff; | ||
--secondary-color: #ff6f61; | ||
--accent-color: #ffd700; | ||
--background-color:#efbbff; | ||
--left-box-background-color: #d896ff; | ||
--text-color: #800080; | ||
--text-color-light: #fff; | ||
--border-color: #660066; | ||
--barcolor: #660066; | ||
} | ||
|
||
body { | ||
margin: 0; | ||
font-family: Arial, sans-serif; | ||
background-color: var(--background-color); | ||
} | ||
|
||
.container { | ||
display: grid; | ||
grid-template-rows: auto 1fr auto; | ||
gap: 20px; | ||
padding: 20px; | ||
max-width: 1200px; | ||
margin: 0 auto; | ||
} | ||
|
||
#search-bar { | ||
padding: 10px; | ||
text-align: center; | ||
} | ||
|
||
#search-bar input[type="text"] { | ||
width: 100%; | ||
max-width: 600px; | ||
padding: 10px; | ||
border: none; | ||
background-color: var(--background-color); | ||
border-bottom: 2px solid var(--border-color); | ||
margin: 0 auto; | ||
display: block; | ||
} | ||
|
||
#main-content { | ||
grid-row: 2; | ||
display: grid; | ||
grid-template-columns: 1fr 3fr; | ||
gap: 20px; | ||
} | ||
|
||
#list-area { | ||
display: flex; | ||
flex-direction: column; | ||
background-color: var(--left-box-background-color); | ||
overflow-y: auto; | ||
height: 480px; | ||
border: 1px solid var(--border-color); | ||
padding: 10px; | ||
box-sizing: border-box; | ||
text-align: center; | ||
} | ||
|
||
#list-area h3 { | ||
margin-bottom: 0; /* Removes the default margin to allow the lines to be closer to the text */ | ||
} | ||
|
||
#visualization { | ||
display: flex; | ||
justify-content: space-around; | ||
align-items: center; | ||
height: 450px; | ||
margin-top: 20px; | ||
} | ||
|
||
#player, audio { | ||
text-align: center; | ||
width: 100%; | ||
} | ||
|
||
#controls-container { | ||
display: flex; | ||
align-items: center; | ||
gap: 20px; | ||
height:150px; | ||
} | ||
|
||
#dj-controls { | ||
display: flex; | ||
flex-direction: row; | ||
align-items: center; | ||
gap: 20px; | ||
border:1px solid var(--border-color); | ||
} | ||
|
||
.slider-container { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
padding-top:25px; | ||
} | ||
.slider-container label { | ||
padding-top: 45px; | ||
color: var(--text-color); | ||
text-align: center; | ||
} | ||
.slider-container input[type="range"] { | ||
transform: rotate(-90deg); | ||
width: 100px; | ||
} | ||
|
||
.button-container { | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
margin-left: auto; | ||
} | ||
|
||
.custom-line { | ||
border: none; | ||
height: 2px; | ||
background-color: var(--text-color); /* Match the color of the text */ | ||
margin: 5px 0; /* Adjust the space around the lines */ | ||
} | ||
|
||
#toggle-song-artist { | ||
width: 100px; | ||
height: 50px; | ||
} | ||
|
||
#song-artist-list h3 { | ||
color: var(--text-color); | ||
} | ||
|
||
#crowd-reaction img { | ||
max-width: 100%; /* Ensure images do not exceed their container */ | ||
} | ||
|
||
.button-grid { | ||
display: grid; | ||
grid-template-columns: repeat(2, auto); /* Creates two columns */ | ||
grid-template-rows: repeat(2, auto); /* Creates two rows */ | ||
gap: 10px; /* Space between buttons */ | ||
justify-content: center; /* Center the grid horizontally */ | ||
align-items: center; /* Center the grid vertically */ | ||
padding: 20px; /* Optional: Padding around the entire grid */ | ||
} | ||
|
||
.grid-button { | ||
width: 50px; /* Width of each button */ | ||
height: 50px; /* Height of each button to make it square */ | ||
background-color: var(--border-color); /* Button color from your color scheme */ | ||
border: 1px solid var(--border-color); /* Button border from your color scheme */ | ||
cursor: pointer; /* Changes the cursor to signify a clickable element */ | ||
} | ||
|
||
.bar { | ||
fill: var(--barcolor); | ||
} | ||
|
||
</style> | ||
<script src="https://d3js.org/d3.v6.min.js"></script> | ||
|
||
</head> | ||
<body> | ||
<div class="container"> | ||
<div id="search-bar"> | ||
<input type="text" id="search-input" placeholder="Search Songs/Artists..."> | ||
</div> | ||
|
||
<div id="main-content"> | ||
<div id="list-area"> | ||
<h3 id="List Title">Song List</h3> | ||
<hr class="custom-line"> | ||
<div id="player"> | ||
<audio controls> | ||
<source src="sample.mp3" type="audio/mpeg"> | ||
Your browser does not support the audio element. | ||
</audio> | ||
</div> | ||
</div> | ||
|
||
<div> | ||
<div id="visualization"> | ||
<!-- <img src="stats.png" alt="Stats"> --> | ||
<div id="bar-chart"></div> | ||
<svg id="stickman" viewBox="0 0 100 200" style="width: 100px; height: 200px;"> | ||
<circle cx="50" cy="30" r="10" fill="black"/> <!-- Head --> | ||
<line x1="50" y1="40" x2="50" y2="100" stroke="black" stroke-width="2"/> <!-- Body --> | ||
<line x1="50" y1="60" x2="30" y2="80" stroke="black" stroke-width="2"/> <!-- Left arm --> | ||
<line x1="50" y1="60" x2="70" y2="80" stroke="black" stroke-width="2"/> <!-- Right arm --> | ||
<line x1="50" y1="100" x2="30" y2="150" stroke="black" stroke-width="2"/> <!-- Left leg --> | ||
<line x1="50" y1="100" x2="70" y2="150" stroke="black" stroke-width="2"/> <!-- Right leg --> | ||
</svg> | ||
</div> | ||
|
||
|
||
<div id="controls-container"> | ||
<div id="dj-controls"> | ||
<img src="Milestone2\disc.png" alt="disc1" style="height: 120px;"> | ||
|
||
<div class="button-grid"> | ||
<button class="grid-button"></button> | ||
<button class="grid-button"></button> | ||
<button class="grid-button"></button> | ||
<button class="grid-button"></button> | ||
</div> | ||
|
||
<img src="Milestone2\disc.png" alt="disc1" style="height: 120px;"> | ||
|
||
|
||
<div class="slider-container"> | ||
<input type="range" id="loudness" name="loudness" min="1" max="100" value="50" orient="vertical" oninput="updateSliderValue(this)"> | ||
<label for="loudness">Loudness: <span id="loudness-value">50</span></label> | ||
</div> | ||
|
||
<div class="slider-container"> | ||
<input type="range" id="tempo" name="tempo" min="60" max="200" value="120" orient="vertical" oninput="updateSliderValue(this)"> | ||
<label for="tempo">Tempo: <span id="tempo-value">120</span></label> | ||
</div> | ||
|
||
</div> | ||
|
||
<div class="button-container"> | ||
<button id="toggle-song-artist" style="height: 100px; width: 100px;" onclick="toggleSongArtist(this)">Toggle Song/Artist</button> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<script> | ||
// Data | ||
var data = [ | ||
{label: 'A', value: 10}, | ||
{label: 'B', value: 20}, | ||
{label: 'C', value: 30}, | ||
{label: 'D', value: 40}, | ||
{label: 'E', value: 6}, | ||
{label: 'F', value: 15}, | ||
{label: 'G', value: 30}, | ||
]; | ||
|
||
// Set dimensions and margins for the chart | ||
var margin = {top: 100, right: 20, bottom: 20, left: 40}, | ||
width = 200 - margin.left - margin.right, | ||
height = 400 - margin.top - margin.bottom; | ||
|
||
// Append SVG object to the div with id="bar-chart" | ||
var svg = d3.select("#bar-chart").append("svg") | ||
.attr("width", width + margin.left + margin.right) | ||
.attr("height", height+200) | ||
.append("g") | ||
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | ||
|
||
// Set the ranges for the scales | ||
var x = d3.scaleBand() | ||
.range([0, width]) | ||
.padding(0.1); | ||
var y = d3.scaleLinear() | ||
.range([height/2, 0, height/2]); | ||
|
||
// Scale the range of the data in the domains | ||
x.domain(data.map(function(d) { return d.label; })); | ||
y.domain([d3.min(data, function(d) { return d.value; }), d3.max(data, function(d) { return d.value; })]); | ||
|
||
// Bars | ||
svg.selectAll(".bar") | ||
.data(data) | ||
.enter().append("rect") | ||
.attr("class", "bar") | ||
.attr("x", function(d) { return x(d.label); }) | ||
.attr("width", x.bandwidth()) | ||
.attr("y", function(d) { return y(Math.max(0, d.value)); }) | ||
.attr("height", function(d) { return Math.abs(y(d.value) - y(0)); }) | ||
.attr("ry", "9"); //curved corner | ||
|
||
// Mirrored bars (sound wave effect) | ||
svg.selectAll(".mirror-bar") | ||
.data(data) | ||
.enter().append("rect") | ||
.attr("class", "bar") | ||
.attr("x", function(d) { return x(d.label); }) | ||
.attr("width", x.bandwidth()) | ||
.attr("y", function(d) { return y(0)-10; }) | ||
.attr("height", function(d) { return Math.abs(y(d.value) - y(0)); }) | ||
.attr("ry", "9") //curved corner | ||
|
||
// Labels | ||
svg.selectAll(".bar-label") | ||
.data(data) | ||
.enter().append("text") | ||
.attr("class", ".bar-label") | ||
.attr("alignment-baseline", "middle") | ||
.attr("fill", "white") | ||
.attr("font-size", "14px") | ||
.attr("x", function(d) { return x(d.label) + x.bandwidth() / 2 ; }) // Center label | ||
.attr("y", function(d) { return y(0) + 1; }) | ||
.attr("transform", function(d) { | ||
var xPosition = x(d.label) + x.bandwidth() / 2; | ||
var yPosition = y(0); | ||
return `rotate(-90, ${xPosition}, ${yPosition})`; // Rotate 90 degrees | ||
}) | ||
.text(function(d) { return d.label; }); | ||
</script> | ||
|
||
<script src="script.js"></script> | ||
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script> | ||
<script> | ||
anime.timeline({ loop: true }) | ||
.add({ | ||
targets: '#stickman line:nth-child(3)', // Left arm | ||
rotate: [0, 20], | ||
duration: 500, | ||
easing: 'easeInOutSine' | ||
}) | ||
.add({ | ||
targets: '#stickman line:nth-child(4)', // Right arm | ||
rotate: [0, -20], | ||
duration: 500, | ||
offset: '-=500', | ||
easing: 'easeInOutSine' | ||
}) | ||
.add({ | ||
targets: '#stickman line:nth-child(5)', // Left leg | ||
rotate: [0, 10], | ||
duration: 500, | ||
offset: 0, | ||
easing: 'easeInOutSine' | ||
}) | ||
.add({ | ||
targets: '#stickman line:nth-child(6)', // Right leg | ||
rotate: [0, -10], | ||
duration: 500, | ||
offset: '-=500', | ||
easing: 'easeInOutSine' | ||
}); | ||
</script> | ||
|
||
|
||
</body> | ||
</html> |