Creating a magazine style gallery in JS - javascript

I am trying to create a magazine style gallery which can fetch a number of JPGS (18) and render them in 2 divs. A Left and right button would then be used to load the next 2 pages. The first page would be the front-over which would be closed. Then afterwards the pages would be side by side like a spread.
I have created the following which is semi working, it loads in a list of JPGs and the next button pushes the image to the div and then iterates. The main issue is that when pressing the next button to change the page its iterating 1 at a time instead of changing to the next 2 pages.
I tried to change the +1 to a +2 in the for loop but it loads the first 2 page spread fine, then the rest it only iterates 1 page at a time.
Could anyone give me some advice on how this can be improved & change 2 pages at a time?
Here is a codePen to make this a bit clearer:
https://codepen.io/nolimit966/pen/JVoPJq
Thank you
var pages = [
{"name":"img1", "src":"images/1.jpg"},
{"name":"img2", "src":"images/2.jpg"},
{"name":"img3", "src":"images/3.jpg"},
{"name":"img4", "src":"images/4.jpg"},
{"name":"img5", "src":"images/5.jpg"},
{"name":"img6", "src":"img/prod-6.png"},
{"name":"img7", "src":"img/prod-7.png"},
{"name":"img8", "src":"img/prod-8.png"},
{"name":"img9", "src":"img/prod-9.png"},
];
imgIndex = 0;
document.getElementById("image2").src = pages[0].src;
document.getElementById("nextBtn").addEventListener("click", function(){
var page2 = document.getElementById("image1")
if(pages.length > imgIndex+1){
imgIndex++;
// page1.classList.toggle('is-active');
document.getElementById("image1").style.display = "block";
document.getElementById("image1").src = pages[imgIndex].src;
document.getElementById("image2").src = pages[imgIndex+1].src;
} else {
console.log("its zero");
imgIndex = 0;
}
});
<button id="prevBtn">Previous</button>
<button id="nextBtn">Next</button>
<div id="container">
<div id="page1">
<img src="" id="image1" alt="" style="display:none;"/>
</div>
<div id="page2">
<img src="" id="image2" alt=""/>
</div>
</div>

You have to add two to the index number each time when index number is not zero (not cover page)
When current page is at cover page (imgIndex=0)
imgIndex 0 -> 1: Display imgIndex 1 and 2
When current page is not at cover page (imgIndex>0)
imgIndex 1 -> 3: Display imgIndex 3 and 4
imgIndex 3 -> 5: Display imgIndex 5 and 6
So instead of
imgIndex++;
Try this
if(imgIndex == 0){
imgIndex++;
}else {
imgIndex += 2;
}

Related

Iterate through an array on click and change albums via another click

I have a ngFor loop which iterates over an array of famous people (see below), this is fine but I would now like to add in image gallery which is where things get tricky. Each person will have 2 photo albums, the albums will be simply strings of urls to remote photos - the first problem is that I would like to be able to click the image tag (or element close by) and on each click I want the image src to change to the next image, when it reaches the end ideally I would like it to go back again to the start or just stop.
this is tricky enough - but each person will have a secondary photo album which is much the same as the first i.e Array however - it gets activated when the user clicks the changeAlbum() which is on a thumbnail image below - the idea is that the first image of the array not in use (as clicking changeAlbum() makes it inactive ) populates this thumbnail and the gallery then uses the images from the secondary gallery - so essentially its like a complex toggle() between the 2 galleries combined with a click to iterate over the array of each gallery - it might even be cool if when you iterate through the first gallery that it auto switches to the secondary one and vice versa
Im not entirely sure how to approach it though - the html and the json struct are the only solid things I have in place.
<div class="card" *ngFor="let c of item" >
<div class="card-content">
<div class="card-image">
<img (click)="changePhoto()" [src]="{{ output image here from the click }}" />
</div>
<div class="card-titles">
<h1>
{{ c.name }}
</h1>
</div>
<div class="card-image">
<img (click)="changeAlbum()" [src]="{{ show image from album not in use here}}" />
</div>
</div>
</div>
The data structure I have so far is like this
item = [{
id: 1,
name: "Joe Jimbob",
album_Main: [{
selected: true,
"https://via.placeholder.com/250",
"https://via.placeholder.com/250",
"https://via.placeholder.com/250",
"https://via.placeholder.com/250",
}],
album_Secondary: [{
selected: false,
"https://via.placeholder.com/250",
"https://via.placeholder.com/250",
"https://via.placeholder.com/250",
"https://via.placeholder.com/250",
}]
}]
This is also relatively solid but im very open to any help anyone can give
changeAlbum(item:any) :void {
if( item.album_Main.selected ) {
item.album_Main.selected == false
} else {
item.album_Secondary.selected == false
}
}
and the change...
changePhoto(photos: Array<string>) :void {
// not sure how to interate this one by one on click
console.log( photos.length )
}
Check this Stackblitz example I made based on your code: https://stackblitz.com/edit/angular-pk6cu8
The important changes are these in app.component.ts
photoIndex = 0;
personIndex = 0;
selectedAlbum = this.item[0].album_Main;
altAlbum = this.item[0].album_Secondary;
isMainAlbumActive = true;
changePhoto() {
if (this.photoIndex < this.selectedAlbum.length - 1) {
this.photoIndex++;
} else {
this.photoIndex = 0;
}
}
changeAlbum() {
if (this.isMainAlbumActive) {
this.selectedAlbum = this.item[this.personIndex].album_Secondary;
this.altAlbum = this.item[this.personIndex].album_Main;
} else {
this.selectedAlbum = this.item[this.personIndex].album_Main;
this.altAlbum = this.item[this.personIndex].album_Secondary;
}
this.isMainAlbumActive = !this.isMainAlbumActive;
}

How to tell if <img> has href attribute?

So I have a simple slideshow using JavaScript to fade images in and out, where all but one of the img elements do not have a href attribute. I would like to put the href attribute of the image into the href attribute of the caption (actually the img alt attribute) so that the text is clickable when the particular slide shows up, and becomes unclickable when the slide goes to the next one. I am very inexperienced in JS and cannot find any resources online to help me with this particular issue. Here is the part of my HTML file (called Finley.html) that is used, and my slideshow.js file.
<section>
<!-- Slideshow -->
<h2 id="caption">Car ride home! First time meeting each other.</h2>
<img id="slide" src="images/Finley/car_ride_home.jpg" alt="">
<div id="slides">
<img src="images/Finley/car_ride_home.jpg" alt="Car ride home! First time meeting each other.">
<img src="images/Finley/he_lay.jpg" alt="Handsome boy!">
<img src="images/Finley/awwww.jpg" alt="First photo together">
<img src="images/Finley/photogenic_af.jpg" alt="Papa, we made it to the community Instagram!" href="https://google.com" target="_blank">
<img src="images/Finley/first_vet.jpg" alt="First vet trip was successful">
<img src="images/Finley/blop.jpg" alt="blop.">
<img src="images/Finley/squishy_cheek.jpg" alt="Car rides make me sleepy">
<img src="images/Finley/first_beach.jpg" alt="First time at the beach and I got rocked by the waves">
<img src="images/Finley/sploot.jpg" alt="sploot.">
<img src="images/Finley/floopy_ears.jpg" alt="My family loves how floopy my ears are!">
<img src="images/Finley/daisy_gf.jpg" alt="Playing with my friend Daisy!">
</div>
</section>
slideshow.js:
$(document).ready(function() {
//declare variables
var nextSlide = $("#slides img:first-child");
var nextCaption;
var nextSlideSource;
// the function for running the slide show
var runSlideShow = function() {
// write the function
$("#caption").fadeOut(1000);
$("#slide").fadeOut(1000,
function() { //callback function
if (nextSlide.next().length == 0) {
nextSlide = $("#slides img:first-child");
} else {
nextSlide = nextSlide.next();
}
nextSlideSource = nextSlide.attr("src");
nextCaption = nextSlide.attr("alt");
if (nextCaption == "Papa, we made it to the community Instagram!") {
$("#caption").attr("href", nextSlide.attr("href"); $("#caption").attr("target", nextSlide.attr("target");
}
$("#slide").attr("src", nextSlideSource).fadeIn(1000); $("#caption").text(nextCaption).fadeIn(1000);
}
); //callback
}; //ready
// start slide show
var timer1 = setInterval(runSlideShow, 5000);
// here's one way to code this app without using the toggle event method
$("#slide").click(function() {
if (timer1 != null) {
clearInterval(timer1);
timer1 = null;
} else {
timer1 = setInterval(runSlideShow, 1000);
}
});
})
This code displays the caption as text above the image, and the image stays on screen for 5 seconds before fading to the next image. To clarify, I'd like the caption text that appears to become a hyperlink to Google (actual site censored) for the one picture when it is displayed, and then return to normal once the next picture comes up. I tried putting line 21-24 in to test for the caption and set the attribute, but those lines stop the slideshow from working (remove those lines to see how it should behave). Maybe it's something in the if statement in line 21, but I'm not sure how to proceed. Any help or tips would be appreciated!
You can do it either like this:
this.hasAttribute('href');
or
$(this).is('[href]');
More Info

how to get divs to display one at a time, set to a time

I have been playing with setInterval and setTimeout to get one div to display before moving on to get the second div to display and then the third (final). After the final div displays I want to loop back to the first div to begin the process of toggling the divs again.
setInterval(function(){
$(".one").toggle();
$(".two").toggle();
}, 5000);
So I find that this loop works really well but when I introduce the ".third" div it skips the second and I am super confused!!
Give them all the same class, and use a counter variable that you increment each time to know which one to show. Use modulus to wrap around when you reach the last div.
var counter = 0;
setInterval(function() {
$(".class").hide();
$(".class").eq(counter).show();
counter = (counter + 1) % $(".class").length;
}, 2000);
.class {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="class">
Div 1
</div>
<div class="class">
Div 2
</div>
<div class="class">
Div 3
</div>
<div class="class">
Div 4
</div>
you need to iterate over your divs otherwise you are just toggling all of them every 5000ms, which might seem to work for only two divs, but not gonna work for more
pseudocode:
var divs = [$(".one"),$(".two"),$(".three")]
var index = 0
function focusNextDiv(){
//hide all divs
//select divs[index] and toggle it
//increment index by 1
//check if index is bigger than divs.length if so reset index to 0
}
setInterval(function(){
focusNextDiv()
}, 5000);

how to pass image for popup into jquery without hard coding

I'm learning jQuery and I need to figure out how to not hard-code. So I have 2 different divs (master and popup) being populated by an array. The first div (master) is visible and the second (popup) that I'm using as a pop-up is hidden. On the view, you see an image in the div( master) and when it is clicked, I have a jQuery function that triggers the hidden div (popup) to show up.
Now if 10 items are gotten from the array, I have 10 images displaying but when I click on any image (including the first), only the first image in the array populates the popup div.
I hard-coded a 'fix' based on my current jQuery knowledge but this is repetitive code which means I can only have the amount of divs declared in my jQuery. I need to find a way that each image displays it's corresponding popup without having to hard code it in all the way
My html code:
Master div:
<div class="master">
<div id="imgprop"><img src="IMGCOMP/bgggg.jpg" alt="Gallery Image" height="238" width="238" /></div>
<div id="ps1" class="popit1" #hard coded popit id>
<section>
<span>IMAGE TITLE</span>
<span id="zoom"></span>
</section>
</div>
</div>
<div class="master">
<div id="imgprop"><img src="IMGCOMP/bgg.jpg" alt="Gallery Image" height="238" width="238" /></div>
<div id="ps1" class="popit2" #hard coded popit id>
<section>
<span>IMAGE TITLE</span>
<span id="zoom"></span>
</section>
</div>
</div>
Popup div:
<div id="GbgPopup1" #hard coded gbpopup id>
<div id="GPopupcontent">
<div class="closeit"></div>
<span class="ecs_tooltip_">Press esc to close <span class="arrow"></span></span>
<div class="image">
<img src="IMGCOMP/bgggg.jpg" alt="Gallery Image" height="400" width="430" />
</div>
</div>
</div>
<div id="GbgPopup2" #hard coded gbpopup id>
<div id="GPopupcontent">
<div class="closeit"></div>
<span class="ecs_tooltip_">Press esc to close <span class="arrow"></span></span>
<div class="image">
<img src="IMGCOMP/bgg.jpg" alt="Gallery Image" height="400" width="430" />
</div>
</div>
</div>
My jQuery code:
jQuery(function($) {
#hard coded
$(".popit1").click(function() {
setTimeout(function(){ // then show popup, deley in .5 second
loadPopup1(); // function show popup
}); // .5 second
return false;
});
$(".popit2").click(function() {
setTimeout(function(){ // then show popup, deley in .5 second
loadPopup2(); // function show popup
}); // .5 second
return false;
});
/* event for close the popup */
$("div.closeit").hover(
function() {
$('span.ecs_tooltip_').show();
},
function () {
$('span.ecs_tooltip_').hide();
}
);
$("div.closeit").click(function() {
disablePopup(); // function close pop up
});
$(this).keyup(function(event) {
if (event.which == 27) { // 27 is 'Ecs' in the keyboard
disablePopup(); // function close pop up
}
});
var popupStatus = 0; // set value
#hard coded
function loadPopup1() {
if(popupStatus == 0) { // if value is 0, show popup
$("#GbgPopup1").fadeIn(0500); // fadein popup div
popupStatus = 1; // and set value to 1
}
}
function loadPopup2() {
if(popupStatus == 0) { // if value is 0, show popup
$("#GbgPopup2").fadeIn(0500); // fadein popup div
popupStatus = 1; // and set value to 1
}
}
#hard coded
function disablePopup() {
if(popupStatus == 1) { // if value is 1, close popup
$("#GbgPopup1").fadeOut("normal");
$("#GbgPopup2").fadeOut("normal");
popupStatus = 0; // and set value to 0
}
}
});
Every help and more jQuery resources to help improve my knowledge is welcomed
I hope I understand your question right. Do you want to know how to take the picture source from master and put it into the popup?
To get the src of the picture in master you can do this:
$(".popit").click(function() {
setTimeout(function(){ // then show popup, deley in .5 second
loadPopup(this); // function show popup
}); // .5 second
return false;
});
function loadPopup(clickedElement) {
if(popupStatus == 0) { // if value is 0, show popup
// first find the img tag from master
var imgSrc = $(clickedElement).parent().find("img").attr("src");
var popup = $("#GbgPopup");
popup.find("img").attr("src", imgSrc);
popup.fadeIn(0500); // fadein popup div
popupStatus = 1; // and set value to 1
}
}
I'm sorry if there are bugs in the code, I did not run it. I trust you can remove the hard coded part from your code again.
create a master div and use http://api.jquery.com/appendto/ to dinamically generate every popup passing only the image and the counter
ie:
function generatePop(image, counter) {
var html = '<div class="ecs_tooltip_" id="pop"'+counter+"><img src=... </div>';
$(html).appendTo('#master-div');
}
After seeing Martin's answer, I was able to dig more into jQuery and adapt his answer to make it work.
All I did was move the code in loadpopup() function into the parent .click() function, change the $(".popit").click for the div(master) to $(".master").click to effectively select the whole div, used the $(this) so I can get the current clicked img in the master div and then replaced the src in the popup div
var popupStatus = 0; // set value
$(".master").click(function() {
var imgSrc = $(this).find('img').attr('src');
var popup = $("#GbgPopup");
popup.find("img").attr("src", imgSrc);
popup.fadeIn(0500); // fadein popup div
popupStatus = 1; // and set value to 1
//return false;
});

javascript image gallery query (next image)

This is my first time on stackoverflow, I really hope someone can help. I'm fairly novice at coding, so I hope my query is simple to solve.
I have created a simple javascript image gallery, where if you click on the left or right arrow it loops to show the next image in my array list. I also have quicklinks that jump to the specific images in this list. How can I get my next/back links to then continue on, to show the next image from the one currently selected? E.g if I have jumped to gallery image 3, for it to then show the next image along from it in the list gallery image 4, and not gallery image 2.
Below are samples of my code.
Thanks so much in advance for your help.
Here is my script:
var num=0;
imgArray = [
['../00_assets/gallery/work_00.jpg','Gallery', '1 of 6',],
['../00_assets/gallery/work_01.jpg','Gallery', '2 of 6',],
['../00_assets/gallery/work_02.jpg','Gallery', '3 of 6'],
['../00_assets/gallery/work_03.jpg','Gallery', '4 of 6'],
['../00_assets/gallery/work_04.jpg','Gallery', '5 of 6'],
['../00_assets/gallery/work_05.jpg','Gallery', '6 of 6'],
]
function slideshow(slide_num) {
document.getElementById('mypic').src=imgArray[slide_num][0];
document.getElementById('mypic').alt=imgArray[slide_num][1];
document.getElementById('number').innerHTML=imgArray[slide_num][2];
}
function slideshowUp() {
num++;
num = num % imgArray.length;
slideshow(num);
}
function slideshowBack() {
num--;
if (num < 0) {num=imgArray.length-1;}
num = num % imgArray.length;
slideshow(num);
}
Here is my HTML (I've taken out the bits that do not seem relevant):
<div align="left">
<!-- First image in array list is here -->
<img src="../00_assets/gallery/work_00.jpg" id="mypic" name="mypic" alt="Gallery">
<!-- Previous link is here -->
←
<!-- First image number is here -->
<div id="number">1 of 9</div>
<!-- Next link is here -->
→
<!-- Three quicklinks are link is here -->
Quicklink 1 |
Quicklink 2 |
Quicklink 3 |
Thank you so much.
You should update your num variable whenever you change the current slide.
Then, when a quicklink is clicked, it will have the current slide for the other methods (slideshowUp and slideshowBack) to work with and keep the navigation as expected.
In other words:
function slideshow(slide_num) {
num = slide_num; // add this line
document.getElementById('mypic').src=imgArray[slide_num][0];
document.getElementById('mypic').alt=imgArray[slide_num][1];
document.getElementById('number').innerHTML=imgArray[slide_num][2];
}

Categories

Resources