Scroll through web images after thumbnail - php

I searched, but did not find the answer to this.
I have a website that displays hundreds of images in thumbnail format. I'm currently using php to display all of the images in thumbnail, then when the thumbnail is clicked upon to display the images in full-size.
What I would like to do is be able to click on a thumbnail and see the resulting full-size image, then at that point be able to scroll both back and forth through the full-size images without going back to the thumbnails.
As an added feature, when viewing the thumbnails, I would like to only load the ones that are currently displayed on the client page...ie - if the client screen resolution supports 20, then load only 20 and wait to load the rest on the client until the user scrolls down. The primary client in this use case is an iphone.
Thanks in advance!

you need to use a slider jquery plugin
Like
Jquery Light Box Plugin

When you click on the image, it should point to a new PHP file containing the full size image, or even better, load it in a new <div> with php you can get the client resolution with other tools

You actual have two seperate questions. One is to show the thumbs fullsize and be able to click to the next image. Almost every plugin to show images has that options. Personally i use fancybox, but pick anyone you like. To enable the next/prev buttons you need to group the images useing the rel tag.
Now to load the images per page, similar to google does it, you need to load it all in by javascript. Below is a setup of how you could do it. This is untested, as I did not have an image gallery at hand.
In the code below I load all images into the array at once, which is not perfect when you have a lot of images (like 1000+). In that case your better of using AJAX to load a new page. But if you have a smaller amount of images, this will be faster.
<script>
//simple JS class to store thumn and fullimage url
function MyImage(thumbnail, fullimage, imgtitle) {
this.thumb = thumbnail;
this.full = fullimage;
this.title = imgtitle;
}
//array that holds all the images
var imagesArray = new Array();
var currentImage = 0;
<?php
//use php code to loop trough your images and store them in the array
//query code to fetch images
//each row like $row['thumb'] and $row['full'] and $row['title'];
while ($row = mysqli_fetch_assoc($result))
{
echo "imagesArray.push(new MyImage('".$row['thumb']."', '".$row['full']."', '".$row['title']."'));";
}
?>
//the thumb width is the width of the full container incl. padding
//In this case I want to use 50x50 images and have 10px on the right and at the bottom. Which results in 60x60
var thumbWidth = 60;
var thumbHeight = 60;
var screenWidth = $('body').width();
var screenHeight = $('body').height();
var maxImagesPerRow = Math.round(screenWidth / thumbWidth);
var maxImagesPerCol = Math.round(screenHeight / thumbHeight);
var totalImagesPerPage = maxImagesPerRow * maxImagesPerCol;
//function to load a new page
//assuming you use jquery
function loadNextPage() {
var start = currentImage;
var end = currentImage + totalImagesPerPage;
if (end >= imagesArray.length) {
end = imagesArray.length - 1;
}
if (end<=start)
return; //last images loaded
$container = $('#thumbnailContainer'); //save to var for speed
$page = $('<div></div>'); //use a new container, not on stage, to prevent the dom for reloading everything on each iteration of the loop
for (start;start<=end;start++) {
//add a new thumbnail to the page
$page.append('<div style="margin:0;padding:0 10px 10px 0;"><a class="fancybox" rel="mygallery" href="'+imagesArray[start].full+'" title="'+imagesArray[start].title+'"><img src="'+imagesArray[start].thumb+'" alt="" /></a></div>');
}
currentImage = start;
//when all images are added to the page, add the page to the container.
$container.append($page);
}
$(function() {
//when loading ready, load the first page
loadNextPage();
});
//function to check if we need to load a new page
function checkScroll() {
var fromTop = $('body').scrollTop();
//page with a 1-based index
var page = 1 + Math.round(fromTop / screenHeight);
var loadedImages = page*totalImagesPerPage;
if (loadedImages==currentImage) {
//we are scrolling the last loaded page
//load a new page
loadNextPage();
}
}
window.onscroll = checkScroll;
</script>
<body>
<div id='thumbnailContainer'></div>
</body>

Related

how to load php array into javascript variable on runtime

i have a website/(mobile, app created with phone gap build), in this site i load some arrays with php into javascript to show some ads. on website it's work very well, but on the mobile apps (iOS and android) i got an empty space. if i fill the array variables in js directly, it works in all versions of the site web and mobile.
the problem is i have about 460 different ads to show. i like to load about 20 ads into js when users start or load the site/app in php i read the mysql db and load these ads witch shown less. after showing the ads, ads-couter +1 .(didn't show it here)
the reason why i'm doing this so, is, because i did'n find something to monetize my html5 css3 query web app, compiled with phone gap build.
now can someone show me or explain me why it works on web but not on app, or why it works both when i fill the variable in js direct??
my php works fine -> to js
in js i have this:
// werbung
function werbung_fill(){
id = new Array;
comment_start = new Array;
bannerLinks = new Array;
adBanners = new Array;
bannerTargets = new Array;
dimension = new Array;
comment_end = new Array;
aktiv = new Array;
angezeigt = new Array;
lasttime = new Array;
$.getJSON('inc/werbung_call.php', function(data) {
/* data will hold the php array as a javascript object */
$.each(data, function(key, val) {
id.push(val.id);
comment_start.push(val.comment_start);
bannerLinks.push(val.bannerLinks);
adBanners.push(val.adBanners);
bannerTargets.push(val.bannerTargets);
dimension.push(val.dimension);
comment_end.push(val.comment_end);
aktiv.push(val.aktiv);
angezeigt.push(val.angezeigt);
lasttime.push(val.lasttime);
});
});
}
function werbung(){
var randNum = Math.floor(Math.random() * (19 - 0 + 1)) + 0;
var topAdBanner = $('#topad > a > img');
var newcomment_start = comment_start[randNum];
var newBannerImg = adBanners[randNum];
var newBannerLink = bannerLinks[randNum];
var newBannerTarget = bannerTargets[randNum];
var newdimension = dimension[randNum];
var newcomment_end = comment_end[randNum];
// update new img src and link HREF value
$(topAdBanner).attr('src',newBannerImg);
$('#topad > a').attr('href',newBannerLink);
$('#topad > a').attr('target',newBannerTarget);
$('#topad > a').attr('alt',newdimension);
var deinTimer = window.setTimeout(werbung, 5000);
//$('#topad1').html(id[randNum]);
}
in
$(document).ready(function() {
// werbungs banner
$('<div id="topad"><img src="" width="320" height="50" alt="" border="0"></div><!-- #end #topad -->').prependTo( $( "#hauptheader" ) );
// werbung
werbung_fill();
werbung();
// werbung
}
with this, i can inject a div without compiling the apps again. (it works fine)
the js, php, index.html are on the same server and the compiled apps use the js css images from server too.
You have a few syntax errors in your JavaScript. You should validate your JavaScript here: http://www.jshint.com/
I suspect Android isn't parsing this correctly:
id = new Array;
Suggest using this syntax instead:
var id = [];

Change background only on refresh with javascript

Iam loading pages in dynamically with PHP like so:
<div id="content">
<div id="fadein">
<?php
/// load page content
$pages_dir = 'content';
if(!empty($_GET['p'])) {
$pages = scandir($pages_dir, 0);
//delete . and ..
unset($pages[0], $pages[1]);
$p = $_GET['p'];
// only files that are in the array can be loaded
if (in_array($p. '.php', $pages)) {
include($pages_dir. '/'.$p. '.php');
} else {
echo 'Helaas deze pagina bestaat niet';
}
} else {
include($pages_dir. '/index.php');
}
?>
</div>
</div>
If you use the navigation at the top of my site the PHP loads the relevant content.
And i got this script at the bottom of my page to change the background image:
function preload(arrayOfImages) {
$(arrayOfImages).each(function(){
$('<img/>')[0].src = this;
// Alternatively you could use:
// (new Image()).src = this;
});
}
// Usage:
preload([
'../public/background/test2/1.jpg',
'../public/background/test2/2.jpg',
'../public/background/test2/3.jpg',
'../public/background/test2/4.jpg',
'../public/background/test2/5.jpg',
'../public/background/test2/6.jpg'
]);
var totalCount = 6;
function changeBackground()
{
var num = Math.ceil( Math.random() * totalCount );
backgroundUrl = '../public/background/test2/'+num+'.jpg';
$('body').css('background-image', 'url(' +backgroundUrl+ ')');
}
changeBackground();
But everytime different content is loaded, the script is executed...
I don't want that. I only want to change the background when the user refreshes the page. Not when different content is loaded when the user is navigating through the site.
As it is now (based on your comment), you are reloading the whole page when you really want to load only new content.
To be able to get the effect that you want, you should use ajax (combining php and javascript) to refresh only a part of your page when you hit a navigation link.
What you could do is (using jQuery for an easy introduction to ajax...):
separate your php script from the html so that you can call it separately and include it in your initial html;
attach an event handler to your navigation links, cancelling the default action (undo the click) and use jQuery's load method to replace your content with the new content (call your php script with the correct parameters).
As the javascript is located in the main html file, it will only execute your background script on the initial page load or page refresh.
If you are trying to manage this through JavaScript alone, then you can create a Cookie with an array of page visits, then on page load you can refer to that array to determine whether a user has visited that page already.

Using JavaScript to show and hide PHP echoed XML data

I'm using PHP to echo out 50 video id's from an XML file. I use the video id's to embed 50 YouTube videos into my website. This works fine but I need to isolate the videos two at a time. I don't want the user to see all fifty videos at once. I want them to see two, then click next, see another two, then maybe click back, etc. etc.
Here's what I have so far:
$url = "http://www.theURLofmyXML.blah";
$xml = simplexml_load_file($url);
$i = 0;
while ($i < 49) {
$title = (string) $xml->query->results->item[$i]->title;
$videoid = (string) $xml->query->results->item[$i]->id;
$explanation = (string) $xml->query->results->item[$i]->explanation;
$i = $i + 1;
echo $title."<br />";
echo '<iframe width="400" height="225" src="http://www.youtube.com/embed/'.$videoid.'?rel=0&autohide=1&showinfo=0" frameborder="0" allowfullscreen></iframe><br/>';
echo $explanation."<br /><br />";
}
So I think the best thing to do is echo all fifty items to the page inside divs labeled 0 to 49...then use JavaScript to hide all divs except 0 and 1 until you click a next button and it switches to hiding everything except 2 and 3...and so on...
But I'm not sure how to do that in JavaScript/jQuery. I think using .show() and .hide() would work but I'm not sure of the syntax.
You can use the following HTML structure:
Previous videos
<div class="video-row active">
<!-- First couple videos -->
</div>
<!-- Loop through all videos, writing the other rows -->
<div class="video-row">
<!-- Last couple videos -->
</div>
Next videos
Note: Use the active class only in the first video row to show them by default on the page load.
With CSS, hide all .video-row (using: display:none;) and show only .video-row.active (using: display:block;).
Finally, use the following Javascript (jQuery needed) to navigate between video rows:
jQuery('.prev-video-row').click(function (event)
{
event.preventDefault();
var prev = jQuery('.video-row.active').prev();
if (prev.length)
{
jQuery('.video-row').removeClass('active');
prev.addClass('active');
}
});
jQuery('.next-video-row').click(function (event)
{
event.preventDefault();
var next = jQuery('.video-row.active').next();
if (next.length)
{
jQuery('.video-row').removeClass('active');
next.addClass('active');
}
});
Honestly speaking, I don't think it's great to have 50 videos embedding in a page - regardless of visibility or not; simply because they will be processed by the browser despite not being visible. (Feel free to correct me if I'm wrong, but the browser is going to see, and process, the whole DOM - and just apply the styles to the "hidden" bits.)
Gustavo Straube has given a really good answer on how to do this if you want to have 50 elements in the DOM despite the effects it may have on both browser and bandwith.
I'd probably go for something more along the lines of parsing the XML, storing all the data as JSON then dynamically updating the DOM with jQuery from HTML supplied with a templating framework like Mustache.js.
/* Generate JSON */
$url = "http://www.theURLofmyXML.blah";
$xml = simplexml_load_file($url);
$i = 0;
$json = array();
while ($i < 49) {
$arr['title'] = (string) $xml->query->results->item[$i]->title;
$arr['videoid'] = (string) $xml->query->results->item[$i]->id;
$arr['explanation'] = (string) $xml->query->results->item[$i]->explanation;
$json[] = $arr;
}
echo json_encode($json);
Then, in your markup have something like the below, just to initialise your first x videos - in this example 10..
$(document).ready(function(){
var template = '{{$title}}<br /><iframe width="400" height="225"'
+ 'src="http://www.youtube.com/embed/{{$videoid}}?rel=0&autohide=1&showinfo=0" frameborder="0" allowfullscreen></iframe><br/>'
+ '{{explanation}}<br /><br />';
var html = '';
var i=0;
for(; i<10; i++){
var item = json[i];
html += Mustache.to_html(template, item);
}
$('#videos').html(html); //where #videos is a div to contain your videos
Next up have an anchor (in this example #next) to get the next 10 videos..
$('#next').click(function(){
/* template, i and json are still in scope! */
var j = i+10;
for(; i<j; i++){
var item = json[i];
html += Mustache.to_html(template, item);
}
$('#videos').html(html); //where #videos is a div to contain your videos
});
The advantage of this is it's also easy to do a previous anchor...
$('#prev').click(function(){
/* template, i and json are still in scope! */
var j = i -10;
i -= 20; //10 for the current page, 10 for the start of the previous page
for(; i<j; i++){ //rebuild div content of previous page
var item = json[i];
html += Mustache.to_html(template, item);
}
$('#videos').html(html);
});
Just to re-iterate, this is an alternative solution - I've suggested it as using JSON is a little bit more lightweight and more flexible than XML, and it also removes the requirement for having 50 DOM elements that aren't in use at one time. There may be a reason you've chosen the implementation that you have, but it's not the implementation I would take if I was given this problem!
For html like:
<div id="section0"></div>
Your jquery would look like:
$(document).ready(function() {
$('#section0').show();
$('#section1').show();
$('#nextButton').click(function(e){
e.preventDefault();
$('#section0').hide();
$('#section1').hide();
$('#section2').show();
$('#section3').show();
return false;
}
});
And so on...

Image substitution

In the gallery of products I have choice to choose a color of item, seria, or side view. Each option has own picture. When I click one of these options I have src-substitution of image, for the effect I'm using fadeIn/fadeOut, it looks like:
$('button').click(function(){
$('img').fadeOut("slow",function(){
$(this).attr("src",newSRC);
$(this).fadeIn("slow");
});
});
but when fadeIn completed The picture does not have time to draw, even if it has already been loaded into the cache and it's looking very wierd for the site-gallery intercoms
I can not use preCache all images, because if the products will be a count of over 100 items the site will loading whole day, in the main case at low connections. I wanted to remove item fully, and then use load, but I can't remove items 'caz the gallery will crash (it's a flexible site, I can't remove items, all will collapse). Now I did a little gif, but ... facepalm, sorry.
So what do you think the best solution could be ?
I would wait for the next image to load before fading it in, like:
var loadFail;
$('button').click(function(){
$('img').fadeOut("slow",function(){
$(this)
.attr("src",newSRC)
.load(function(){
$('img').fadeIn("slow");
clearTimeout(loadFail);
});
loadFail = setTimeout(function(){
$('img').fadeIn("slow");
}, 4000);
});
});
I'd start the loading of the new image right away (into a temporary image object) on the click so it's available sooner (perhaps even before the fadeOut is done) rather than waiting until you actually need it to start the loading. This will get the image into the browser cache so it will load immediately when you assign the src of the real image and there will be less waiting:
$('button').click(function(){
var imgLoaded = false, fadeDone = false;
var fadeTarget = $('img');
// fadeIn the new image when everything is ready
function fadeIfReady() {
if (imgLoaded && fadeDone) {
fadeTarget.attr("src", newSrc).fadeIn("slow");
}
}
// create temporary image for starting preload of new image immediately
var tempImg = new Image();
tempImg.onload = function() {
imgLoaded = true;
fadeIfReady();
};
tempImg.src = newSrc;
// start the fadeOut and do the fadeIn when the fadeOut is done or
// when the image gets loaded (whichever occurs last)
fadeTarget.fadeOut("slow",function(){
fadeDone = true;
fadeIfReady();
});
});

How to make a simple dynamic slideshow/timelapse

I have a folder where are saved images from a webcam each X time.
I want to use these image to create a slideshow without transitions effects or music => i want to make a timelaps!
These slideshow must be dynamic (i can use php to build the list of image, each time a user want to watch the "video").
Any sugguestion and code to do this? Javascript? Php? or others??
Thanx!
That's the best way i found: simple and speedy
<HTML>
<HEAD>
<TITLE>Video</TITLE>
</HEAD>
<BODY BGCOLOR="#000000">
<img name="foto">
<SCRIPT LANGUAGE="JavaScript">
var Pic = new Array();
Pic[0] = '/images/image1.jpg'
Pic[1] = '/images/image2.jpg'
Pic[2] = '/images/image3.jpg'
//this part in real code is replaced with a PHP script that print image location dinamically
var t;
var j = 0;
var p = Pic.length;
var preLoad = new Array();
for (i = 0; i < p; i++) {
preLoad[i] = new Image();
preLoad[i].src = Pic[i];
}
//all images are loaded on client
index = 0;
function update(){
if (preLoad[index]!= null){
document.images['foto'].src = preLoad[index].src;
index++;
setTimeout(update, 1000);
}
}
update();
</script>
</BODY>
</HTML>
Have your PHP script send a meta refresh tag in the heading to reload the page with the latest image after the desired time.
NOTE: There are better, more AJAX-like ways of doing this, but this is the simplest. Using AJAX to reload just the image and not the whole page would be harder to write but a better user experience.

Categories