Making a traditional film animation using kirupa's slide show

Londonkillsme.com thanks its my birthday today

Wow! This looks fantastic. Sorry, what would you like to do beyond what you already have? It seems to be fairly fast, and each frame seems to be clickable too!

londonkillsme.com so apart from making the animation look like a good animation by professional standards, I have to make the animation user operable so you open the jacket click on the links and the animation can restart ie link goes to new screen or closes if other link is chosen. So I have to make code that controls the movement of the frames by the links that are touched and essentially that is the beauty of the project because it could apply to really complex web animations just using html and css. jump in the rabbit hole if you got any suggestions this project is non tween and non gsock a traditional animation frame by frame and interactive on every level at base.

so K, londonkillsme.com just converted your slide show into a vertical one takes 3 secs to load - bad!!! and it does some really funky things, if you download the website and make it local take off the viewport div all the frames animate as you scroll. Really interesting that means every frame could be animated or the javascript could be used on one frame only. Needs soooo much work please help if you got any code to help sugestions please

the reason for making slide show animation vertical is the posibillity of making it responsive to all media, with horizontal there is an odd thought about making the aspect ratio right, which is really important to an animator, filmaker or visual music maker. Portrait aspect phones etc can be limited by width to control vh percentages etc instead of using padding hack to use height in horizontal layouts where height is the controller of the aspect ratio. After svg width height is removed and img, svg spreads to all widths of phones with 100% or vw, this is obviously controllable but you want the minimal amount of rendering painting resizing and vertical gives a constant for all devices controlled by width to give height if that makes sense by my excited thought process and writing and also content was originally designed to scroll vertically so it makes sense to make the content vertical for the animation also, and to add to this film projector reels roll vertically through the projector, making it more like a real film animation. note takes 3 secs to start loading on laptop god knows what it does to a phone

hello kirupa is there any way to add a start stop button to the javascript in your slideshow so that it plays only once and then can be reset.

    <script>
 // just querying the DOM...like a boss!
var links = document.querySelectorAll(".itemLinks");
var wrapper = document.querySelector("#wrapper");
 
// the activeLink provides a pointer to the currently displayed item
var activeLink = 0;
 
// setup the event listeners
for (var i = 0; i < links.length; i++) {
    var link = links[i];
    link.addEventListener('click', setClickedItem, false);
 
    // identify the item for the activeLink
    link.itemID = i;
}
 
// set first item as active
links[activeLink].classList.add("active");
 
function setClickedItem(e) {
    removeActiveLinks();
       resetTimer();
 
    var clickedLink = e.target;
    activeLink = clickedLink.itemID;
 
    changePosition(clickedLink);
}
//
function removeActiveLinks() {
    for (var i = 0; i < links.length; i++) {
        links[i].classList.remove("active");
    }
}
 
// Handle changing the slider position as well as ensure
// the correct link is highlighted as being active
//changing the var translate value here turns vertical to horizontal movement 
function changePosition(link) {
    var position = link.getAttribute("data-pos");
 
    var translateValue = "translate3d(0px," + position + ",  0px)";
    wrapper.style.transform = translateValue;
 
    link.classList.add("active");
}
//we now have 92 frames 46 of them repeated twice at 25 frames per sec. 1 sec =1000ms so 1000ms divided by 25 equals 40ms between frames
var timeoutID;
 
function startTimer() {
    // wait 2 seconds before calling goInactive
    timeoutID = window.setInterval(goToNextItem, 40);
}
//removing startTimer here the one below stops the anime at the begining until you click any of links 

startTimer();
 
function resetTimer() {
    window.clearInterval(timeoutID);
    startTimer();
}
 
function goToNextItem() {
    removeActiveLinks();
    if (activeLink < links.length - 1) {
        activeLink++;
    } else {
        activeLink = 0;
    }
 
    var newLink = links[activeLink];
    changePosition(newLink);
}
</script>

Hi @LondonKillsMe - certainly! Do you have a link to the full example? Or would you prefer I make it in my version on the site and you will reverse engineer it?

I cannot reply to some of my posts I am registered as spam
Link is:
londonkillsme.com
Thank you so much Kirupa will update my site tonight
I think it would be more helpfull for everybody if you changed your version on your site as the book links to it. the javascript on my site is the same anyway just vertical and id differences with a timer bolted on

Apologies for the site marking you as a spammer. I went ahead and manually overrode that designation. Not sure how that happens.

Regarding the slideshow, I’ll make the changes ASAP!

If I am understanding what you are saying - what you would like to see is to have a Play button the user must click to have the slideshow play. Once it reaches the end, it will stop. To start it again, the user will click the Play button again.

Should someone be able to pause the slideshow in the middle while it is running?

I think that would be great to have buttons to pause while running plus stop start and also if possible to show how to keep the slideshow repeating and how to reset from body load as well ,for other users the more functionality the more we can learn about javascript. I think its quite daunting for most new coders to face javascript I think from my experience after trying to code my own websites a great and important challenge to get over the mystery of coding. Thanks Kirupa means a lot to me and I am sure thousands that will read your book.

This helps! Let me see what I can do here. If everything goes well, I can share something tomorrow…or early next week if things get too busy :slight_smile:

@LondonKillsMe - there is more I need to do here, but here is a start with the pause, play, and restart capabilities:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Automatic Content Slider Example</title>
  <style>
    #contentContainer {
      width: 550px;
      height: 350px;
      border: 5px black solid;
      overflow: hidden;
    }

    #wrapper {
      width: 4400px;
      position: relative;
      transform: translate3d(0, 0, 0);
      transition: transform .5s ease-in-out;
      display: flex;
    }

    .content {
      height: 350px;
      white-space: normal;
      width: 550px;
      text-align: center;
      padding-top: 70px;
    }

    .content p {
      font-family: Arial, sans-serif;
      font-weight: bold;
      opacity: .3;
      font-size: 144px;
      margin: 0;
    }

    #itemOne {
      background-color: #0099CC;
      background-image: url("//www.kirupa.com/images/blueSquare.png");
    }

    #itemTwo {
      background-color: #FFCC00;
      background-image: url("//www.kirupa.com/images/yellowSquare.png");
    }

    #itemThree {
      background-color: #FF6666;
      background-image: url("//www.kirupa.com/images/pinkSquare.png");
    }
    #itemFour {
      background-color: #E8E8E8;
      background-image: url("//www.kirupa.com/images/graySquare.png");
    }
    #itemFive {
      background-color: #5a0088;
      background-image: url("//www.kirupa.com/images/blueSquare.png");
    }

    #itemSix {
      background-color: #00b54e;
      background-image: url("//www.kirupa.com/images/yellowSquare.png");
    }

    #itemSeven {
      background-color: #131a54;
      background-image: url("//www.kirupa.com/images/pinkSquare.png");
    }

    #itemEight {
      background-color: #bdbdbd;
      background-image: url("//www.kirupa.com/images/graySquare.png");
    }

    #navLinks {
      text-align: center;
      width: 550px;
    }

    #navLinks ul {
      margin: 0px;
      padding: 0px;
      display: inline-block;
      margin-top: 6px;
    }

    #navLinks ul li {
      float: left;
      text-align: center;
      margin: 10px;
      list-style: none;
      cursor: pointer;
      background-color: #CCCCCC;
      padding: 5px;
      border-radius: 50%;
      border: black 5px solid;
    }

    #navLinks ul li:hover {
      background-color: #FFFF00;
    }

    #navLinks ul li.active {
      background-color: #333333;
      color: #FFFFFF;
      outline-width: 7px;
    }

    #navLinks ul li.active:hover {
      background-color: #484848;
      color: #FFFFFF;
    }
  </style>
</head>

<body>
  <div id="contentContainer">
    <div id="wrapper">
      <div id="itemOne" class="content">

      </div>
      <div id="itemTwo" class="content">

      </div>
      <div id="itemThree" class="content">

      </div>
      <div id="itemFour" class="content">

      </div>
      <div id="itemFive" class="content">

      </div>
      <div id="itemSix" class="content">

      </div>
      <div id="itemSeven" class="content">

      </div>
      <div id="itemEight" class="content">

      </div>
    </div>
  </div>
  <div id="navLinks">
    <ul>
      <li id="firstLink" class="itemLinks" data-pos="0px"></li>
      <li class="itemLinks" data-pos="-550px"></li>
      <li class="itemLinks" data-pos="-1100px"></li>
      <li class="itemLinks" data-pos="-1650px"></li>
      <li class="itemLinks" data-pos="-2200px"></li>
      <li class="itemLinks" data-pos="-2750px"></li>
      <li class="itemLinks" data-pos="-3300px"></li>
      <li class="itemLinks" data-pos="-3850px"></li>
    </ul>
  </div>
  <button id="pauseButton">Pause</button>
  <button id="playButton">Play</button>
  <button id="restartButton">Restart</button>
  <script>
    // just querying the DOM...like a boss!
    var links = document.querySelectorAll(".itemLinks");
    var wrapper = document.querySelector("#wrapper");

    // the activeLink provides a pointer to the currently displayed item
    var activeLink = 0;

    // setup the event listeners
    for (var i = 0; i < links.length; i++) {
      var link = links[i];
      link.addEventListener('click', setClickedItem, false);

      // identify the item for the activeLink
      link.itemID = i;
    }

    // set first item as active
    links[activeLink].classList.add("active");

    function setClickedItem(e) {
      removeActiveLinks();
      //resetTimer();

      var clickedLink = e.target;
      activeLink = clickedLink.itemID;

      changePosition(clickedLink);
    }

    function removeActiveLinks() {
      for (var i = 0; i < links.length; i++) {
        links[i].classList.remove("active");
      }
    }

    // Handle changing the slider position as well as ensure
    // the correct link is highlighted as being active
    function changePosition(link) {
      var position = link.getAttribute("data-pos");

      var translateValue = "translate3d(" + position + ", 0px, 0)";
      wrapper.style["transform"] = translateValue;

      link.classList.add("active");
    }

    //
    // The code for sliding the content automatically
    //
    var timeoutID;

    function startTimer() {
      // wait 2 seconds before calling goInactive
      timeoutID = window.setInterval(goToNextItem, 2000);
    }
    startTimer();

    function resetTimer() {
      window.clearInterval(timeoutID);
      startTimer();
    }

    function goToNextItem() {
      removeActiveLinks();

      if (activeLink < links.length - 1) {
        activeLink++;
      } else {
        activeLink = 0;
      }

      var newLink = links[activeLink];
      changePosition(newLink);
    }

    let pauseButton =  document.querySelector("#pauseButton");
    let playButton =  document.querySelector("#playButton");
    let restartButton =  document.querySelector("#restartButton");

    playButton.disabled = true;

    pauseButton.addEventListener("click", () => {
      window.clearInterval(timeoutID);
      pauseButton.disabled = true;
      playButton.disabled = false;
    });

    playButton.addEventListener("click", () => {
      window.clearInterval(timeoutID);
      startTimer();

      pauseButton.disabled = false;
      playButton.disabled = true;
    });

    restartButton.addEventListener("click", () => {
      activeLink = 0;
      window.clearInterval(timeoutID);
      removeActiveLinks();
      changePosition(document.querySelector("#firstLink"));

      startTimer();
    });

  </script>
</body>

</html>

Thank you so much new script gives me a great start to see how the functionality works. In the script can you explain how to change playing the slideshow once as opposed to playing continuously, or button play to end and stop and button go to start and stop to show difference in code please.Been changing button true false seems to work a bit better Big hack but if you remove active link below it plays only once. now buttons need tweaking after slideshow has finished. if only firing slideshow once add activelink=0 to play button and remove at function goToNextItem()…else, see notes below

  <script>
    // just querying the DOM...like a boss!
    var links = document.querySelectorAll(".itemLinks");
    var wrapper = document.querySelector("#wrapper");

    // the activeLink provides a pointer to the currently displayed item
    var activeLink = 0;

    // setup the event listeners
    for (var i = 0; i < links.length; i++) {
      var link = links[i];
      link.addEventListener('click', setClickedItem, false);

      // identify the item for the activeLink
      link.itemID = i;
    }

    // set first item as active
    links[activeLink].classList.add("active");

    function setClickedItem(e) {
     removeActiveLinks();
    
     //if changed this stops slideshow instead of restarting at clicked link after stop button is pressed

      var clickedLink = e.target;
      activeLink = clickedLink.itemID;

      changePosition(clickedLink);
    }

    function removeActiveLinks() {
      for (var i = 0; i < links.length; i++) {
        links[i].classList.remove("active");
      }
      
    }

    // Handle changing the slider position as well as ensure
    // the correct link is highlighted as being active
    function changePosition(link) {
      var position = link.getAttribute("data-pos");

      var translateValue = "translate3d(0px," + position + ",  0px)";
      wrapper.style["transform"] = translateValue;

      link.classList.add("active");
    }
    //
    // The code for sliding the content automatically
    //
    var timeoutID;

    function startTimer() {
      // wait 2 seconds before calling goInactive this changes speed of slideshow
      timeoutID = window.setInterval(goToNextItem, 40);
      //setTimeout(goToNextItem, 2000);
    }
    
    //startTimer(); add this to run automatically

    function resetTimer() {
    window.clearInterval(timeoutID);
    startTimer();
    }

    function goToNextItem() {
 //take out to make all links active   
      removeActiveLinks();

      if (activeLink < links.length - 1) {
        activeLink++;
      }

      else {
      //activeLink = 0; insertfor looping playback  
      }

      var newLink = links[activeLink];
      changePosition(newLink);
    }

    let startButton =  document.querySelector("#startButton");
    let pauseButton =  document.querySelector("#pauseButton");
    let playButton =  document.querySelector("#playButton");
    let replayButton =  document.querySelector("#replayButton");

    startButton.disabled = true;
    playButton.disabled = false;
    pauseButton.disabled = true;
  
   startButton.addEventListener("click", () => {
window.location.reload();
      pauseButton.disabled = false;
      playButton.disabled = false;
    });

    pauseButton.addEventListener("click", () => {
      window.clearInterval(timeoutID);
      startButton.disabled = false;
      pauseButton.disabled = true;
      playButton.disabled = false;
    });

    playButton.addEventListener("click", () => {
      window.clearInterval(timeoutID);
      startTimer();
	activeLink = 0;//can set what frame to start with
startButton.disabled = false;
      pauseButton.disabled = false;
      playButton.disabled = true;
    });

    replayButton.addEventListener("click", () => {
      activeLink = 0;
      window.clearInterval(timeoutID);
      removeActiveLinks();
      changePosition(document.querySelector("#Nw1"));
      startTimer();     
      pauseButton.disabled = false;
      playButton.disabled = false;
    });
  </script>

see londonkillsme.com

Sorry for the delay on this. Work and other obligations have shrunk my time on this. I haven’t forgotten about it.

i have a rational consent that when i post here all of my data is used openly, all of our data is collected without allowing it to do so. there is nothing we can do without a lot of hard work to stop that. on open archives, your files there are data sniffers on your html upload accounts whether you like it or not how do we make safe protocols or not.

kirupa getting my svg content down to 3kb per frame from 62kb on my animation as was getting fouc on start up slide really want it to work with larger images, should be able to handle it on older machines and mobiles but lagging not loading content before firing. put an inline svg on first frame and that seemed to help, so not sure if content or retrofitted script that slowing things down. please help when you have time nick - londonkillsme.com

It was very smooth for me! How are you optimizing the SVGs? One tool that I use is SVGOMG:

SVGOMG - SVGO's Missing GUI

I paste my SVG markup into it and let it remove unnecessary content, precision, etc. that can greatly reduce the file size.

just using an svg editor to ungroup and delete repeated unessescary code. but my model should work with larger files as proved by reducing file sizes and finding no difference, there is glitch on first onload it takes 2or3 secs for body onload without first svg frame being inline code. When first frame is a external backgroun the same as all of them. Its a hack to solve this by making it inline. dont know why this is happening. will keep working. thanks K

one of my most important questions is how to use svg backgrounds as a data sorce without them being inline. Convert them to 64 to compact them but no anchors?, You can open external links on a svg file straight, yes. you make an svg a background, yes with no links. you make it inline yes you get layerable links. so i guess it is part of the dom. but why are external svg or image backgrounds not part of the dom when svgs are clickable over html layers. so powerful but missing that background accesibilty to make 3d…scapes like css should be like svg. Also why are fixed positions not allowable to clickable backgrounds, like creating a dashboard, with svg should be background clickable, but this is removed from normal play. I guess this is to keep things safe and accesible. While on another note html body shows up code in cool old school green on black, if you play ordering your layout, unlike svg, ever seen that, great background for your code camp… and on thanks K will keep looking and learning…N