4

I've been using jQuery Cycle 2 now for some years, wondering if there is a way to accomplish most of what this does without the need for jQuery? http://jquery.malsup.com/cycle2/faq/

Here is a basic css fade in / fade out cycle transition.

    var actual = 0;
    var total = 3;

    function addClass(elem, name) {
        elem.className = elem.className + " " + name;
    }

    function deleteClass(elem, name) {
        var c = elem.className;
        elem.className = c.replace(name, "").replace(/   /g, " ").replace(/^ | $/g, "");
    }

    function nextImg() {
        var e;

        e = document.getElementById("img" + actual);
        deleteClass(e, "visible");

        actual++;
        if (actual > total - 1) actual = 0;

        e = document.getElementById("img" + actual);
        addClass(e, "visible");
    }

    var slider = setInterval(nextImg, 3000);
    .slide {
        border: none; 
        opacity: 0; 
        position: absolute; 
        top: 0; 
        left: 0;
        -webkit-transition: opacity .300s linear;
        -moz-transition: opacity .300s linear;
        -o-transition: opacity .300s linear;
        transition: opacity .300s linear;
    }
    .visible {
        opacity: 1;
    }
    <div class="header">
    <span id="img0" class="slide visible"><img src="1.jpg">Orlandos studio</span>
    <span id="img1" class="slide"><img src="2.jpg">Fida in Van</span>
    <span id="img2" class="slide"><img src="3.jpg">Eternalife Productions</span>
    </div>
Sean
  • 767
  • 1
  • 6
  • 19
drooh
  • 578
  • 4
  • 18
  • 46
  • This looks like vanilla js? – Sean Jun 17 '20 at 23:05
  • yes, but it's not nearly as robust as jQuery Cycle2, I'm looking for an alternative. – drooh Jun 17 '20 at 23:12
  • [Swiper Slider](https://swiperjs.com/) could be alternatives for jQuery Cycle 2, and it's entirely written in Vanilla JavaScript – Momin Jul 03 '20 at 17:05
  • Excellent.. this one looks like the ticket https://swiperjs.com/demos/280-autoplay.html – drooh Jul 03 '20 at 17:17
  • there is a bunch of alternatives (including swiper) https://js.libhunt.com/cycle2-alternatives but they are lack of that impressive list of animation effects – artanik Jul 03 '20 at 17:20
  • yeah I hear ya, for me just the simple crossfade is the cleanest. – drooh Jul 03 '20 at 17:21

5 Answers5

4

I'm sure there is a shorter way to do this, however, this is my take on it. Does the same operation, just a little bit shorter.

var parent = document.getElementsByClassName("header")[0];
let i = 1;
let l = parent.children.length;

function imgCycle() {

  let pre = parent.children[((i - 1) < 0) ? l - 1 : i - 1]; // get previous holder of visible
  pre.className = pre.className.replace("visible", "");

  let e = parent.children[i];
  e.className += "visible";

  i = (i + 1) % l; // Make it loop around
}

var slider = setInterval(imgCycle, 3000);
.slide {
  border: none;
  opacity: 0;
  position: absolute;
  top: 0;
  left: 0;
  -webkit-transition: opacity .300s linear;
  -moz-transition: opacity .300s linear;
  -o-transition: opacity .300s linear;
  transition: opacity .300s linear;
}

.visible {
  opacity: 1;
}
<div class="header">
  <span id="img0" class="slide visible"><img src="1.jpg">Orlandos studio</span>
  <span id="img1" class="slide"><img src="2.jpg">Fida in Van</span>
  <span id="img2" class="slide"><img src="3.jpg">Eternalife Productions</span>
</div>
Sean
  • 767
  • 1
  • 6
  • 19
2

Checkout the below libraries:

I have not tried but there are many features, might be useful for you!


I have been working on this Slide-Projection-Vanilla-JS library for the last 2 days and have done some basic things as JQuery Cycle 2 has.

There are no any documentation or readme for now, I will add it soon, but I have added all kind of examples for ready to use.

Below features that relates with Cycle 2 library, for more details you can checkout GitHub Repository,

  • Next / Prev Controls
  • Pause on Hover Controls
  • Caption Controls
  • Manual Fx Controls
  • Overlay Options
  • Speed Option
  • Auto Play Option

Demo:

.center {
    text-align: center;
}

#pauser {
    width: 45%;
    padding: 30px;
    margin: auto;
    text-align: center;
    font-size: 16px
}

.info {
    padding: 5px 2px;
    color: #9B4D39;
    background: #FCE9E3;
    border: solid 1px #FBE1D5;
    -webkit-border-radius: 4px;
    -moz-border-radius: 4px;
    border-radius: 4px
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/turivishal/Slide-Projection-Vanilla-JS@0.0.1/build/slide-projection.styles.min.css">
<h3 class="center">Slide Projection (SP)</h3>
<div class="sp-wrapper">
    <div 
        class="sp-slideshow" 

        data-sp-speed="4000"
        data-sp-auto-play="true"

        data-sp-fx="slide" 
        data-sp-fx-next="next-slide"
        data-sp-fx-prev="prev-slide"
        data-sp-fx-active="active-slide"
        data-sp-fx-initial="initial-slide"

        data-sp-caption-template="Slide {{slideNum}} of {{slideCount}}">

        <!-- empty element for caption -->
        <div class="sp-caption"></div>
        <div class="sp-overlay"></div>

        <div class="sp-slide" data-sp-desc="Lorem ipsum dolor sit amet, consectetur adipiscing elit. In placerat risus bibendum, luctus nunc et, ultricies mauris. Pellentesque sagittis euismod urna">
            <img src="https://cdn.jsdelivr.net/gh/turivishal/Slide-Projection-Vanilla-JS@0.0.1/demos/images/sp1.jpg" alt="SP1" />
        </div>
        <div class="sp-slide" data-sp-desc="Lorem ipsum dolor sit amet, consectetur adipiscing elit.">
            <img src="https://cdn.jsdelivr.net/gh/turivishal/Slide-Projection-Vanilla-JS@0.0.1/demos/images/sp2.jpg" alt="SP2" />
        </div>
        <div class="sp-slide" data-sp-desc="Lorem ipsum dolor sit amet, consectetur adipiscing elit.">
            <img src="https://cdn.jsdelivr.net/gh/turivishal/Slide-Projection-Vanilla-JS@0.0.1/demos/images/sp3.jpg" alt="SP3" />
        </div>
        <div class="sp-slide" data-sp-desc="Lorem ipsum dolor sit amet, consectetur adipiscing elit.">
            <img src="https://cdn.jsdelivr.net/gh/turivishal/Slide-Projection-Vanilla-JS@0.0.1/demos/images/sp4.jpg" alt="SP4" />
        </div>
        <div class="sp-slide" data-sp-desc="Lorem ipsum dolor sit amet, consectetur adipiscing elit.">
            <img src="https://cdn.jsdelivr.net/gh/turivishal/Slide-Projection-Vanilla-JS@0.0.1/demos/images/sp5.jpg" alt="SP5" />
        </div>

        <div class="sp-button-next"></div>
        <div class="sp-button-prev"></div>

    </div>

</div>

<script src="https://cdn.jsdelivr.net/gh/turivishal/Slide-Projection-Vanilla-JS@0.0.1/build/slide-projection.vanilla.min.js"></script>
turivishal
  • 34,368
  • 7
  • 36
  • 59
1

Have you seen slendr, it's relatively small and extendable.

Features

  • Written and tested entirely using Typescript.
  • Lightweight (just 2KB gzipped UMD)
  • Responsive (desktop and mobile) by default.
  • Modern browsers only. No more legacy browsers like IE10 or IE11 (but you can find it on v1.3 release).
  • High performance by Lighthouse audit.
  • CSS3
  • Hardware Acceleration 60fps animation.
  • Progressive images loading.
  • Highly customizable.
  • SASS support.

And it uses minimal markup...

<div class="slendr-slides">
    <section class="slendr-slide" data-slide-src="image1.jpg"></section>
    <section class="slendr-slide"></section>
    <section class="slendr-slide" data-slide-src="image2.jpg"></section>
</div>

check out a demo on codepen

rexfordkelly
  • 1,623
  • 10
  • 15
1

This is a very simple, vanilla js implementation (no library is required). Also, in ES 5 (supported in every browser).

I didn't add images as content as I don't have any, but the ugly demo content still can demonstrate the component.

It only supports crossfade, but you may change it to whatever else in the attached CSS. All you need is, to modify the .crossfade-item and the .crossfade-item.active class rulesets.

The script only adds/removes the active class, prevents the animation from running is the mouse is above the component, and drives the controls.

Usable for multiple sliders on the same page.

var CrossFade = function(selector, interval) {
  this.interval = interval || 2000;
  this.container = document.querySelector(selector);
  this.items = this.container.querySelectorAll('.crossfade-item');
  this.leftControl = this.container.querySelector('.control-left');
  this.rightControl = this.container.querySelector('.control-right');
  this.activeIndex = 0;
  
  this.goNext = function() {
    var oldIndex = this.activeIndex;
    if (this.activeIndex + 1 > this.items.length - 1) {
      this.activeIndex = 0;
    } else {
      ++this.activeIndex;
    }
    this.items.item(oldIndex).classList.remove('active');
    this.items.item(this.activeIndex).classList.add('active');
  }.bind(this)
  
  this.goBack = function() {
    var oldIndex = this.activeIndex;
    if (this.activeIndex - 1 < 0) {
      this.activeIndex = this.items.length - 1;
    } else {
      --this.activeIndex;
    }
    this.items.item(oldIndex).classList.remove('active');
    this.items.item(this.activeIndex).classList.add('active');
  }.bind(this)
  
  this.removeTimer = function() {
    clearInterval(this.timer);
  }.bind(this);
  
  this.setTimer = function() {
    this.timer = setInterval(this.goNext, this.interval);
  }.bind(this);
  
  this.leftControl.addEventListener('click',this.goBack);
  this.rightControl.addEventListener('click', this.goNext);
  
  this.container.addEventListener('mouseover', this.removeTimer);
  this.container.addEventListener('mouseout', this.setTimer);
  
  this.setTimer();
}

new CrossFade('#oneCrossFade');
new CrossFade('#twoCrossFade', 3000);
/*chrome, you may set dimensions, positions, etc. here*/

.crossfade {
  position: relative;
  width: 480px;
  height: 120px;
}

.crossfade-item {
  position: absolute;
  left: 0;
  top: 0;
  width: 480px;
  height: 120px;
  z-index: 0;
  opacity: 0;
  transition: 2s all ease-out;
}

.crossfade-item.active {
  z-index: 1;
  opacity: 1;
  transition: 1s all ease-in;
}

.crossfade-control {
  position: absolute;
  z-index: 2;
  top: calc(50% - 10px);
}

.crossfade-control.control-left {
  left: 0;
}

.crossfade-control.control-right {
  right: 0;
}

/*content, you may put whatever you want after this point*/

.red {
  background-color: red;
}

.green {
  background-color: green;
}

.blue {
  background-color: blue;
}

.yellow {
  background-color: yellow;
  color: #000;
}

.cyan {
  background-color: cyan;
}

.magenta {
  background-color: magenta;
}

.red, .green, .blue, .cyan, .magenta {
  color: white;
}
<div class="crossfade" id="oneCrossFade">
  <div class="crossfade-item red active">
    <h2>A title here 1</h2>
    <p>Some longer description comes here 1</p>
  </div>
  <div class="crossfade-item green">
    <h2>A title here 2</h2>
    <p>Some longer description comes here 2</p>
  </div>
  <div class="crossfade-item blue">
    <h2>A title here 3</h2>
    <p>Some longer description comes here 3</p>
  </div>
  <button class="crossfade-control control-left">
    &lt;
  </button>
  <button class="crossfade-control control-right">
    &gt;
  </button>
</div>

<br /> <!-- this to demonstrate the support for multiple "sliders" on the same page -->

<div class="crossfade" id="twoCrossFade">
  <div class="crossfade-item magenta active">
    <h2>A title here 1</h2>
    <p>Some longer description comes here 1</p>
  </div>
  <div class="crossfade-item yellow">
    <h2>A title here 2</h2>
    <p>Some longer description comes here 2</p>
  </div>
  <div class="crossfade-item cyan">
    <h2>A title here 3</h2>
    <p>Some longer description comes here 3</p>
  </div>
  <button class="crossfade-control control-left">
    &lt;
  </button>
  <button class="crossfade-control control-right">
    &gt;
  </button>
</div>
beerwin
  • 9,813
  • 6
  • 42
  • 57
  • this is really nice, I like that it pauses on hover, could you add paging dots to the bottom/center? – drooh Oct 27 '21 at 19:08
0

So here is the best answer I could come up with:

First, you create a container with a span and an img.

<div class="container">
  <img id="image">
  <span id="text"></span>
</div>

Then, you position everything where you want, add some style to everything and create the fade transitions with @keyframes (in this example, I'll position the text and image in the center of the page).

body {
  background-color: #000;
  height: 100vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.container {
  width: auto;
  height: auto;
  padding: 1rem;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
}

span {
  color: #fff;
  font-family: sans-serif;
  font-size: 2rem;
  margin: 0 1rem;
}

img {
  height: 2rem;
  width: 2rem;
  margin: 0 1rem;
  object-fit: cover;
  border-radius: 2px;
  border: none;
}

@keyframes fade {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  80% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

Lastly, you need a function to change the text innerHTML and image src every x seconds.

const text = document.getElementById("text");
const image = document.getElementById("image");
var text_options = ["Orlandos Studio", "Fida in Van", "Eternalife Productions"];
var image_options = [
  "http://via.placeholder.com/400x400",
  "http://via.placeholder.com/400x400",
  "http://via.placeholder.com/400x400"
];
var i = 0;
var j = text_options.length;

text.innerHTML = text_options[I];
image.src = image_options[i];

setInterval(function loop() {
  text.innerHTML = text_options[i];
  text.style.animation = "fade 3s ease-in-out infinite";
  image.src = image_options[i];
  image.style.animation = "fade 3s ease-in-out infinite";
  i = (i + 1) % j;
}, 3000);

Take a look at my solution on Codepen: https://codepen.io/maxym11/pen/OJMERLJ

Hope it works!

EDIT 1: I realized you wanted to draw attention to

a vanilla javascript alternative to Mals Cycle 2 that has most of the same features, advance slide prev/next, pager, timed, preload,

so I recommend you to check out this tutorial: https://www.w3schools.com/howto/howto_js_slideshow.asp

EDIT 2: Also take a look at this, this, this, and this.

MaxxyM11
  • 36
  • 3