Create an Image Slideshow in React

Responsive, Auto-play, Manual Navigation Buttons

An Object Is A
JavaScript in Plain English

--

We’re going to build a React image slider that has an auto-play function as well as manual navigation buttons. We won’t be using any external libraries; all native JSX, CSS, JavaScript.

We’ll start by putting all of our elements on screen.

We need two components: Deck.js and Card.js

We have 6 elements to work with:

  • In the Deck.js
    1. an img that we’ll use as a button for moving right (IMG)
    2. an img that we’ll use as a button for moving left (IMG)
    3. a view port (DIV)
    4. an images container (DIV)
    5. a DIV to hold our “radio” buttons (DIV)
  • In the Card.js
    6. a “card” which we’ll use to hold the image (DIV)
    7. the actual image (IMG)

Now we need to center everything on screen.

We’ll use a combination of absolute positions and transforms.

Now that everything is centered, we need to order the cards from left to right.

We write a simple function that determines the middle card of our deck and moves the cards to the left of that middle to the left and the cards to the right of that middle to the right.

order_cards = () => {
let counter_for_right = 1,
counter_for_left = this.middle_card_by_index;
for (let i = 0; i < this.images.children.length; i++) {
this.images.children[i].style.transitionDuration = '0.0s';
if (i < this.middle_card_by_index) {
this.images.children[i].style.left = `-${(counter_for_left *
this.new_width) - (this.new_width / 2)}px`;
counter_for_left--;
} else if (i > this.middle_card_by_index) {
this.images.children[i].style.left = `${(counter_for_right *
this.new_width) + (this.new_width / 2)}px`;
counter_for_right++;
} else {
this.images.children[i].style.left = `${this.new_width /
2}px`;
}
}
}

Let’s discuss RESPONSIVE.

To make our carousel responsive, we need to resize our view port based on percentages and not hard pixel units.

So we’ll just pick 50% and calculate a hard pixel count based on the width of the user’s browser window; then we’ll run this code in a resize window event listener.

window.addEventListener(‘resize’, () => {
img_width_as_percentage = 50;
// img_width_as_percentage = window.innerWidth < 768 ? 100 : img_width_as_percentage;
this.new_width =
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ?
(img_width_as_percentage / 100) * window.screen.width :
(img_width_as_percentage / 100) * window.innerWidth;
this.view_port.style.width = `${this.new_width}px`;this.order_cards();
});

We also resize our left & right buttons and “radio” buttons based on the viewport and window width.

Now that we have our resize code, every time we resize the browser window, our carousel resizes.

We have 3 large tasks on-hand

  1. BUTTON navigation
  2. RADIO” navigation
  3. Auto-Play functionality

The basis for ALL navigation is this piece of code here:

for (let i = 0; i < this.images.children.length; i++) {
this.images.children[i].style.transitionDuration = ‘0.0s’;
const updated_position = this.last_positions[i] + /* some difference */; this.images.children[i].style.left = `${updated_position}px`;
this.last_positions[i] = updated_position;
}

What it says is this:

Take the current position of all of the images…

where are they on the X-axis?

…add some difference which will move them to a new position.

We have a last_positions array to keep track of where our images are on screen.

Let’s code up the BUTTON navigation

Very simple.

We move the images left or right one whole card width.
This makes our difference simply equal to the width of one card.

this.images.children[i].style.transitionDuration = ‘0.0s’;const updated_position = this.last_positions[i] + this.new_width;this.images.children[i].style.left = `${updated_position}px`;
this.last_positions[i] = updated_position;

Let’s code up the RADIO navigation

Very simple.

We calculate which “radio” button the user clicked.

Do a little calculation to determine how many pixels to move left or right.
That is our difference.

let new_card = null;for (let i = 0; i < this.images.children.length; i++) {
if (event.target === this.selection_buttons_container.children[i])
new_card = i;
}
for (let i = 0; i < this.images.children.length; i++) {
const updated_position = this.last_positions[i] +
((this.current_card — new_card) * this.new_width);
this.images.children[i].style.transitionDuration = ‘0.0s’;
this.images.children[i].style.left = `${updated_position}px`;
this.last_positions[i] = updated_position;
}

Let’s handle Auto-Play

The logic is simple.

Just put our next button navigation logic in a setInterval() function.

this.autoplay_timeout_id = setTimeout(() => {
this.autoplay_interval_id = setInterval(() => {
for (let i = 0; i < this.images.children.length; i++) {
this.images.children[i].style.transitionDuration = ‘0.0s’;
const updated_position = this.last_positions[i] —
this.new_width;
this.images.children[i].style.left = `${updated_position}px`;
this.last_positions[i] = updated_position;
}
this.current_card = (this.current_card ===
this.number_of_cards_by_index) ? 0 : ++this.current_card;
}, 1100);
}, 1200);

There is much more nuance to this project

You can get the source files here and you can follow the video tutorial down below.

If you would like a more in-depth guide, check out my full video tutorial on YouTube, An Object Is A.

Be sure to follow us on Instagram and Twitter to keep up with our latest Web Development tutorials.

Be sure to follow us on Instagram and Twitter to keep up with our latest Web Development tutorials.

--

--