Sync Embedded YouTube Video Time Stamp to Custom Progress Bar - html

I am stuck on a portion of a project I have been working on today. The task is to sync the timestamp information from the embedded youtube video and display a custom progress bar matching the length of the song at the bottom of the page. Here is the layout so far:
So basically, how do I pull constant timestamps to update the progress and how do I animate the bar to complete 100% matching the end of the video.
I have already disabled the user's ability to scrobble the embedded youtube video. NOTE: the user should not be able to change the time of the youtube video using the custom progress bar either (it is just there for visual queue)!
Please let me know if you need more clarification. HTML and CSS are below. Thank you!! :)
HTML >>>
<!DOCTYPE html>
<html>
<head>
<title>Chat</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="header-bar">
<div class="bar"></div>
<div class="dropshadow"></div>
</div>
<div class="container-middle-third">
<div class="youtube-video" style="float: left;">
<div class="DJ-text">Affinity FM DJ Room</div>
<div class="DJ-underline"></div>
<div class="transparent-layer"> <iframe width="850px" height="477px" src="https://www.youtube.com/embed/2GvIq2SpVFM?autoplay=0&showinfo=0&controls=0" frameborder="0" allowfullscreen></iframe></div>
</div>
<div class="chat" style="float: left;">
<div class="Chat-text">Chat</div>
<div class="Chat-underline"></div>
<input type="text" class="chat-name" placeholder="Chat">
<div class="info-rect">Info</div>
<div class="chat-messages"></div>
<textarea placeholder="Join the conversation..."></textarea>
<div class="chat-status">Status: <span>Idle</span></div>
</div>
</div>
<div class="bottom-bar">
<div class="thumbnail" style="float: left"></div>
<div class="title-bar" style="float: left;">
<div class="song-name">Finding Hope - Let Go (feat. Deverano)</div>
<div class="dj-playing">Affinity FM is playing</div>
<div class="progress-background"></div>
<div class="progress-bar"></div>
</div>
<div class="subscribe" style="float: left;"></div>
</div>
<script src="http://127.0.0.1:8080/socket.io/socket.io.js"></script>
<script>
(function() {
var getNode = function(s) {
return document.querySelector(s);
},
// Get required nodes
status = getNode('.chat-status span'),
messages = getNode('.chat-messages'),
textarea = getNode('.chat textarea'),
chatName = getNode('.chat-name'),
statusDefault = status.textContent,
setStatus = function(s){
status.textContent = s;
if(s !== statusDefault){
var delay = setTimeout(function(){
setStatus(statusDefault);
clearInterval(delay);
}, 3000);
}
};
//try connection
try{
var socket = io.connect('http://127.0.0.1:8080');
} catch(e){
//Set status to warn user
}
if(socket !== undefined){
//Listen for output
socket.on('output', function(data){
if(data.length){
//Loop through results
for(var x = 0; x < data.length; x = x + 1){
var message = document.createElement('div');
message.setAttribute('class', 'chat-message');
message.textContent = ': ' + data[x].message;
var name=document.createElement('span');
name.setAttribute('class', 'userName');
name.textContent = data[x].name;
message.insertBefore(name, message.firstChild);
//Append
messages.appendChild(message);
messages.insertBefore(message, messages.firstChild);
}
}
});
//Listen for a status
socket.on('status', function(data){
setStatus((typeof data === 'object') ? data.message : data);
if(data.clear === true){
textarea.value = '';
}
});
//Listen for keydown
textarea.addEventListener('keydown', function(event){
var self = this,
name = chatName.value;
if(event.which === 13 && event.shiftKey === false){
socket.emit('input', {
name: name,
message: self.value
});
}
});
}
})();
</script>
</body>
</html>
and CSS >>>
body {
background-color: #0f0f17;
margin: 0px;
width: 100%;
}
.container-middle-third{
margin-top: 20px;
margin-left: 155px;
}
body,
textarea,
input {
font: 13px "Raleway", sans-serif;
color: #ffffff;
}
.bar{
height: 80px;
width: 100%;
background-color: #15151d;
}
.DJ-text{
font-weight: 700;
/*position:relative;*/
text-transform: uppercase;
}
.Chat-text{
font-weight: 700;
text-transform: uppercase;
}
.DJ-underline{
width: 850px;
height: 1px;
position:relative;top:10px;
background-color: #3f3f45;
margin: 0px 0px 40px;
}
.Chat-underline{
width: 100%;
position:relative;
/*left:-140px;*/
float:right;
height: 1px;
position:relative;top:10px;
background-color: #3f3f45;
margin: 0px 0px 40px;
}
.transparent-layer{
width: 850px;
height: 477px;
pointer-events: none;
background-color: #ffffff;
}
.ad{
width: 728px;
height: 90px;
border: 1px solid #000000;
margin-left: 11px;
margin-top: 20px;
}
.chat {
min-width: 400px;
margin: 0px 0px 0px 135px;
}
.chat-messages,
.chat-textarea,
.chat-name {
border: 1px solid #1a1a23;
background-color: #1a1a23;
}
.userName{
font-weight: 700;
color: #079ce0;
}
.chat-messages {
width:380px;
height:400px;
overflow-y:scroll;
padding:10px;
}
.chat-message {
margin-bottom:10px;
}
.info-rect{
height: 40px;
width: 180px;
padding:10px;
max-width: 100%;
margin:0;
border:0;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
text-transform: uppercase;
background-color: #15151d
}
.chat-name{
height: 40px;
max-width: 100%;
width: 180px;
padding:10px;
border:0;
margin:0;
font-weight: 700;
text-transform: uppercase;
float:left;
text-align: center;
}
.chat textarea {
width:380px;
padding:10px;
margin:0;
border-top:0;
max-width:100%;
border-top: 1px solid #0f0f17;
border-bottom: 1px solid #1a1a23;
border-right: 1px solid #1a1a23;
border-left: 1px solid #1a1a23;
background-color: #1a1a23;
}
.chat-status {
color: #bbb;
opacity: 0;
background-color: #0f0f17;
}
.info-rect,
.chat textarea,
.chat-name {
max-width: 100%;
}
.bottom-bar{
position: fixed;
bottom: 0;
width: 100%;
}
.thumbnail{
width: 80px;
height: 80px;
background-color: #ffffff
}
.title-bar{
width:1000px;
height: 80px;
background-color: #1a1a23;
}
.song-name{
font-weight: 700;
text-transform: uppercase;
margin-left: 30px;
margin-top: 25px;
}
.dj-playing{
margin-left: 30px;
}
.progress-background{
width: 1000px;
height: 4px;
background-color: #313139;
position: fixed;
bottom: 0;
}
.progress-bar{
width: 400px;
height: 4px;
background-color: #fa1d57;
position: fixed;
bottom: 0;
}
.subscribe{
width: 520px;
height: 80px;
background-color: #15151d;
}

Love your questions!
switch the iframe with a div with id="player" (any name you want, it could be "my_own_player" or "XYZ_player"...)
Then now you're all set to convert your iframe player into a Youtube player object so that you can accomplish what you desire, using the "IFrame player API".
Make sure you style your div the same way you wanted your iframe.
Just add the following script :
//This function creates an <iframe> (and YouTube player)
function onYouTubeIframeAPIReady()
{
player = new YT.Player("player",
{
height: "850",
width: "477",
videoId: "2GvIq2SpVFM",
events:
{
"onReady": onPlayerReady,
"onStateChange": onPlayerStateChange
}
});
}
Replace videoId with your video's ID.
Replace height with your video's height.
Replace width with your video's width.
NOW, to get the "Video Time Stamps" like you say, in order to make the progress bar is easy. The player object has two methods that will do that:
getCurrentTime()
getDuration()
getDuration is the total time of the video in seconds. While getCurrentTime is the time where the video has played up to. Divide
getCurrentTime by getDuration and you'll get a ratio for the progress bar. Multiply it by 100 and you get the percentage you're looking for:
(player.getCurrentTime()/player.getDuration())*100;
That's it! Once you got a percentage that represents getCurrentTime / getDuration, you don't need anything else for an html progress bar. Just style that html bar element's width to that percentage. Just make sure that red "bar" has a background (another div) that's easily recognized as the outward limit for the progress bar. Or just put it inside another div that's visible on the page like so :
<div id="progress" style="width: 800px; height: 10px; border: 1px solid #fff;">
<div id="bar" style="width: 1px; height: 10px; background: #f00;"></div>
</div>
Please, just try out your modified HTML:
<!DOCTYPE html>
<html>
<head>
<title>Chat</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="header-bar">
<div class="bar"></div>
<div class="dropshadow"></div>
</div>
<div class="container-middle-third">
<div class="youtube-video" style="float: left;">
<div class="DJ-text">Affinity FM DJ Room</div>
<div class="DJ-underline"></div>
<div class="transparent-layer"> <div id="player" style="width: 850px; height: 477px;"></div></div>
</div>
<div class="chat" style="float: left;">
<div class="Chat-text">Chat</div>
<div class="Chat-underline"></div>
<input type="text" class="chat-name" placeholder="Chat">
<div class="info-rect">Info</div>
<div class="chat-messages"></div>
<textarea placeholder="Join the conversation..."></textarea>
<div class="chat-status">Status: <span>Idle</span></div>
</div>
</div>
<div class="bottom-bar">
<div class="thumbnail" style="float: left"></div>
<div class="title-bar" style="float: left;">
<div class="song-name">Finding Hope - Let Go (feat. Deverano)</div>
<div class="dj-playing">Affinity FM is playing</div>
<div class="progress-background">
<div id="progress-bar" class="progress-bar"></div>
</div>
</div>
<div class="subscribe" style="float: left;"></div>
</div>
<script src="http://127.0.0.1:8080/socket.io/socket.io.js"></script>
<script>
(function() {
var getNode = function(s) {
return document.querySelector(s);
},
// Get required nodes
status = getNode('.chat-status span'),
messages = getNode('.chat-messages'),
textarea = getNode('.chat textarea'),
chatName = getNode('.chat-name'),
statusDefault = status.textContent,
setStatus = function(s){
status.textContent = s;
if(s !== statusDefault){
var delay = setTimeout(function(){
setStatus(statusDefault);
clearInterval(delay);
}, 3000);
}
};
//try connection
try{
var socket = io.connect('http://127.0.0.1:8080');
} catch(e){
//Set status to warn user
}
if(socket !== undefined){
//Listen for output
socket.on('output', function(data){
if(data.length){
//Loop through results
for(var x = 0; x < data.length; x = x + 1){
var message = document.createElement('div');
message.setAttribute('class', 'chat-message');
message.textContent = ': ' + data[x].message;
var name=document.createElement('span');
name.setAttribute('class', 'userName');
name.textContent = data[x].name;
message.insertBefore(name, message.firstChild);
//Append
messages.appendChild(message);
messages.insertBefore(message, messages.firstChild);
}
}
});
//Listen for a status
socket.on('status', function(data){
setStatus((typeof data === 'object') ? data.message : data);
if(data.clear === true){
textarea.value = '';
}
});
//Listen for keydown
textarea.addEventListener('keydown', function(event){
var self = this,
name = chatName.value;
if(event.which === 13 && event.shiftKey === false){
socket.emit('input', {
name: name,
message: self.value
});
}
});
}
})();
</script>
<script>
var time_total;
var timeout_setter;
var player;
var tag = document.createElement("script");//This code loads the IFrame Player API code asynchronously
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
//This function creates an <iframe> (and YouTube player) OR uses the iframe if it exists at the "player" element after the API code downloads
function onYouTubeIframeAPIReady()
{
player = new YT.Player("player",
{
height: "850",
width: "477",
videoId: "2GvIq2SpVFM",
events:
{
"onReady": onPlayerReady,
"onStateChange": onPlayerStateChange
}
});
}
//The API will call this function when the video player is ready
function onPlayerReady(event)
{
event.target.playVideo();
time_total = convert_to_mins_and_secs(player.getDuration(), 1);
loopy();
}
function loopy()
{
var current_time = convert_to_mins_and_secs(player.getCurrentTime(), 0);
document.getElementById("progress-bar").style.width = (player.getCurrentTime()/player.getDuration())*100+"%";
console.log( current_time + " / " + time_total);
timeout_setter = setTimeout(loopy, 1000);
}
function convert_to_mins_and_secs(seconds, minus1)
{
var mins = (seconds>=60) ?Math.round(seconds/60):0;
var secs = (seconds%60!=0) ?Math.round(seconds%60):0;
var secs = (minus1==true) ?(secs-1):secs; //Youtube always displays 1 sec less than its duration time!!! Then we have to set minus1 flag to true for converting player.getDuration()
var time = mins + ":" + ((secs<10)?"0"+secs:secs);
return time;
}
// 5. The API calls this function when the player's state changes
function onPlayerStateChange(event)
{
if (event.data == YT.PlayerState.ENDED)
{
console.log("END!");
clearTimeout(timeout_setter);
}
else
{
console.log(event.data);
}
}
</script>
</body>
</html>
With your CSS:
body {
background-color: #0f0f17;
margin: 0px;
width: 100%;
}
.container-middle-third{
margin-top: 20px;
margin-left: 155px;
}
body,
textarea,
input {
font: 13px "Raleway", sans-serif;
color: #ffffff;
}
.bar{
height: 80px;
width: 100%;
background-color: #15151d;
}
.DJ-text{
font-weight: 700;
/*position:relative;*/
text-transform: uppercase;
}
.Chat-text{
font-weight: 700;
text-transform: uppercase;
}
.DJ-underline{
width: 850px;
height: 1px;
position:relative;top:10px;
background-color: #3f3f45;
margin: 0px 0px 40px;
}
.Chat-underline{
width: 100%;
position:relative;
/*left:-140px;*/
float:right;
height: 1px;
position:relative;top:10px;
background-color: #3f3f45;
margin: 0px 0px 40px;
}
.transparent-layer{
width: 850px;
height: 477px;
pointer-events: none;
background-color: #ffffff;
}
.ad{
width: 728px;
height: 90px;
border: 1px solid #000000;
margin-left: 11px;
margin-top: 20px;
}
.chat {
min-width: 400px;
margin: 0px 0px 0px 135px;
}
.chat-messages,
.chat-textarea,
.chat-name {
border: 1px solid #1a1a23;
background-color: #1a1a23;
}
.userName{
font-weight: 700;
color: #079ce0;
}
.chat-messages {
width:380px;
height:400px;
overflow-y:scroll;
padding:10px;
}
.chat-message {
margin-bottom:10px;
}
.info-rect{
height: 40px;
width: 180px;
padding:10px;
max-width: 100%;
margin:0;
border:0;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
text-transform: uppercase;
background-color: #15151d
}
.chat-name{
height: 40px;
max-width: 100%;
width: 180px;
padding:10px;
border:0;
margin:0;
font-weight: 700;
text-transform: uppercase;
float:left;
text-align: center;
}
.chat textarea {
width:380px;
padding:10px;
margin:0;
border-top:0;
max-width:100%;
border-top: 1px solid #0f0f17;
border-bottom: 1px solid #1a1a23;
border-right: 1px solid #1a1a23;
border-left: 1px solid #1a1a23;
background-color: #1a1a23;
}
.chat-status {
color: #bbb;
opacity: 0;
background-color: #0f0f17;
}
.info-rect,
.chat textarea,
.chat-name {
max-width: 100%;
}
.bottom-bar{
position: fixed;
bottom: 0;
width: 100%;
}
.thumbnail{
width: 80px;
height: 80px;
background-color: #ffffff
}
.title-bar{
width:1000px;
height: 80px;
background-color: #1a1a23;
}
.song-name{
font-weight: 700;
text-transform: uppercase;
margin-left: 30px;
margin-top: 25px;
}
.dj-playing{
margin-left: 30px;
}
.progress-background{
width: 1000px;
height: 4px;
background-color: #313139;
position: fixed;
bottom: 0;
}
.progress-bar{
width: 400px;
height: 4px;
background-color: #fa1d57;
position: fixed;
bottom: 0;
}
.subscribe{
width: 520px;
height: 80px;
background-color: #15151d;
}
Or just look at the result there :
http://lespointscom.com/a/misc/demo/2016_06_19/main.html
IFrame player API reference:
https://developers.google.com/youtube/iframe_api_reference#Loading_a_Video_Player

Related

Trying to get a <div> to appear when I hover on another <a> element. What is my problem?

I've found answers to the problem on this site and have implemented the techniques suggested, but I really cannot see what I am missing. Is there something in the larger setup of the code that is preventing me from getting this to work or am I just blind? Is it because I already have another action taking place for hovers over <a>?
Relevant code is
.box2{
display:none;
}
a{
border-bottom:1px dotted;
}
a:hover{
border-bottom:1px solid;
}
.topics:hover + .box2{
display:flex;
}
<p>... interested in a <a class="topics">wide array of topics</a> ... </p>
<div class="box2">A list of topics</div>
https://codepen.io/brxtn/pen/KKKKzXy
<!---GRAIN JAVA START--->
var viewWidth,
viewHeight,
canvas = document.getElementById("canvas"),
ctx;
// change these settings
var patternSize = 64,
patternScaleX = 1,
patternScaleY = 1,
patternRefreshInterval = 4,
patternAlpha = 25; // int between 0 and 255,
var patternPixelDataLength = patternSize * patternSize * 4,
patternCanvas,
patternCtx,
patternData,
frame = 0;
window.onload = function() {
initCanvas();
initGrain();
requestAnimationFrame(loop);
};
// create a canvas which will render the grain
function initCanvas() {
viewWidth = canvas.width = canvas.clientWidth;
viewHeight = canvas.height = canvas.clientHeight;
ctx = canvas.getContext('2d');
ctx.scale(patternScaleX, patternScaleY);
}
// create a canvas which will be used as a pattern
function initGrain() {
patternCanvas = document.createElement('canvas');
patternCanvas.width = patternSize;
patternCanvas.height = patternSize;
patternCtx = patternCanvas.getContext('2d');
patternData = patternCtx.createImageData(patternSize, patternSize);
}
// put a random shade of gray into every pixel of the pattern
function update() {
var value;
for (var i = 0; i < patternPixelDataLength; i += 4) {
value = (Math.random() * 255) | 0;
patternData.data[i] = value;
patternData.data[i + 1] = value;
patternData.data[i + 2] = value;
patternData.data[i + 3] = patternAlpha;
}
patternCtx.putImageData(patternData, 0, 0);
}
// fill the canvas using the pattern
function draw() {
ctx.clearRect(0, 0, viewWidth, viewHeight);
ctx.fillStyle = ctx.createPattern(patternCanvas, 'repeat');
ctx.fillRect(0, 0, viewWidth, viewHeight);
}
function loop() {
if (++frame % patternRefreshInterval === 0) {
update();
draw();
}
requestAnimationFrame(loop);
}
<!---GRAIN JAVA END--->
<!---LEAF JAVA START--->
let leaf = false;
const leaf_animation = () => {
if (!leaf) {
document.querySelector(".scale-in-hor-left").style.display = "block";
leaf = true;
} else {
document.querySelector(".scale-in-hor-left").style.display = "none";
leaf = false;
}
}
document.querySelector("#menuleaf").addEventListener("click", leaf_animation);
<!---LEAF JAVA END--->
body {
background-size: 70px 70px;
background-image: linear-gradient(to right, grey 1px, transparent 1px), linear-gradient(to bottom, grey 1px, transparent 1px);
font-family: Quicksand;
}
#canvas {
position: absolute;
padding: 0;
margin: 0;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 80%;
}
h1 {
font-family: Quicksand;
font-weight: normal;
font-color: grey;
position: relative;
}
p {
font-color: grey;
font-size: 11pt;
margin: 0px;
}
.box1 {
display: flex;
flex-direction: column;
position: static;
float: left;
color: black;
border: 1px;
border-style: solid;
border-color: grey;
width: 399px;
height: 280px;
margin-left: 62px;
margin-top: 62px;
padding-left: 20px;
background: white;
}
.box2 {
display: none;
flex-direction: column;
position: static;
float: left;
color: black;
font-size: 9pt;
text-align: justify;
border: 1px;
border-style: solid;
border-color: grey;
width: 331px;
height: 121px;
margin-left: 69px;
margin-top: 132px;
padding: 9px;
background: white;
}
.topics:hover+.box2 {
display: flex;
}
#menuleaf {
cursor: help;
}
#menuleaf:hover,
#menuleaf:focus {
margin-left: 2.5px;
}
menu {
width: 200px;
position: absolute;
bottom: 0px;
left: 0px;
}
ul {
list-style-type: none;
line-height: 10px;
padding: 0px;
}
li {
float: left;
padding: 5px;
}
a {
position: relative;
border-bottom: 1px dotted;
text-decoration: none;
color: black;
font-size: 10pt;
}
a:hover {
border-bottom: 1px solid;
}
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Quicksand|Raleway|Titillium+Web&display=swap" rel="stylesheet">
</head>
<body>
<canvas id="canvas"></canvas>
<div class="box1">
<h1>Brixton Sandhals
<img id="menuleaf" src="https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/microsoft/209/seedling_1f331.png" height="15px"></h1>
<p><em>"Up here my eyes are green leaves, unseeing."</em></p>
<br>
<p>Hello! I am a born and raised Canadian living, working, writing, and musing about a <a class="topics">wide array of topics</a> in Shiga, Japan.</p>
<div class=menu>
<ul>
<li>🦠quarantine</li>
<li>are.na</li>
<li>twitter</li>
<li>insta</li>
<li>special.fish</li>
</ul>
</div>
</div>
<!---endbox-->
<div class=box2>✨poetry, bodybuiling, canadian literature, japanese literature, language learning, using linguistics to learn languages, translation as collaboration, techniques for learning chinese, korean, and japanese in tandem, psychoanalysis, religion, the anthropology
and pyschology of religion, scandinavia, astrology, theopoetics, aesthetics, somaesthetics, hermeneutics, the kyoto school, design, the history of the web, the complex plane, and set theory.
</div>
</body>
</html>
I would use script:
NOTE: <a data-target="quarentine" href="/quarantine.html">quarantine</a>
const hover = function(tgt,over) {
if (tgt.tagName.toUpperCase() === "A") {
const id = tgt.getAttribute("data-target");
if (id) {
const div = document.getElementById(id);
if (div) div.classList.toggle("show",over)
}
}
};
document.querySelector(".menu")
.addEventListener("mouseover",function(e) { hover(e.target,true) })
document.querySelector(".menu")
.addEventListener("mouseout",function(e) { hover(e.target) })
<!---GRAIN JAVA START--->
var viewWidth,
viewHeight,
canvas = document.getElementById("canvas"),
ctx;
// change these settings
var patternSize = 64,
patternScaleX = 1,
patternScaleY = 1,
patternRefreshInterval = 4,
patternAlpha = 25; // int between 0 and 255,
var patternPixelDataLength = patternSize * patternSize * 4,
patternCanvas,
patternCtx,
patternData,
frame = 0;
window.onload = function() {
initCanvas();
initGrain();
requestAnimationFrame(loop);
};
// create a canvas which will render the grain
function initCanvas() {
viewWidth = canvas.width = canvas.clientWidth;
viewHeight = canvas.height = canvas.clientHeight;
ctx = canvas.getContext('2d');
ctx.scale(patternScaleX, patternScaleY);
}
// create a canvas which will be used as a pattern
function initGrain() {
patternCanvas = document.createElement('canvas');
patternCanvas.width = patternSize;
patternCanvas.height = patternSize;
patternCtx = patternCanvas.getContext('2d');
patternData = patternCtx.createImageData(patternSize, patternSize);
}
// put a random shade of gray into every pixel of the pattern
function update() {
var value;
for (var i = 0; i < patternPixelDataLength; i += 4) {
value = (Math.random() * 255) | 0;
patternData.data[i] = value;
patternData.data[i + 1] = value;
patternData.data[i + 2] = value;
patternData.data[i + 3] = patternAlpha;
}
patternCtx.putImageData(patternData, 0, 0);
}
// fill the canvas using the pattern
function draw() {
ctx.clearRect(0, 0, viewWidth, viewHeight);
ctx.fillStyle = ctx.createPattern(patternCanvas, 'repeat');
ctx.fillRect(0, 0, viewWidth, viewHeight);
}
function loop() {
if (++frame % patternRefreshInterval === 0) {
update();
draw();
}
requestAnimationFrame(loop);
}
<!---GRAIN JAVA END--->
<!---LEAF JAVA START--->
let leaf = false;
const leaf_animation = () => {
if (!leaf) {
document.querySelector(".scale-in-hor-left").style.display = "block";
leaf = true;
} else {
document.querySelector(".scale-in-hor-left").style.display = "none";
leaf = false;
}
}
document.querySelector("#menuleaf").addEventListener("click", leaf_animation);
<!---LEAF JAVA END--->
body {
background-size: 70px 70px;
background-image: linear-gradient(to right, grey 1px, transparent 1px), linear-gradient(to bottom, grey 1px, transparent 1px);
font-family: Quicksand;
}
#canvas {
position: absolute;
padding: 0;
margin: 0;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 80%;
}
h1 {
font-family: Quicksand;
font-weight: normal;
font-color: grey;
position: relative;
}
p {
font-color: grey;
font-size: 11pt;
margin: 0px;
}
.box1 {
display: flex;
flex-direction: column;
position: static;
float: left;
color: black;
border: 1px;
border-style: solid;
border-color: grey;
width: 399px;
height: 280px;
margin-left: 62px;
margin-top: 62px;
padding-left: 20px;
background: white;
}
.box2 {
display: none;
flex-direction: column;
position: static;
float: left;
color: black;
font-size: 9pt;
text-align: justify;
border: 1px;
border-style: solid;
border-color: grey;
width: 331px;
height: 121px;
margin-left: 69px;
margin-top: 132px;
padding: 9px;
background: white;
}
.topics:hover+.box2 {
display: flex;
}
#menuleaf {
cursor: help;
}
#menuleaf:hover,
#menuleaf:focus {
margin-left: 2.5px;
}
menu {
width: 200px;
position: absolute;
bottom: 0px;
left: 0px;
}
ul {
list-style-type: none;
line-height: 10px;
padding: 0px;
}
li {
float: left;
padding: 5px;
}
a {
position: relative;
border-bottom: 1px dotted;
text-decoration: none;
color: black;
font-size: 10pt;
}
a:hover {
border-bottom: 1px solid;
}
.show { display: flex }
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Quicksand|Raleway|Titillium+Web&display=swap" rel="stylesheet">
</head>
<body>
<canvas id="canvas"></canvas>
<div class="box1">
<h1>Brixton Sandhals
<img id="menuleaf" src="https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/microsoft/209/seedling_1f331.png" height="15px"></h1>
<p><em>"Up here my eyes are green leaves, unseeing."</em></p>
<br>
<p>Hello! I am a born and raised Canadian living, working, writing, and musing about a <a class="topics">wide array of topics</a> in Shiga, Japan.</p>
<div class=menu>
<ul>
<li>🦠<a data-target="quarentine" href="/quarantine.html">quarantine</a></li>
<li><a data-target="arena" href="http://are.na/brixton-sandhals/">are.na</a></li>
<li>twitter</li>
<li>insta</li>
<li>special.fish</li>
</ul>
</div>
</div>
<!---endbox-->
<div id="quarentine" class=box2>✨poetry, bodybuiling, canadian literature, japanese literature, language learning, using linguistics to learn languages, translation as collaboration, techniques for learning chinese, korean, and japanese in tandem, psychoanalysis, religion, the anthropology
and pyschology of religion, scandinavia, astrology, theopoetics, aesthetics, somaesthetics, hermeneutics, the kyoto school, design, the history of the web, the complex plane, and set theory.
</div>
<div id="arena" class=box2>bla bla bla</div>
</body>
</html>

HTML elements won't align properly on mobile

The html elements on this simple to do list app i'm making won't properly align themselves when ran on mobile. Essentially when on mobile, the h1 tag should be in the center of the screen as well as the input box and add button under it and the tasks being added to the page, instead on mobile everything is off alignment. Any fixes?
let task;
let text;
let addTask;
let list;
let taskNo = 0;
let remove;
let input = document.getElementById('message');
let btn = document.getElementById('btn');
input.addEventListener("keypress", function() {
if (event.keyCode == 13) {
if (input.value === "") {
alert("Please enter a task!");
} else {
createTask();
}
}
});
btn.onclick = function() {
if (input.value === "") {
alert("Please enter a task!");
} else {
createTask();
}
};
function createTask() {
task = input.value;
addTask = document.createElement('li');
text = document.createTextNode(task);
addTask.appendChild(text);
addTask.classList.add("task");
taskNo++;
addTask.id = taskNo;
document.getElementById("taskList").appendChild(addTask);
input.value = "";
let list = document.getElementsByClassName("task");
[...list].forEach(b => {
b.addEventListener("click", () => {
remove = document.getElementById(b.id);
remove.parentNode.removeChild(remove);
});
});
}
html, body{
margin: 0;
padding: 0;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
background-color: #29313d;
color: white;
}
#container {
width: 100%;
}
h1{
text-align: center;
font-size: 44px;
}
#input{
margin: auto;
text-align: center;
}
#message, #btn{
display: inline-block;
height: 100%;
margin-top: 10px;
padding: 0;
float: left;
-webkit-box-sizing: border-box;
}
#message{
background-color: #333;
color: white;
border: 4px solid coral;
padding-left: 10px;
width: 75%;
height: 50px;
border-radius: 10px;
}
#btn{
font-size: 20px;
background-color: coral;
border: 4px solid coral;
color: black;
margin-left: 5%;
width: 20%;
height: 50px;
border-radius: 10px;
}
#btn:focus{
outline: none;
}
#message:focus{
outline: none;
}
#input{
height: 50px;
width: 400px;
}
#taskList{
list-style-type: none;
padding: 0;
margin-top: 50px;
}
.task {
margin: auto;
width: 85%;
margin-top: 5px;
padding: 10px;
border: 4px solid coral;
background-color: #333;
color: white;
border-radius: 10px;
}
#media(max-width: 600px) {
#container {
width: 80%;
}
h1{
margin: auto;
}
#message{
width: 100%;
}
#btn{
display: none;
}
.task{
width: 100%;
margin-left: 0;
margin-right: 0;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=10">
<link href="resources/style.css" rel="stylesheet" type="text/css">
<link href="resources/logo.png" rel="shortcut icon" type="image/png">
<title>Jennis App</title>
</head>
<body>
<div id="container">
<h1>To Do List</h1>
<div id="input">
<div class="input-group">
<input type="text" id="message" placeholder="Please enter a new task">
</div>
<div class="input-group">
<input type="button" id="btn" value="Add">
</div>
</div>
<ul id="taskList">
</ul>
</div>
<script src="resources/code.js" type="text/javascript"></script>
</body>
</html>
you need to make some css changes in media.
Center the container for small device using margin
Remove display: none for #btn in media query
Use flex to align add button for small device
clearfix the .input-group using before and after
let task;
let text;
let addTask;
let list;
let taskNo = 0;
let remove;
let input = document.getElementById('message');
let btn = document.getElementById('btn');
input.addEventListener("keypress", function() {
if (event.keyCode == 13) {
if (input.value === "") {
alert("Please enter a task!");
} else {
createTask();
}
}
});
btn.onclick = function() {
if (input.value === "") {
alert("Please enter a task!");
} else {
createTask();
}
};
function createTask() {
task = input.value;
addTask = document.createElement('li');
text = document.createTextNode(task);
addTask.appendChild(text);
addTask.classList.add("task");
taskNo++;
addTask.id = taskNo;
document.getElementById("taskList").appendChild(addTask);
input.value = "";
let list = document.getElementsByClassName("task");
[...list].forEach(b => {
b.addEventListener("click", () => {
remove = document.getElementById(b.id);
remove.parentNode.removeChild(remove);
});
});
}
html, body{
margin: 0;
padding: 0;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
background-color: #29313d;
color: white;
}
#container {
width: 100%;
}
h1{
text-align: center;
font-size: 44px;
}
#input{
margin: auto;
text-align: center;
}
#message, #btn{
display: inline-block;
height: 100%;
margin-top: 10px;
padding: 0;
float: left;
-webkit-box-sizing: border-box;
}
#message{
background-color: #333;
color: white;
border: 4px solid coral;
padding-left: 10px;
width: 75%;
height: 50px;
border-radius: 10px;
}
#btn{
font-size: 20px;
background-color: coral;
border: 4px solid coral;
color: black;
margin-left: 5%;
width: 20%;
height: 50px;
border-radius: 10px;
}
#btn:focus{
outline: none;
}
#message:focus{
outline: none;
}
#input{
height: 50px;
width: 400px;
}
#taskList{
list-style-type: none;
padding: 0;
margin-top: 50px;
}
.task {
margin: auto;
width: 85%;
margin-top: 5px;
padding: 10px;
border: 4px solid coral;
background-color: #333;
color: white;
border-radius: 10px;
}
#media(max-width: 600px) {
#container {
width: 80%;
margin: 0 auto; /* to align center */
}
h1{
margin: auto;
}
#message{
width: 100%;
}
#btn{
/* display: none; */
}
.task{
width: 100%;
margin-left: 0;
margin-right: 0;
}
/*** Additional css ***/
.input-group.flex {
display: flex;
justify-content: center;
}
.input-group:before, .input-group:after {
content: "";
display: table;
clear: both;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=10">
<link href="resources/style.css" rel="stylesheet" type="text/css">
<link href="resources/logo.png" rel="shortcut icon" type="image/png">
<title>Jennis App</title>
</head>
<body>
<div id="container">
<h1>To Do List</h1>
<div id="input">
<div class="input-group">
<input type="text" id="message" placeholder="Please enter a new task">
</div>
<!-- Added one additional class -->
<div class="input-group flex">
<input type="button" id="btn" value="Add">
</div>
</div>
<ul id="taskList">
</ul>
</div>
<script src="resources/code.js" type="text/javascript"></script>
</body>
</html>
working fiddle here

Extract YouTube Thumbnails From Videos Within A Playlist & Display On Webpage

My webpage plays a YouTube playlist and displays the track name at the bottom (spent most of the day on that), I figured it would be great to have a thumbnail of the specific video playing from the playlist displayed at the bottom next to the track title. I understand how to do this for a specific video, but how would I implement this for a playlist of videos? It is important that the image is refreshed for each new song that is played.
Here is a jsfiddle with my current work: https://jsfiddle.net/ruumL5s7/
ALSO, I am having issues with vertically aligning the video and chat divs between the top and bottom bar. I'm also running into issues with the bottom bar not staying a 'full' bar when the screen is resized (the different divs all break apart), I've tried a couple ideas to prevent that, with no avail. So any assistance is greatly appreciated!
Thank you!
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Chat</title>
<link rel="stylesheet" href="main.css">
</head>
<div class="all-content">
<body>
<div class="header-bar">
<div class="bar">
<img src="C:\Users\jlewa\Desktop\assets\affinity_fm_only_letters.png" class="top-logo" style="float: left;">
<ul class="standard-nav" style="float: left;">
<li>Home</li>
<li>Lyrics Hub</li>
<li>Affinity LIVE</li>
<li>Merchandise</li>
</ul>
</div>
<div class="dropshadow"></div>
</div>
<div class="container-middle-third">
<div class="youtube-video" style="float: left;">
<div class="DJ-text">Affinity FM DJ Room</div>
<div class="DJ-underline"></div>
<div id="player" style="width: 1280px; height: 720px;"></div></div>
</div>
<div class="chat" style="float: left;">
<div class="Chat-text">Chat</div>
<div class="Chat-underline"></div>
<input type="text" class="chat-name" placeholder="Chat">
<div class="info-rect">Info</div>
<div class="chat-messages"></div>
<textarea placeholder="Join the conversation..."></textarea>
<div class="chat-status">Status: <span>Idle</span></div>
</div>
<div class="bottom-bar">
<div class="thumbnail" id="thumbnail" style="float: left"></div>
<div class="title-bar" style="float: left;">
<div class="title" id="title"></div>
<div class="dj-playing">Affinity FM is playing</div>
<div class="progress-background">
<div id="progress-bar" class="progress-bar"></div>
</div>
</div>
<div class="subscribe" style="float: left;">
<div class="g-ytsubscribe" data-channel="SAMusicPlaylist" data-layout="full" data-theme="dark" data-count="default"></div>
</div>
</div>
<script src="http://127.0.0.1:8080/socket.io/socket.io.js"></script>
<script src="https://apis.google.com/js/platform.js"></script>
<script>
(function() {
var getNode = function(s) {
return document.querySelector(s);
},
// Get required nodes
status = getNode('.chat-status span'),
messages = getNode('.chat-messages'),
textarea = getNode('.chat textarea'),
chatName = getNode('.chat-name'),
statusDefault = status.textContent,
setStatus = function(s){
status.textContent = s;
if(s !== statusDefault){
var delay = setTimeout(function(){
setStatus(statusDefault);
clearInterval(delay);
}, 3000);
}
};
//try connection
try{
var socket = io.connect('http://127.0.0.1:8080');
} catch(e){
//Set status to warn user
}
if(socket !== undefined){
//Listen for output
socket.on('output', function(data){
if(data.length){
//Loop through results
for(var x = 0; x < data.length; x = x + 1){
var message = document.createElement('div');
message.setAttribute('class', 'chat-message');
message.textContent = ': ' + data[x].message;
var name=document.createElement('span');
name.setAttribute('class', 'userName');
name.textContent = data[x].name;
message.insertBefore(name, message.firstChild);
//Append
messages.appendChild(message);
messages.insertBefore(message, messages.firstChild);
}
}
});
//Listen for a status
socket.on('status', function(data){
setStatus((typeof data === 'object') ? data.message : data);
if(data.clear === true){
textarea.value = '';
}
});
//Listen for keydown
textarea.addEventListener('keydown', function(event){
var self = this,
name = chatName.value;
if(event.which === 13 && event.shiftKey === false){
socket.emit('input', {
name: name,
message: self.value
});
}
});
}
})();
</script>
<script>
var time_total;
var timeout_setter;
var player;
var tag = document.createElement("script");//This code loads the IFrame Player API code asynchronously
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
//This function creates an <iframe> (and YouTube player) OR uses the iframe if it exists at the "player" element after the API code downloads
function onYouTubeIframeAPIReady()
{
player = new YT.Player("player",
{
height: "853",
width: "480",
/* videoId: "GGmxVDXM5X2UxaP9PvWQ4Z171DXyGcq", */
playerVars: {
listType:'playlist',
list: 'PL_GGmxVDXM5X2UxaP9PvWQ4Z171DXyGcq',
controls: '0',
html5: '1',
cc_load_policy: '0',
disablekb: '1',
iv_load_policy: '3',
modestbranding: '1',
showinfo: '0',
rel: '0',
},
events:
{
"onReady": onPlayerReady,
"onStateChange": onPlayerStateChange
}
});
}
var num = (1 + Math.floor(Math.random() * 10));
//The API will call this function when the video player is ready
function onPlayerReady(event)
{
event.target.playVideo();
time_total = convert_to_mins_and_secs(player.getDuration(), 1);
loopy();
player.addEventListener('onStateChange', 'onPlayerStateChange');
player.setShuffle( {
'shufflePlaylist': 1
} );
}
function loopy()
{
var current_time = convert_to_mins_and_secs(player.getCurrentTime(), 0);
document.getElementById("progress-bar").style.width = (player.getCurrentTime()/player.getDuration())*100+"%";
console.log( current_time + " / " + time_total);
timeout_setter = setTimeout(loopy, 300);
}
function convert_to_mins_and_secs(seconds, minus1)
{
var mins = (seconds>=60) ?Math.round(seconds/60):0;
var secs = (seconds%60!=0) ?Math.round(seconds%60):0;
var secs = (minus1==true) ?(secs-1):secs; //Youtube always displays 1 sec less than its duration time!!! Then we have to set minus1 flag to true for converting player.getDuration()
var time = mins + ":" + ((secs<10)?"0"+secs:secs);
return time;
}
// 5. The API calls this function when the player's state changes
function onPlayerStateChange(event)
{
if (event.data == YT.PlayerState.ENDED)
{
console.log("END!");
clearTimeout(timeout_setter);
document.getElementById("progress-bar").style.cssText = "transition: none;";
}
else if (event.data == YT.PlayerState.PLAYING)
{
console.log("PLAYING");
loopy();
document.getElementById("progress-bar").style.cssText = "transition: all 300ms linear 0s;";
console.log(player.getPlayerState());
if (player.getPlayerState() == 1) {
document.getElementById( "title" ).innerText = player.getVideoData().title;
}
}
else if (event.data == YT.PlayerState.PAUSED)
{
event.target.playVideo();
console.log("PLAUSED");
}
else
{
console.log(event.data);
}
}
</script>
</body>
</div>
</html>
CSS:
body {
background-color: #0f0f17;
margin: 0px;
width: 100%;
}
.container-middle-third{
margin-top: 20px;
margin-left: 70px;
}
body,
textarea,
input {
font: 13px "Raleway", sans-serif;
color: #ffffff;
}
.all-content{
width: 1920px;
display: block;
margin-left: auto;
margin-right: auto;
}
.bar{
height: 90px;
width: 1920px;
background-color: #15151d;
}
.top-logo{
max-height: 100%;
max-width: 100%;
margin-left: 4%
}
/*li{
display: inline;
padding-right: 20px;
}
.standard-nav {
list-style: none;
padding: 0;
text-transform: uppercase;
line-height: 13px;
font-weight: 700;
margin-left: 63%;
max-height: 100%;
} */
.DJ-text{
font-weight: 700;
/*position:relative;*/
text-transform: uppercase;
}
.Chat-text{
font-weight: 700;
text-transform: uppercase;
}
.DJ-underline{
width: 1280px;
height: 1px;
position:relative;top:10px;
background-color: #3f3f45;
margin: 0px 0px 40px;
}
.Chat-underline{
width: 100%;
position:relative;
/*left:-140px;*/
float:right;
height: 1px;
position:relative;top:10px;
background-color: #3f3f45;
margin: 0px 0px 40px;
}
.youtube-video{
position: relative;
}
.transparent-layer{
width: 850px;
height: 477px;
pointer-events: none;
background-color: #ffffff;
}
.ad{
width: 728px;
height: 90px;
border: 1px solid #000000;
margin-left: 11px;
margin-top: 20px;
}
.chat {
position: relative;
min-width: 400px;
margin: 0px 0px 0px 112px;
}
.chat-messages,
.chat-textarea,
.chat-name {
border: 1px solid #1a1a23;
background-color: #1a1a23;
}
.userName{
font-weight: 700;
color: #079ce0;
}
.chat-messages {
width:380px;
height:586px;
overflow-y:scroll;
padding:10px;
}
.chat-message {
margin-bottom:10px;
}
.info-rect{
height: 40px;
width: 180px;
padding:10px;
max-width: 100%;
margin:0;
border:0;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
text-transform: uppercase;
background-color: #15151d
}
.chat-name{
height: 40px;
max-width: 100%;
width: 180px;
padding:10px;
border:0;
margin:0;
font-weight: 700;
text-transform: uppercase;
float:left;
text-align: center;
}
.chat textarea {
width:380px;
padding:10px;
margin:0;
border-top:0;
max-width:100%;
border-top: 1px solid #0f0f17;
border-bottom: 1px solid #1a1a23;
border-right: 1px solid #1a1a23;
border-left: 1px solid #1a1a23;
background-color: #1a1a23;
}
.chat-status {
color: #bbb;
opacity: 0;
background-color: #0f0f17;
}
.info-rect,
.chat textarea,
.chat-name {
max-width: 100%;
}
.bottom-bar{
position: absolute;
bottom: 0;
display:table;
}
.thumbnail{
width: 90px;
height: 80px;
opacity: 0.2;
background-color: #ffffff;
}
.title-bar{
width:1372px;
height: 80px;
background-color: #1a1a23;
}
.title{
font-weight: 700;
text-transform: uppercase;
margin-left: 30px;
margin-top: 25px;
}
.dj-playing{
margin-left: 30px;
}
.progress-background{
width: 1372px;
height: 3px;
background-color: #313139;
position: fixed;
bottom: 0;
}
.progress-bar{
height: 3px;
width: 0px;
transition: all 300ms linear;
background-color: #fa1d57;
bottom: 0;
}
.subscribe{
width: 458px;
height: 80px;
background-color: #15151d;
display:table-cell;
}
.g-ytsubscribe{
width: 450px;
display: block;
margin-left: auto;
margin-right: auto;
}
This time you have to use a key with the Youtube API 3.
You can do that with either js or Php.
Php
<?
$api_key = "AIzaSyDRfgPj9a2vnckVkSGoKktNfrozbMvjkdw";
$play_list_id = "PLcV3JzAz3r32-on4upkyAv0VtvYXAl-Nz";
$url = "https://www.googleapis.com/youtube/v3/playlists?part=snippet&id=" . $play_list_id;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response_raw = curl_exec($ch);
$response = json_decode($response_raw);
echo "default image :" . $response->items[0]->snippet->thumbnails->default->url;
echo "<br />\n<br />\n";
echo "medium image :" . $response->items[0]->snippet->thumbnails->medium->url;
echo "<br />\n<br />\n";
echo "maxres image :" . $response->items[0]->snippet->thumbnails->maxres->url;
echo "<br />\n<br />\n";
echo print_r($response, 1);
?>
The most important thing in the script is the url with the query parameters. Just remember to replace the $api_key, and the $play_list_id with your own.
Now with javascript, it's almost the same thing.
JS
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script>
function make_request()
{
var response = "";
var response1 = "";
var api_key = "AIzaSyBaS4_vwohJW7Ndb9EkjSqsoD75O4f4jXI";
var play_list_id = "PLcV3JzAz3r32-on4upkyAv0VtvYXAl-Nz";
var url = "https://www.googleapis.com/youtube/v3/playlists?part=snippet&id=" + play_list_id + "&key=" + api_key;
$.ajax
({
url: url,
dataType: "json",
type: "get",
async: false,
success: function(data)
{
response = JSON.stringify(data);
response1 = data;
}
});
alert(response1.items[0].snippet.thumbnails.default.url);
console.log(response1.items[0].snippet.thumbnails.default.url);
console.log(response);
}
function init()
{
gapi.client.setApiKey("AIzaSyBaS4_vwohJW7Ndb9EkjSqsoD75O4f4jXI");
gapi.client.load('youtube', 'v3').then(make_request);
}
</script>
<script src="https://apis.google.com/js/client.js?onload=init"></script>
Take a look at those in action :
http://lespointscom.com/a/misc/demo/2016_06_21/curl_any.php
http://lespointscom.com/a/misc/demo/2016_06_21/curl_any.zip
http://lespointscom.com/a/misc/demo/2016_06_21/gapi_1.html
But remember: when you do it with Php, you have to create a Google server key. When you do it with js, guess what? You do it with a browser key. But most important, remember to enable Youtube data api 3 in developers console!
Reference to get a KEY :
https://developers.google.com/api-client-library/javascript/start/start-js#choose-google-services

Div side-by-side alignment with YouTube video

While I understand that aligning two div's side by side is a common question, I am having a little bit of an issue getting the YouTube video and chat box to align next to each other. I should be using a span, since this would allow the chatbox in the same space as the youtube video correct? I'm still learning the ropes here in HTML. Here is what the page currently looks like:
Here is my current HTML code, the divs dealing with the youtube video is class name "youtube-video" and div dealing with the chat box is class "chat"
<!DOCTYPE html>
<html>
<head>
<title>Chat</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="header-bar">
<div class="bar"></div>
<div class="dropshadow"></div>
</div>
<div class="DJ-text">Affinity FM DJ Room
<span class="Chat-text">Chat</span>
<div class="DJ-underline"></div>
<div class="Chat-underline"></div></div>
<div class="youtube-video" style="float: left;">
<iframe width="900px" height="500px" src="https://www.youtube.com/embed/2GvIq2SpVFM" frameborder="0" allowfullscreen></iframe>
</div>
<div class="chat" style="float: left; padding: 0px 0px 0px 12px;">
<input type="text" class="chat-name" placeholder="Chat">
<div class="info-rect">Info</div>
<div class="chat-messages"></div>
<textarea placeholder="Join the conversation..."></textarea>
<div class="chat-status">Status: <span>Idle</span></div>
</div>
<script src="http://127.0.0.1:8080/socket.io/socket.io.js"></script>
<script>
(function() {
var getNode = function(s) {
return document.querySelector(s);
},
// Get required nodes
status = getNode('.chat-status span'),
messages = getNode('.chat-messages'),
textarea = getNode('.chat textarea'),
chatName = getNode('.chat-name'),
statusDefault = status.textContent,
setStatus = function(s){
status.textContent = s;
if(s !== statusDefault){
var delay = setTimeout(function(){
setStatus(statusDefault);
clearInterval(delay);
}, 3000);
}
};
//try connection
try{
var socket = io.connect('http://127.0.0.1:8080');
} catch(e){
//Set status to warn user
}
if(socket !== undefined){
//Listen for output
socket.on('output', function(data){
if(data.length){
//Loop through results
for(var x = 0; x < data.length; x = x + 1){
var message = document.createElement('div');
message.setAttribute('class', 'chat-message');
message.textContent = ': ' + data[x].message;
var name=document.createElement('span');
name.setAttribute('class', 'userName');
name.textContent = data[x].name;
message.insertBefore(name, message.firstChild);
//Append
messages.appendChild(message);
messages.insertBefore(message, messages.firstChild);
}
}
});
//Listen for a status
socket.on('status', function(data){
setStatus((typeof data === 'object') ? data.message : data);
if(data.clear === true){
textarea.value = '';
}
});
//Listen for keydown
textarea.addEventListener('keydown', function(event){
var self = this,
name = chatName.value;
if(event.which === 13 && event.shiftKey === false){
socket.emit('input', {
name: name,
message: self.value
});
}
});
}
})();
</script>
</body>
</html>
Here is my CSS for youtube-video and chat:
body {
background-color: #0f0f17;
margin: 0px;
width: 100%;
}
body,
textarea,
input {
font: 13px "Raleway", sans-serif;
color: #ffffff;
}
.bar{
height: 115px;
width: 100%;
background-color: #15151d;
}
.DJ-text{
font-weight: 700;
position:relative;left:50px;
position:relative;top:80px;
text-transform: uppercase;
}
.Chat-text{
position:relative;left:900px;
}
.DJ-underline{
width: 900px;
height: 1px;
position:relative;top:20px;
background-color: #3f3f45;
}
.Chat-underline{
width: 400px;
position:relative;left:-140px;
float:right;
height: 1px;
position:relative;top:20px;
background-color: #3f3f45;
}
/*.youtube-video{
position: relative; left: 50px;
position: relative; top: 130px;
}
.chat {
max-width: 400px;
background-color: #0f0f17;
position:relative;left:1093px;
position:relative;top:150px;
}*/
.chat-messages,
.chat-textarea,
.chat-name {
border: 1px solid #1a1a23;
background-color: #1a1a23;
}
.userName{
font-weight: 700;
color: #079ce0;
}
.chat-messages {
width:100%;
height:400px;
overflow-y:scroll;
padding:10px;
}
.chat-message {
margin-bottom:10px;
}
.info-rect{
height: 40px;
width: 180px;
padding:10px;
max-width: 100%;
margin:0;
border:0;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
text-transform: uppercase;
}
.chat-name{
height: 40px;
max-width: 100%;
width: 180px;
padding:10px;
border:0;
margin:0;
font-weight: 700;
text-transform: uppercase;
float:left;
text-align: center;
}
.chat textarea {
width:100%;
padding:10px;
margin:0;
border-top:0;
max-width:100%;
border-top: 1px solid #0f0f17;
border-bottom: 1px solid #1a1a23;
border-right: 1px solid #1a1a23;
border-left: 1px solid #1a1a23;
background-color: #1a1a23;
}
.chat-status {
color: #bbb;
background-color: #0f0f17;
}
.info-rect,
.chat textarea,
.chat-name {
max-width: 100%;
}
Using the code above supplied by #georges_user2251342, this is what the page looks like:
Here is the reference PSD: http://imgur.com/4XU62C9
It is true what they say! If I understand correctly, by centering, you mean to put 2 things side by side, next to each other so to speak.
In your case, the "youtube-video" element and the "chat" element need to be put side by side with percentages, yes. However, I would use 66% with 33% for percentages instead of 80% with 20%. Because your "chat" element doesn't look good with just 20%. It looks crunched up.
Look at these :
(66%-33%) http://lespointscom.com/a/misc/demo/2016_06_18/main_4.html
(80%-20%) http://lespointscom.com/a/misc/demo/2016_06_18/main_5.html
AGAIN THE NEW HTML :
<!DOCTYPE html>
<html>
<head>
<title>Chat</title>
<link rel="stylesheet" href="main6.css">
</head>
<body>
<div class="header-bar">
<div class="bar"></div>
<div class="dropshadow"></div>
</div>
<div class="container">
<div class="youtube-video">
<div class="DJ-text">Affinity FM DJ Room</div>
<div class="DJ-underline"></div>
<iframe class="iframe" src="https://www.youtube.com/embed/2GvIq2SpVFM" frameborder="0" allowfullscreen></iframe>
</div>
<div class="chat">
<div class="Chat-text">Chat</div>
<div class="Chat-underline"></div>
<input type="text" class="chat-name" placeholder="Chat">
<div class="info-rect">Info</div>
<div class="chat-messages"></div>
<textarea placeholder="Join the conversation..."></textarea>
<div class="chat-status">Status: <span>Idle</span></div>
</div>
</div>
<script src="http://127.0.0.1:8080/socket.io/socket.io.js"></script>
<script>
(function() {
var getNode = function(s) {
return document.querySelector(s);
},
// Get required nodes
status = getNode('.chat-status span'),
messages = getNode('.chat-messages'),
textarea = getNode('.chat textarea'),
chatName = getNode('.chat-name'),
statusDefault = status.textContent,
setStatus = function(s){
status.textContent = s;
if(s !== statusDefault){
var delay = setTimeout(function(){
setStatus(statusDefault);
clearInterval(delay);
}, 3000);
}
};
//try connection
try{
var socket = io.connect('http://127.0.0.1:8080');
} catch(e){
//Set status to warn user
}
if(socket !== undefined){
//Listen for output
socket.on('output', function(data){
if(data.length){
//Loop through results
for(var x = 0; x < data.length; x = x + 1){
var message = document.createElement('div');
message.setAttribute('class', 'chat-message');
message.textContent = ': ' + data[x].message;
var name=document.createElement('span');
name.setAttribute('class', 'userName');
name.textContent = data[x].name;
message.insertBefore(name, message.firstChild);
//Append
messages.appendChild(message);
messages.insertBefore(message, messages.firstChild);
}
}
});
//Listen for a status
socket.on('status', function(data){
setStatus((typeof data === 'object') ? data.message : data);
if(data.clear === true){
textarea.value = '';
}
});
//Listen for keydown
textarea.addEventListener('keydown', function(event){
var self = this,
name = chatName.value;
if(event.which === 13 && event.shiftKey === false){
socket.emit('input', {
name: name,
message: self.value
});
}
});
}
})();
</script>
</body>
</html>
AGAIN THE NEW CSS :
.youtube-video{
float: left;
width:66%;
}
.chat {
float: left;
width:33%;
}
.iframe {
width:98%;
min-height:500px;
}
.container {
width:98%;
}
body {
background-color: #0f0f17;
margin: 0px;
width: 100%;
}
body,
textarea,
input {
font: 13px "Raleway", sans-serif;
color: #ffffff;
}
.bar{
height: 115px;
width: 100%;
background-color: #15151d;
}
.DJ-text{
font-weight: 700;
/*position:relative;
left:50px;
top:80px;*/
text-transform: uppercase;
}
.Chat-text{
font-weight: 700;
/*position:relative;left:900px;*/
text-transform: uppercase;
}
.DJ-underline{
width: 98%;
height: 1px;
position:relative;top:20px;
background-color: #3f3f45;
margin: 0px 0px 50px;
}
.Chat-underline{
width: 100%;
position:relative;
/*left:-140px;*/
float:right;
height: 1px;
position:relative;top:20px;
background-color: #3f3f45;
margin: 0px 0px 50px;
}
.chat-messages,
.chat-textarea,
.chat-name {
border: 1px solid #1a1a23;
background-color: #1a1a23;
}
.userName{
font-weight: 700;
color: #079ce0;
}
.chat-messages {
width:95%;
height:400px;
overflow-y:scroll;
padding:10px;
}
.chat-message {
margin-bottom:10px;
}
.info-rect{
height: 40px;
width: 180px;
padding:10px;
max-width: 100%;
margin:0;
border:0;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
text-transform: uppercase;
}
.chat-name{
height: 40px;
max-width: 100%;
width: 180px;
padding:10px;
border:0;
margin:0;
font-weight: 700;
text-transform: uppercase;
float:left;
text-align: center;
}
.chat textarea {
width:95%;
padding:10px;
margin:0;
border-top:0;
max-width:100%;
border-top: 1px solid #0f0f17;
border-bottom: 1px solid #1a1a23;
border-right: 1px solid #1a1a23;
border-left: 1px solid #1a1a23;
background-color: #1a1a23;
}
.chat-status {
color: #bbb;
background-color: #0f0f17;
}
.info-rect,
.chat textarea,
.chat-name {
max-width: 100%;
}
#media only screen and (max-width: 772px) and (min-width: 0px)
{
.youtube-video{
width:100%;
}
.chat{
width:100%;
}
}
#media only screen and (max-width: 1254px) and (min-width: 0px)
{
.info-rect{
width:30%;
}
}
#media only screen and (max-width: 1054px) and (min-width: 0px)
{
.info-rect{
width:10%;
}
}
You can bring the chat box to the right by using position property.
Add this css for youtube-video
width:80%;
height:100%;
position:absolute;
left:0;
top:0;
Add this css for chat
width:20%;
height:100%;
position:absolute;
right:0;
top:0;
So, by doing this, you can bring the chat box to right.
Here is the Plnkr
Hope it works for you :)
Just put a float: left; to both divs :
<!DOCTYPE html>
<html>
<head>
<title>Chat</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="header-bar">
<div class="bar"></div>
<div class="dropshadow"></div>
</div>
<div class="DJ-text">Affinity FM DJ Room
<span class="Chat-text">Chat</span>
<div class="DJ-underline"></div>
<div class="Chat-underline"></div></div>
<div class="youtube-video" style="float: left;">
<iframe width="900px" height="500px" src="https://www.youtube.com/embed/2GvIq2SpVFM" frameborder="0" allowfullscreen></iframe>
</div>
<div class="chat" style="float: left; padding: 0px 0px 0px 12px;">
<input type="text" class="chat-name" placeholder="Chat">
<div class="info-rect">Info</div>
<div class="chat-messages"></div>
<textarea placeholder="Join the conversation..."></textarea>
<div class="chat-status">Status: <span>Idle</span></div>
</div>
<script src="http://127.0.0.1:8080/socket.io/socket.io.js"></script>
<script>
(function() {
var getNode = function(s) {
return document.querySelector(s);
},
// Get required nodes
status = getNode('.chat-status span'),
messages = getNode('.chat-messages'),
textarea = getNode('.chat textarea'),
chatName = getNode('.chat-name'),
statusDefault = status.textContent,
setStatus = function(s){
status.textContent = s;
if(s !== statusDefault){
var delay = setTimeout(function(){
setStatus(statusDefault);
clearInterval(delay);
}, 3000);
}
};
//try connection
try{
var socket = io.connect('http://127.0.0.1:8080');
} catch(e){
//Set status to warn user
}
if(socket !== undefined){
//Listen for output
socket.on('output', function(data){
if(data.length){
//Loop through results
for(var x = 0; x < data.length; x = x + 1){
var message = document.createElement('div');
message.setAttribute('class', 'chat-message');
message.textContent = ': ' + data[x].message;
var name=document.createElement('span');
name.setAttribute('class', 'userName');
name.textContent = data[x].name;
message.insertBefore(name, message.firstChild);
//Append
messages.appendChild(message);
messages.insertBefore(message, messages.firstChild);
}
}
});
//Listen for a status
socket.on('status', function(data){
setStatus((typeof data === 'object') ? data.message : data);
if(data.clear === true){
textarea.value = '';
}
});
//Listen for keydown
textarea.addEventListener('keydown', function(event){
var self = this,
name = chatName.value;
if(event.which === 13 && event.shiftKey === false){
socket.emit('input', {
name: name,
message: self.value
});
}
});
}
})();
</script>
</body>
</html>
and for a better look, add padding: 0px 0px 0px 12px; or a similar small padding to seperate both divs.
Add this css for youtube-video
width:80%;
float:left;
Add this css for chat
width:20%;
float:left;

How to make drag to a picture in that division?

I have this sample:
link
CODE HTML:
<div class="border">
<div id="i-choose">
<input type="file" name="file" id="file" class="inputfile">
<label for="file">Browse</label>
</div>
</div>
CODE CSS:
#i-choose {
float: left;
font-size: 17pt;
}
.inputfile {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;}
#i-choose label {
line-height: 0px;
font-size: 17pt;
margin-top: 12px;
height: auto;
color: #0096BD;
margin-left: 5px;
cursor: pointer;}
.border{
border:1px dashed grey;
overflow:hidden;
}
Basically what I want to do is shoot an image in the div and to be drop.
I put a picture more clearly understand.
How can I solve this problem? Does anyone have any idea?
Thanks in advance!
Please take a look at the sample JS code below:
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#blah').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
$("#file").change(function () {
readURL(this);
});
CSS:
#div1 {
border: 1px solid #aaaaaa;
padding: 10px;
min-height:70px;
width: 350px;
}
#i-choose {
float: left;
font-size: 17pt;
}
.inputfile {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
#i-choose label {
line-height: 0px;
font-size: 17pt;
margin-top: 12px;
height: auto;
color: #0096BD;
margin-left: 5px;
cursor: pointer;
}
.border {
border:1px dashed grey;
overflow:hidden;
}
and the associated HTML :
<form id="form1" runat="server">
<div class="border">
<div id="i-choose">
<input type='file' id="file" name="file" class="inputfile" />
<label for="file">Browse</label>
<img id="blah" src="#" alt="" draggable="true" ondragstart="drag(event)" />
</div>
</div>
JsFiddle