Creating a Carousel with JS, HTML, CSS Part 2
JavaScript Experiment: Carousel images
Part 2
The Set-up:
Lets make some changes.
How it looks after the initial set-up:
There are a few design changes I'd like to make before I put in the images, and I'll do that now. The main reason is I want the left and right image containers to be skewed and smaller than the main image. When the images change, it should feel like they are moving. I'll add that styling now, so if there are any problems with how the images appear when they are assigned a new div, I'll know before going to deep in the code.
I'm going to run the HTML file in the browser, and inspect it with the web dev tools. There I can click on an element and change its properties and see the results in live time. This is part of why setting up that CSS file is helpful. The web dev tools will pick up the related CSS class's and ID's and I can manipulate them directly. Once I have it looking how I want, I can copy and paste what I have done into my CSS file and have the same results when the page is reloaded.
*helpful hint*
Sometimes the browser will want to load an older version of a file that it has stored in its cache. If something isn't changing and you suspect it should, try clearing the browsing data to clear that cache. Then when the page is reloaded, it will grab the newest version you have saved.
See the live demo:
----Image: redesign---
The biggest changes are made to the #right_img, #main_img, and #left_img containers. I have gone into the setup javascript and removed the test code that put red borders on all the DOM elements we wanted to test.
Below are the transforms, skews, and box shadows applied to give it the shape it has in the image. This can be and will be altered as the design gets tweaked. Feel free to play with the CSS and set it up how you like.
I have also added an @media to make the #main_img width 75vw when the max-width screen size is smaller than 800 px.
--start code block--
#left_img {
width: 20vw;
height: 45vh;
margin-top: 4vh;
transform: skew(-10deg, -3deg);
box-shadow: -2px 2px 10px grey;
position: relative;
z-index: 7;
}
#main_img {
box-shadow: 0px 0px 10px black;
position: static;
z-index: 8;
border: 1px solid silver;
}
#right_img {
width: 20vw;
height: 45vh;
margin-top: 4vh;
transform: skew(10deg, -2deg);
box-shadow: 2px 2px 10px grey;
position: relative;
z-index: 7;
}
/* MOBILE */
@media all and (max-width: 799px) and (min-width: 220px) {
#main_img {
width: 75vw;
}
--end code block--
Let's get some Images in there!
All my images are jpg and are in an images folder inside of the main folder where the HTML, CSS, and JavaScript sit. On a live site, you may need to add a path to the image file into the JS to retrieve the images properly. For local, and in this experiment, I only need to know 'images\faces0.jpg". I'll show that in the first step.
I created the play function first and added a clearinterval so I could pause it during the run if there were issues.
So play and pause are first.
I also added a few Global items to help control the carousel as it iterated through the possible indexes.
(UPDATE: 9/20/2020 added a break to the for loop in assignIMGs(n). The loop only needs to run 3 times)
-- start code block PLAY/PAUSE ---
//-- ADDED GLOBALS:
let PLAY_CAROUSEL;
// hold the current index for carousel image assignment
let CURRENT = 0
//set up a bool to stop users from skipping images while carousel is in play mode.
let PLAYING = false;
function assignIMGs(n) {
//The number of images I have for the carousel are 0-20:
max = 20
min = 0
count = 0;
for (i = n; i <= max; i++) {
if(count >= 3) {
break
}
path = getpath(i)
if (count == 0) {
LEFT_IMG.src = path
}
if (count == 1) {
MAIN_IMG.src = path
}
if (count == 2) {
RIGHT_IMG.src = path
}
count++
}
if (n + 1 > max || n == max) {
path = getpath(0)
MAIN_IMG.src = path
}
if (n + 2 > max || n == max) {
path = getpath(1)
RIGHT_IMG.src = path
}
//console.log(`current n = ${n}`)
if (n < max) {
CURRENT = n + 1
return n + 1
}
else {
CURRENT = 0
return 0
}
}
function BTN_listener() {
//LEFT_BTN.addEventListener('click', left)
PLAY_BTN.addEventListener('click', play)
PAUSE_BTN.addEventListener('click', pause)
//RIGHT_BTN.addEventListener('click', right)
}
function getpath(n) {
let path = "images/"
let name = "faces" + n + '.jpg'
return path + name
}
function play() {
PLAYING = true
var n = CURRENT
PLAY_CAROUSEL = setInterval(function () { n = assignIMGs(n) }, 2000);
}
function pause() {
PLAYING = false
clearInterval(PLAY_CAROUSEL)
}
--end code block PLAY/PAUSE ---
The first function I wrote was the assignIMGs(n).
I knew I wanted to assign the images to the elements LEFT_IMG, MAIN_IMG, and RIGHT_IMG.
The images, although not in an array, are being retrieved by a number affixed to the image name. So treating it as an array, I stated a min and a max. The path is retrieved by applying a number to the end of the setup file name system I have. So much like an array, I know my images do not go beyond:
'faces20.jpg' or below 'faces0.jpg'. I can locate and access each one by iterating through those numbers 0-20, just like I would an array.
I set up the CURRENT global to hold our current number that is the first image in LEFT_IMG.
PLAYING is set up so that users can't press the left, or right button as the carousel images are being assigned during the interval.
play and pause merely set the interval and clear it as needed. CURRENT holds the first image number and it is retrieved with getpath(n).
For left and right, because I'm still not using an array, but simply the file names and an affixed number to the filename, I'm still going to pretend I'm accessing an array with the min, max, allowing the images that are beyond 20, or below 0, to set to the proper index/number picture.
-- start code block PLAY/PAUSE ---
function right() {
if (!PLAYING) {
max = 20
min = 0
CURRENT = CURRENT + 1
if (CURRENT > max) {
CURRENT = 0
}
if (CURRENT < min) {
CURRENT = max
}
next = CURRENT + 1
prev = CURRENT - 1
if (next > max) {
next = 0
}
if (prev < 0) {
prev = max
}
path1 = getpath(prev)
LEFT_IMG.src = path1
path2 = getpath(CURRENT)
MAIN_IMG.src = path2
path3 = getpath(next)
RIGHT_IMG.src = path3
}
}
function left() {
if (!PLAYING) {
max = 20
min = 0
CURRENT = CURRENT - 1
if (CURRENT > max) {
CURRENT = 0
}
if (CURRENT < min) {
CURRENT = max
}
next = CURRENT + 1
prev = CURRENT - 1
if (next > max) {
next = 0
}
if (prev < 0) {
prev = max
}
path1 = getpath(prev)
LEFT_IMG.src = path1
path2 = getpath(CURRENT)
MAIN_IMG.src = path2
path3 = getpath(next)
RIGHT_IMG.src = path3
}
}
--end code block PLAY/PAUSE ---
This could be set up to access an array of the image file names instead. So if you have files you can't rename, you'd need to put them into an array, and access them by index. In theory, it should work just the same.
Now that the experiment is done. We have code we can reference and use if ever someone or ourselves would like a carousel on their page!
There's a hiccup when this carousel runs the first time as the images are not stored in the browser cache. How would we fix that? Should we? If the number of images increased to 200, would we want the images pre-loaded, lazy-loaded, or to let it hiccup? Let me know what you think.
GIMME THE CODE:
live github pages link: Faces 2019
*end notes*
If I may need to explain something further, as always, drop a comment, let me know.
If I made a mistake or error, let me know.
Take it, break it, make it your own.
May the spam be ever in your flavor!
Comments
Post a Comment