Reputation: 1173
EDIT:
I'm currently working with the anwser of Louys Patrice Besette, and i'm almost done with putting all the slides in. However sometimes when i refresh the page. The video becomes black and does not play. And this goes on for all the next upcomming videos. And then a few refreshes later it works again.
Why does this happen?
I get this error in the console when the error (black videos) happen: index.html:1 Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().
Also one more question. Is the a way to make like a waiting line for the things to be loaded? I'm on about 60-70% now of being finished with the site. However, i notice that my laptop has to work very very very hard in order to load all the videos and images for the first time.
End of EDIT
Right now i'm trying to make a kind of slide show to display Images and Videos one by one.
My code so far looks like this:
<div id="div1" class="hidden">
<video autoplay>
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" type="video/mp4">
</video>
</div>
<div id="div2" class="hidden"><img src="http://www.w3schools.com/css/trolltunga.jpg" /></div>
<div id="div3" class="hidden"><img src="http://www.w3schools.com/css/trolltunga.jpg" /></div>
<div id="div4" class="hidden">
<video autoplay>
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" type="video/mp4">
</video>
</div>
<div id="div5" class="hidden"><img src="http://www.w3schools.com/css/trolltunga.jpg" /></div>
<div id="div6" class="hidden"><img src="http://www.w3schools.com/css/trolltunga.jpg" /></div>
<div id="div7" class="hidden">
<video autoplay>
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" type="video/mp4">
</video>
</div>
<div id="div8" class="hidden"><img src="http://www.w3schools.com/css/trolltunga.jpg" /></div>
<div id="div9" class="hidden"><img src="http://www.w3schools.com/css/trolltunga.jpg" /></div>
This code collects 9 "slides". 3 videos and 7 images. I want to show these one by one on the web page (each displaying for a different time).
I do this by:
<script type="text/javascript">
//show first slide
function showIt() {
document.getElementById("div1").className = "shown";
}
setTimeout("showIt()", 0000);
//Start fading first slide
function hideIt() {
document.getElementById("div1").className = "fade";
}
setTimeout("hideIt()", 16000);
//Start showing 2nd slide
function showIt2() {
document.getElementById("div2").className = "shown";
}
setTimeout("showIt2()", 16500);
//Remove the first slide
function removeIt() {
document.getElementById("div1").className = "hidden";
}
setTimeout("removeIt()", 17000);
//Start fading second slide
function hideIt2() {
document.getElementById("div2").className = "fade";
}
setTimeout("hideIt2()", 27000);
//Remove the second slide
function removeIt2() {
document.getElementById("div1").className = "hidden";
}
setTimeout("removeIt2()", 28000);
//When end is reached, reload page
setTimeout(window.location.reload.bind(window.location), 28000);
</script>
img {
max-width: 78%;
position:absolute;
margin-left: 10.5%;
}
video {
max-width: 78%;
position:absolute;
margin-left: 10.5%;
}
.hidden{
visibility: hidden;
}
.fade{
-webkit-animation: fadeout 1s; /* Safari, Chrome and Opera > 12.1 */
-moz-animation: fadeout 1s; /* Firefox < 16 */
-ms-animation: fadeout 1s; /* Internet Explorer */
-o-animation: fadeout 1s; /* Opera < 12.1 */
animation: fadeout 1s;
}
@keyframes fadeout {
from { opacity: 1; }
to { opacity: 0; }
}
/* Firefox < 16 */
@-moz-keyframes fadeout {
from { opacity: 1; }
to { opacity: 0; }
}
/* Safari, Chrome and Opera > 12.1 */
@-webkit-keyframes fadeout {
from { opacity: 1; }
to { opacity: 0; }
}
/* Internet Explorer */
@-ms-keyframes fadeout {
from { opacity: 1; }
to { opacity: 0; }
}
/* Opera < 12.1 */
@-o-keyframes fadeout {
from { opacity: 1; }
to { opacity: 0; }
}
.shown{
-webkit-animation: fadein 1s; /* Safari, Chrome and Opera > 12.1 */
-moz-animation: fadein 1s; /* Firefox < 16 */
-ms-animation: fadein 1s; /* Internet Explorer */
-o-animation: fadein 1s; /* Opera < 12.1 */
animation: fadein 1s;
}
@keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
/* Firefox < 16 */
@-moz-keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
/* Safari, Chrome and Opera > 12.1 */
@-webkit-keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
/* Internet Explorer */
@-ms-keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
/* Opera < 12.1 */
@-o-keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
As you can see, i'm only displaying 2 slides right now. while i have 9 ready. (in total i have got 40+). If i keep going the way i go right now. i will get tons and tons of code...
Is there a way to make this more compact/smaller?
I searched the internet for slideshows and find things. However i want to set the time to be seen for each slide. Since some slides need to be displayed 20 seconds and other 10.
Also i made a fiddle, but it is not working in there... https://jsfiddle.net/a10yarxj/
Upvotes: 1
Views: 2276
Reputation: 33933
I understand, in your question, that you want to have full control over the slideshow timings.
The display time...
And I added the possibility for fade in/out times to be different aswell.
The slides will contain image or video, wich may be longer than your timing... Letting the sound continue while other slides are displayed.
I suppose that the image/video order may (and will!) change over time...
And that the slide amount is variable.
So I made this small script that you will not have to modify each time you change the slideshow content.
All params are provided in the HTML:
For the 3 first parameters, if the value is missing, default time is applyed and a «NOTICE» is shown in console.log()
.
For the last, if it is missing, it will be considered false.
I used jQuery .animate()
instead of CSS @keyframes
because the effect is easier to achieve this way, since only the opacity
is affected.
The slideshow is looping... So no need for a new page load at the end.
Here it is, in the below snippet and on CodePen:
EDIT
I added a setTimeout
"bugfix" on lines 8 to 12 and on line 54.
As per below comments, it appears that a setTimeout
may remain in DOM on page refresh [F5].
To prevent that, we clear it if it exist.
var slides = $(".slide");
var lastSlideIndex = slides.length-1;
var currentSlideIndex = 0;
var defaultTiming = 1000;
var defaultFadeInTime = 1000;
var defaultFadeOutTime = 1000;
// Prevents a setTimeout to remain in browser cache on page refresh.
if (typeof slideTimer !== 'undefined') {
clearTimeout(slideTimer);
}
var slideTimer;
// Show slide function
function showSlide() {
var thisSlide = slides.eq(currentSlideIndex);
// Delays
var timing = parseFloat(thisSlide.attr("data-timing")) * 1000; // Transform seconds in milliseconds
if(isNaN(timing)){timing=defaultTiming; console.log("NOTICE: ----------- data-timing is missing, using default.");}
var fadeInTime = parseFloat(thisSlide.attr("data-fadein")) * 1000;
if(isNaN(fadeInTime)){fadeInTime=defaultFadeInTime; console.log("NOTICE: ----------- data-fadein is missing, using default.");}
var fadeOutTime = parseFloat(thisSlide.attr("data-fadeout")) * 1000;
if(isNaN(fadeOutTime)){fadeOutTime=defaultFadeOutTime; console.log("NOTICE: ----------- data-fadeout is missing, using default.");}
console.log("Slide: "+currentSlideIndex+":\n Display time: "+timing+" millisec.\n Fadein: "+fadeInTime+" millisec.\n Fadeout: "+fadeOutTime+" millisec.");
thisSlide.animate({"opacity":1},fadeInTime);
// If this slide contains a video
if(slides.eq(currentSlideIndex).find("video").length > 0){
// Prevents more than 1 video to play at the same time
$("video").each(function(){
console.log("All video paused.")
$(this)[0].pause();
});
// Play this video from the start
var thisVideo = slides.eq(currentSlideIndex).find("video")[0];
thisVideo.currentTime = 0;
console.log("Video playing.");
thisVideo.play()
}
// Prepare for next slide
currentSlideIndex++;
// Reset to slide 0 if last was reached
if(currentSlideIndex>lastSlideIndex){
currentSlideIndex=0;
}
slideTimer = setTimeout(function(){
// Fade out previous slide
var previousSlideIndex = currentSlideIndex-1;
// If previous was last slide
if(previousSlideIndex == -1){
previousSlideIndex = lastSlideIndex;
}
// If previous slide was set to pause
if(slides.eq(previousSlideIndex).attr("data-videopause")=="true"){
console.log("Video has been paused.");
slides.eq(previousSlideIndex).find("video")[0].pause();
}
slides.eq(previousSlideIndex).animate({"opacity":0},fadeOutTime);
showSlide();
}, timing);
}
// Init
showSlide();
img {
max-width: 78%;
position:absolute;
margin-left: 10.5%;
}
video {
max-width: 78%;
position:absolute;
margin-left: 10.5%;
}
.slide{
opacity:0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slide" data-timing=4 data-fadein=0.5 data-fadeout=1 data-videopause=false>
<video>
<source src="https://www.bessetteweb.com/SO/39920322/video-1.mp4" type="video/mp4">
</video>
</div>
<div class="slide" data-timing=4 data-fadein=0.5 data-fadeout=0.5><img src="https://upload.wikimedia.org/wikipedia/commons/3/30/Fritz_von_Wille_0071.jpg" /></div>
<div class="slide" data-timing=2 data-fadein=0.5 data-fadeout=1><img src="https://upload.wikimedia.org/wikipedia/commons/f/f3/Truncated_View_of_the_Broekzijdse_Molen_on_the_Gein_by_Piet_Mondrian.jpg" /></div>
<div class="slide" data-timing=6 data-fadein=0.5 data-fadeout=2 data-videopause=true>
<video>
<source src="https://www.bessetteweb.com/SO/39920322/video-2.mp4" type="video/mp4">
</video>
</div>
<div class="slide" data-timing=2 data-fadein=0.5 data-fadeout=3><img src="https://upload.wikimedia.org/wikipedia/commons/0/01/Walter_Leistikow_-_Liebesinsel_(1905).jpg" /></div>
<div class="slide" data-timing=4 data-fadein=0.5 data-fadeout=1><img src="https://upload.wikimedia.org/wikipedia/commons/e/ee/%D0%92%D0%B5%D1%87%D0%B0%D1%80_%D0%90._%D0%93%D0%B0%D1%80%D0%B0%D1%9E%D1%81%D0%BA%D1%96.jpg" /></div>
<div class="slide" data-timing=6 data-fadein=0.5 data-fadeout=0.5 data-videopause=true>
<video>
<source src="https://www.bessetteweb.com/SO/39920322/video-3.mp4" type="video/mp4">
</video>
</div>
<div class="slide" data-timing=3 data-fadein=0.5 data-fadeout=1><img src="https://upload.wikimedia.org/wikipedia/commons/8/88/Morris21.jpg" /></div>
<div class="slide" data-timing=2 data-fadein=0.5 data-fadeout=2><img src="https://upload.wikimedia.org/wikipedia/commons/3/30/Fritz_von_Wille_0071.jpg" /></div>
<!-- ---------------------------
Copyright issues:
Images used here are labelled for reuse and videos were made by me for this example.
The Google image search I used: https://www.google.ca/search?q=paysage&espv=2&biw=1600&bih=1110&tbs=islt:svga,isz:ex,iszw:500,iszh:400&tbm=isch&source=lnt#tbs=islt:svga%2Cisz:ex%2Ciszw:500%2Ciszh:400%2Csur:fc&tbm=isch&q=landscape+-flickr&imgrc=pqMMLvfhjtbSuM%3A
-->
Upvotes: 2
Reputation: 5745
I have add only one function call with timeout. You can add time of your slide directly in table. Please try
var totalSlide =[0,2000,2000,2000,2000,2000,2000,2000,2000];
var slideStart = 0;
showIt();
function showIt() {
setTimeout(function(){
var idNow = document.getElementById("div"+(slideStart+1));
idNow.className = "shown";
slideStart++;
setTimeout(function(){
idNow.className = "fade";
setTimeout(function(){idNow.className = "hidden";},500)
if(slideStart == totalSlide.length-1 ){
slideStart = 0;
}
showIt()
},totalSlide[slideStart])
}, 0)
}
img {
max-width: 78%;
position:absolute;
margin-left: 10.5%;
}
video {
max-width: 78%;
position:absolute;
margin-left: 10.5%;
}
.hidden{
visibility: hidden;
}
.fade{
-webkit-animation: fadeout 1s; /* Safari, Chrome and Opera > 12.1 */
-moz-animation: fadeout 1s; /* Firefox < 16 */
-ms-animation: fadeout 1s; /* Internet Explorer */
-o-animation: fadeout 1s; /* Opera < 12.1 */
animation: fadeout 1s;
}
@keyframes fadeout {
from { opacity: 1; }
to { opacity: 0; }
}
/* Firefox < 16 */
@-moz-keyframes fadeout {
from { opacity: 1; }
to { opacity: 0; }
}
/* Safari, Chrome and Opera > 12.1 */
@-webkit-keyframes fadeout {
from { opacity: 1; }
to { opacity: 0; }
}
/* Internet Explorer */
@-ms-keyframes fadeout {
from { opacity: 1; }
to { opacity: 0; }
}
/* Opera < 12.1 */
@-o-keyframes fadeout {
from { opacity: 1; }
to { opacity: 0; }
}
.shown{
-webkit-animation: fadein 1s; /* Safari, Chrome and Opera > 12.1 */
-moz-animation: fadein 1s; /* Firefox < 16 */
-ms-animation: fadein 1s; /* Internet Explorer */
-o-animation: fadein 1s; /* Opera < 12.1 */
animation: fadein 1s;
}
@keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
/* Firefox < 16 */
@-moz-keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
/* Safari, Chrome and Opera > 12.1 */
@-webkit-keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
/* Internet Explorer */
@-ms-keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
/* Opera < 12.1 */
@-o-keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div1" class="hidden">
<video autoplay>
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" type="video/mp4">
</video>
</div>
<div id="div2" class="hidden"><img src="http://www.w3schools.com/css/trolltunga.jpg" /></div>
<div id="div3" class="hidden"><img src="http://www.w3schools.com/css/trolltunga.jpg" /></div>
<div id="div4" class="hidden">
<video autoplay>
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" type="video/mp4">
</video>
</div>
<div id="div5" class="hidden"><img src="http://www.w3schools.com/css/trolltunga.jpg" /></div>
<div id="div6" class="hidden"><img src="http://www.w3schools.com/css/trolltunga.jpg" /></div>
<div id="div7" class="hidden">
<video autoplay>
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" type="video/mp4">
</video>
</div>
<div id="div8" class="hidden"><img src="http://www.w3schools.com/css/trolltunga.jpg" /></div>
<div id="div9" class="hidden"><img src="http://www.w3schools.com/css/trolltunga.jpg" /></div>
UPDATE
var video = $(".div7").find("video");
function playVid() {
video .play();
}
function pauseVid() {
video .pause();
}
Upvotes: 2
Reputation: 9157
UPDATE
[...] However i want to set the time to be seen for each slide. Since some slides need to be displayed 20 seconds and other 10.
You can use data
attribute to store duration time of each slide:
<div id="div1" data-duration="3500" class="hidden">
<img src="..." />
</div>
Then (using jQuery), you could combine setTimeout
's for each action (each class toggle). Use class
instead of id
:
var durations = 0;
var play = function(){
var that = $(this), i = that.index(), duration = that.data('duration'), l = $('.hidden').length;
setTimeout(function(){
that.toggleClass('hidden shown');
setTimeout(function(){
that.toggleClass('shown fade');
setTimeout(function(){
that.toggleClass('fade hidden');
if(i+1 === l){
// No need to reload page. If you want to loop over again, uncomment this:
// $('.hidden').each(play);
}
}, 500);
}, duration);
}, durations);
durations += duration+500;
}
$('.hidden').each(play);
Upvotes: 0
Reputation: 5911
Yes, there is. From a pure javascript perspective, this is a quick solution but it can be improved further (that can be your job):
(function() {
var currentDivNumber = 1;
function removeIt() {
document.getElementById("div"+currentDivNumber).className = "hidden";
currentDivNumber++;
if ( currentDivNumber > maxSlides) {
currentDivNumber=1;
}
setTimeout(showIt, 500);
}
function hideIt() {
document.getElementById("div"+currentDivNumber).className = "fade";
setTimeout(removeIt, 500);
}
function showIt() {
document.getElementById("div"+currentDivNumber).className = "shown";
setTimeout(hideIt, 500);
}
setTimeout(showIt, 16000);
})();
This is not optimal it can be further improved. Plus maybe better CSS can be used to remove additional if not all javascript?
see : https://jsfiddle.net/0mvpfthL/1/
Upvotes: 0