Jump to content
2Radon

I cannot ever put a slideshow in my page, please help!

Recommended Posts

Hi, I am trying to make this webpage for posting and viewing news. It will be shown on a big screen in our Hub. I've been having a super hard time with putting a proper slideshow in the HubWeb_HubPage.php one. I've tried copying in code from two other pre-made slideshows, but best I've got was a misaligned slideshow that didn't fit the top right area properly. And I made an embedded YouTube video appear and reappear on top of it periodically. So I decided to learn and do a simple one myself. What could go wrong if I'm writing the thing inside my webpage myself, right? Nothing happens. See for yourself. It's driving me mad already. My goal for the top right slideshow area is to have at least 5 images or videos sliding and autoplaying with the top right area filled as much as possible, though keeping normal proportions (to not stretch the image). So the whole webpage with news must be responsive and fill the screen it's on. The slideshow area is 70%/70% of the screen width (the webpage will be put on fullscreen on the display in Hub). But I can't even get the images sliding!

 

Please download the zipped folder from this link and check out the code and the page:

http://s000.tinyupload.com/index.php?file_id=60798650373352387766

 

I've also attached just the HubPage that has the slideshow code on it. This one is how far I could get it modifying the CSS values.

 

Thank you for your help!

<!DOCTYPE html><?phpif (!empty($_POST)) {file_put_contents('NewsLines.txt', $_POST['newsline'] . "____" . date("d.m") . "____" . "^^^^" . PHP_EOL, FILE_APPEND);}?><html>	<head>    <!-- load jQuery -->    <script src="jquery-1.11.3.min.js"></script>		<link rel="stylesheet" type="text/css" href="HubWeb_CSS.css">		</script>		<script type="text/javascript">			window.onload = function() {				fullClock();				newscaster();				updater();			}				$(document).ready(function() {							   		var currentPosition = 0;		var slideWidth = 500;		var slides = $('.slide');		var numberOfSlides = slides.length;		var slideShowInterval;		var speed = 3000;				slideShowInterval = setInterval(changePosition, speed);				slides.wrapAll('<div id="slidesHolder"></div>')				slides.css({ 'float' : 'left' });				$('#slidesHolder').css('width', slideWidth * numberOfSlides);						function changePosition() {			if(currentPosition == numberOfSlides - 1) {				currentPosition = 0;			} else {				currentPosition++;			}			moveSlide();		}						function moveSlide() {				$('#slidesHolder')				  .animate({'marginLeft' : slideWidth*(-currentPosition)});		}	});															function fullClock() {				var today=new Date();				var mon=today.getMonth();				var d=today.getDate();				var h=today.getHours();				var m=today.getMinutes();				var s=today.getSeconds();				var timeOfDay=(h<12)?"AM":"PM";								var period = "";				if (h == 8 && m >= 55 && m <= 59) {					period = "Registration";				} else if (h == 9) {					period = "Period 1";				} else if (h == 10) {					period = "Period 2";				} else if (h == 11 && m < 15) {					period = "Break";				} else if ((h == 11 && m >= 15) || (h == 12 && m < 15)) {					period = "Period 3";				} else if ((h == 12 && m >= 15) || (h == 13 && m < 15)) {					period = "Period 4";				} else if (h == 13 && m >= 15 && m < 50) {					period = "Lunch";				} else if ((h == 13 && m >= 50) || (h == 14 && m < 50)) {					period = "Period 5";				} else if ((h == 14 && m >= 50) || (h == 15 && m <= 35)) {					period = "Period 6";				} else {					period = "";				}								mon = mon + 1;				mon = checkTime(mon);				d = checkTime(d);				m = checkTime(m);				s = checkTime(s);				document.getElementById('date').innerHTML = d+"."+mon;				document.getElementById('clock').innerHTML = h+":"+m+":"+s;				document.getElementById('AMPM').innerHTML = timeOfDay;				document.getElementById('period').innerHTML = period;				var t = setTimeout(function(){fullClock()},500);			}			function checkTime(i) {				if (i<10) {i = "0" + i};  // add zero in front of numbers < 10				return i;			}						// VIDEO--------------------------------------------------------------------------------------------------------------------									function updater() {				setInterval(function() { newscaster() }, 1000);			}						function newscaster() {				$.ajax({					url: 'NewsLines.txt',					type:'POST',					success: function(m){					  allLines = m;					  allLines = allLines.split("r");					  					  // Splice loop reverse because splice messes up the index of the original array the loop is looking up					  for (var i = allLines.length-1; i >= 0; i--) {						checkLine = allLines[i].split("____");						if (checkLine[0].length <= 1) {							allLines.splice(i, 1);						}					  }					  					  textline = allLines[allLines.length - 1].split("____");					  document.getElementById('news1').innerHTML = textline[0];					  document.getElementById('date1').innerHTML = textline[1];					  					  textline = allLines[allLines.length - 2].split("____");					  document.getElementById('news2').innerHTML = textline[0];					  document.getElementById('date2').innerHTML = textline[1];					  					  textline = allLines[allLines.length - 3].split("____");					  document.getElementById('news3').innerHTML = textline[0];					  document.getElementById('date3').innerHTML = textline[1];					}				});			}						// clicking on a line or image in the Hub Page deletes that IMG in the directory or text line from the News Lines file			function deleteLine(Nr) {				var answer = confirm("Delete News Line " + Nr + "?");				if (answer) {					search = document.getElementById('news' + Nr).innerHTML + "____" + document.getElementById('date' + Nr).innerHTML;					$.post('HubWeb_Deleter.php', {search});				}			}					</script>	</head>	<body>		<div id="slideshow">			<div id="slideshowWindow">							<div class="slide">					<img src="Slideshow/banner01.jpg" />				</div><!--/slide-->								<div class="slide">					<img src="Slideshow/banner02.jpg" />				</div><!--/slide-->								<div class="slide">					<img src="Slideshow/banner03.jpg" />				</div><!--/slide-->						</div><!--/slideshowWindow-->		</div><!--/slideshow-->	  				<div id="side">					<div id="sideclock1" onclick="window.location='HubWeb_StaffPage.php';">				<p id="date"></p>				<p id="clock"></p>			</div>			<div id="sideclock2" onclick="window.location='HubWeb_StaffPage.php';">				<p id="AMPM"></p>				<p id="period"></p>			</div>		</div>		<!-- add current time and period number on side section, say if Student WiFi is ON? -->		<div = id="bottom">			<div id="line1" onclick="deleteLine('1')">				<img src="Contents/GreenStar.svg" id="star1">				<marquee id="news1" scrollamount=5>News line 1</marquee>				<p id="date1">01.01</p>			</div>			<div id="line2" onclick="deleteLine('2')">				<img src="Contents/GreenStar.svg" id="star2">				<marquee id="news2" scrollamount=5>News line 2</marquee>				<p id="date2">02.02</p>			</div>			<div id="line3" onclick="deleteLine('3')">				<img src="Contents/GreenStar.svg" id="star3">				<marquee id="news3" scrollamount=5>News line 3</marquee>				<p id="date3">03.03</p>			</div>		</div>	</body></html>

HubWeb_HubPage.php

HubWeb_CSS.css

Edited by davej

Share this post


Link to post
Share on other sites

You have an extra </script> tag that doesn't belong there, I'm not sure if there are any other errors like that though. Are you checking your browser's console for Javascript error messages?

Share this post


Link to post
Share on other sites

I've gotten to understand somewhat more those divs by using background colors and changing their sizes, but I still cannot figure out why, if I increate the .slide img CSS size any more they just stack in column, as you can see at around 40% they already stack. As if there was not enough space in their container, but I don't see which one no matter what I try.

I know there's no float: up or down, but changing to left doesn't help anyway.

 

#slideshow is the responsive portion of the page I want to have the slideshow appear in#slideshowWindow is the rectangle which will show the current portion of the slideshow (and it would fill the #slideshow area anyway)

.slide is a content container for a slideshow unit and I plan to add videos too (oh god! and if not, I'll make videos appear on top of #slideshow and disappear periodically, not a part of the slideshow)

.slide img is the styling of any images inside a .slide container

 

Edit: I got it, the problem was with the #slidesHolder div created by jQuery, I adjusted the width of that, and divided the .slide div width by the number of slides in CSS. (5 slides, each 20% width of #slidesHolder, makes it big enough and fits all)

 

But there are still a few problems. I wonder if I can center an image in that area vertically if it doesn't fill the area vertically, and fit an image vertically if it is vertically longer than it is wide (meaning that the bottom of the image is overflowing)?

 

And about videos... Can I pause the slideshow when an embedded or <video> tag video is autoplaying in one of the contents? Would it take a lot of hassle? My guess is putting a video on top of the slideshow and hiding it periodically would be much less hassle.

HubWeb_HubPage.php

HubWeb_CSS.css

Edited by 2Radon

Share this post


Link to post
Share on other sites

But there are still a few problems. I wonder if I can center an image in that area vertically if it doesn't fill the area vertically, and fit an image vertically if it is vertically longer than it is wide (meaning that the bottom of the image is overflowing)?

I'm not sure if there's a way with CSS to do all of that cleanly. One way with Javascript would be to put the image on the page, maybe in a hidden container, and then figure out the dimensions of it and whether or not it will fit. You could calculate the necessary top and bottom margins for it to be vertically centered, or adjust the height to make it fit.

And about videos... Can I pause the slideshow when an embedded or <video> tag video is autoplaying in one of the contents?

I believe the video element has certain events that you can use to figure out when it's done playing or when it gets paused or whatever, you can use those events to adjust the slideshow.

Share this post


Link to post
Share on other sites

I'm going to put the image aligning aside for future then.

Decided to go with YouTube embeds for videos. I'm still clueless on how to use the YouTube API as I don't see a download or link, or anything...

But I've changed the slidemaker() to have a loop now and change the element depending on if it finds the file name in dir.log is a .txt file or not. The .txt file contains the embed link and is then read and used as the source for the iframe element that is made with replaceWith().

Well, I first did it for one element, and then I decided to make it a loop and add var i to strings where I need to address the next element, but then it stopped working and it doesn't even get to the for loop so I added alerts to know where it is. And Igot just ajax success but no for loop alerts.

function slidemaker() {	$.post('HubWeb_Scanner.php');		$.ajax({		url: 'Slides/dir.log',		type:'POST',		success: function(m){			aFiles = m.split("rn");		  			alert("ajax success...");//			for (i = 1; i > 5; i++) {		  				alert("for.. start");//				var file = "Slides/" + aFiles[aFiles.length - (i + 1)];			  				alert(file);//				check = file.indexOf(".txt");			  				alert(check);//				if (check > 0) {			  					alert("is link");//					// Link for embed in TXT										alert("script tag:"+'<iframe id="slide'+i+'" src="" frameborder="0" allowfullscreen></iframe>');					$('#slide'+i).replaceWith('<iframe id="slide'+i+'" src="" frameborder="0" allowfullscreen></iframe>');					urlReader(file, function(output) {											alert(output);						document.getElementById("slide"+i).src = output;					});				} else {									alert("is img");//					// Image										alert("script tag:"+'<img id="slide'+i+'" src="" />');					$('#slide'+i).replaceWith('<img id="slide'+i+'" src="" />');					document.getElementById("slide"+i).src = file;				}			}		  // document.getElementById("slide2").src = "Slides/" + aFiles[aFiles.length - 3];		  		  // document.getElementById("slide3").src = "Slides/" + aFiles[aFiles.length - 4];		  		  // document.getElementById("slide4").src = "Slides/" + aFiles[aFiles.length - 5];		  		  // document.getElementById("slide5").src = "Slides/" + aFiles[aFiles.length - 6];		  		}	});}
Edited by 2Radon

Share this post


Link to post
Share on other sites

Alright, this could be interesting...

 

I got it to work, but I wanted it to work with multiple iframe videos, so I used a couple arrays and another cycle counter to store the iframe sources to be used later, because as I found out, if I leave the urlReader() in the cycle, by the time it finishes its work, the cycle is on a different step, leaving the step, during which urlReader was initiated, empty.

 

I'm sorry I lost the link to where I found this handleData() ajax solution, but it explained that the script won't wait for the response and it could be worked around by "promising" the return value.

function urlReader(path, handleData) {	$.ajax({		url: path,		type:'POST',		success: function(m){			handleData(m);		}	});}

So I thought I'm crazy for doing ridiculously messy things like this, but it interested me and I started doing it anyway.

However, somewhere I messed up, as expected, and I am screwing it around now until I straighten it.

function slidemaker() {	$.post('HubWeb_Scanner.php');		$.ajax({		url: 'Slides/dir.log',		type:'POST',		success: function(m){			aFiles = m.split("rn");						var slidecycle = 0;			var framecounter = 0;			while (slidecycle < 6) {				slidecycle++;				var file = "Slides/" + aFiles[aFiles.length - (slidecycle + 1)];				var check = file.indexOf(".txt");				if (check > 0) {					var remember[framecounter] = slidecycle;					var thatfile[framecounter] = file;					framecounter++;				} else {					$('#slide'+slidecycle).replaceWith('<img id="slide'+slidecycle+'" src="'+file+'" />');				}			}						var memorycycle = 0;			while (remember[memorycycle]) {				urlReader(thatfile[memorycycle], function(output) {					$('#slide'+remember[memorycycle]).replaceWith('<iframe id="slide'+remember[memorycycle]+'" src="'+output+'" frameborder="0" allowfullscreen></iframe>');					memorycycle++			}			});		}	});}

Share this post


Link to post
Share on other sites

Check your developer console for error messages, but I don't think lines 208 and 209 are going to work, you don't use var when declaring individual array elements.

Share this post


Link to post
Share on other sites

I've gotten through that part. Now I'm trying to separate the slideshow delay times using values from a text file as milliseconds and creating a timeout before each animate() function. I've had no good luck with this loop and my Chrome debugger no longer tells me enough about this.

This loop is inside a $.ajax POST function to get the delay times and the first 5 elements of the array should be applied to each slide consequently. variable currentPosition already tells which slide it's on.

while (true) {	if (currentPosition == numberOfSlides - 1) {		currentPosition = 0;	} else {		currentPosition++;	}		$('#slidesHolder').animate({'marginLeft': slideWidth * (-currentPosition)});	sleep(aDelays[1]);}
// I found this sleep() function while searching for ways to delay the loop, but the idea I want still doesn't work.function sleep(milliseconds) {  var start = new Date().getTime();  for (var i = 0; i < 1e7; i++) {if ((new Date().getTime() - start) > milliseconds){ break;}  }}
Edited by 2Radon

Share this post


Link to post
Share on other sites

That's a terrible sleep function, it uses a busy loop which means the CPU is sitting there running a loop over and over doing no other work. So the CPU is tied up doing nothing. Javascript does not have a non-busy sleep, that's what setTimeout is for.You can store the timeouts and things like that in an array, which it looks like you were doing in the previous code, and check that array to figure out how long to delay the next animation. You should still use setTimeout to trigger the animation though. A more modern approach would be to use requestAnimationFrame instead of setTimeout.

Share this post


Link to post
Share on other sites

Thanks, I checked out that requestAnimationFrame a bit, but it was probably too advanced for this time and I didn't quite understand how it could make this work like it works now.

So I kept on with the setTimeout and followed my feeling that there had to be a way of looping all the setTimeout functions with one setInterval.

I could have done the reptitive lines through loops, but that's for a remake in the future, I think.

Passing an array as function argument didn't work, but I only have 5 elements anyway, luckily.

$(document).ready(function() {	var currentPosition = 0;	var slideWidth = $(document).width() * 0.7;	var slides = $('.slide');	var numberOfSlides = slides.length;		slides.wrapAll('<div id=slidesHolder></div>');	slides.css({'float':'left'});	$('#slidesHolder').css('width', slideWidth * numberOfSlides);		slideScheduler();		function slideScheduler() {		$.ajax({			url: 'Slides/delay.log',			type:'POST',			success: function(m){				var aDelays = m.split("rn").map(Number);				var totalDelay = aDelays[0] + aDelays[1] + aDelays[2] + aDelays[3] + aDelays[4];				aDelays[0] = parseInt(aDelays[0]);				aDelays[1] = parseInt(aDelays[1]);				aDelays[2] = parseInt(aDelays[2]);				aDelays[3] = parseInt(aDelays[3]);				aDelays[4] = parseInt(aDelays[4]);								var tim1;				var tim2;				var tim3;				var tim4;				var tim5;								// This takes some time until it starts working				setInterval(function() {					slideTimer(aDelays[0],aDelays[1],aDelays[2],aDelays[3],aDelays[4]);				}, totalDelay + 100); // + 100 so it doesn't overlap and swap around the delays								function slideTimer(delay1, delay2, delay3, delay4, delay5) {					clearTimeout(tim1);					clearTimeout(tim2);					clearTimeout(tim3);					clearTimeout(tim4);					clearTimeout(tim5);					tim1 = setTimeout(changePosition, delay1);					tim2 = setTimeout(changePosition, delay1 + delay2);					tim3 = setTimeout(changePosition, delay1 + delay2 + delay3);					tim4 = setTimeout(changePosition, delay1 + delay2 + delay3 + delay4);					tim5 = setTimeout(changePosition, delay1 + delay2 + delay3 + delay4 + delay5);				}			}		});	}			function changePosition() {		if (currentPosition == numberOfSlides - 1) {			currentPosition = 0;		} else {			currentPosition++;		}				moveSlide();	}		function moveSlide() {		$('#slidesHolder').animate({'marginLeft': slideWidth * (-currentPosition)});	}	});

Now I can put an input box for video length value in the Staff Page where people will post the slides.

 

I got frustrated with trying to start using the YouTube API in my page. It's just so much mess and I couldn't find anywhere an explanation on how to add it straight and clear. Thought that besides the enabling in https://code.google.com/ or whatever it could be just <script src...> but no?

 

I need to make the video play when it is in the current position of the slideshow and and replay when it cycles back to the video again. Because of the separate delays I don't need to mute or stop the video, it will just be delayed for approximately the length of the video. I am now looking at reloading the iframe when it comes to the current position.

 

Edit: I got the iframe to reload when it is in the current position. The only little meh about this is that it takes quite a while before the script gets to the setTimeout part. Any easy way to fix that?

Edited by 2Radon

Share this post


Link to post
Share on other sites

You can pass an array as an argument, I'm not sure what you tried that failed. The most common way to do this is to have a single function that you call though, which will check which slide is being shown and then show the next one, and schedule itself to run again. You could have an array of objects that describe each slide, for example:

var slides = [  {    filename: 'image1.png',    delay: 2000,    caption: 'Image 1'  },  {    filename: 'image2.png',    delay: 3000,    caption: 'Image 2'  },  {    filename: 'image3.png',    delay: 1500,    caption: 'Image 3'  },  ...];
Also a counter to keep track of which slide you're on, which you already have. The function would figure out which slide to show, for how long, update the page and schedule itself again. e.g.:
function show_slide() {  if (currentSlide == slides.length - 1) {    currentSlide = 0;  }  else {    currentSlide++;  }  var slide = slides[currentSlide];  // update HTML here with slide.filename and slide.caption  setTimeout(show_slide, slide.delay);}
That's about it, plus the code to update the actual page. You don't need to schedule everything at once, it's common to just do one thing at a time and then have the function schedule itself to run again.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...