1
0
mirror of https://github.com/php/web-php.git synced 2026-03-23 23:02:13 +01:00

Made elephpant image banner dynamic.

Elephpant images are pulled from flickr via the php-master server hourly.
The web site now provides a simple PHP script to serve a random sampling
of these images in JSON format.

The web browser now loads the elephpant images via JavaScript, requesting
only the number of images that are required to fill the viewport. Images
are inserted into the page using the data URI scheme. This ensures that 
only one http request is needed to load all of the required images.

If the browser window resizes, the JavaScript will fetch additional images
as required to fill out the viewport again. There is a slight delay built
in (250ms) to avoid excessive requests while the window is being resized.

Some browsers (e.g. older versions of MSIE) do not support the data URI
scheme. For these browsers we may wish to provide a fallback mechanism of
aggregating the images (e.g. MHTML, aka MIME HTML).

If the images fail to load, the elephant banner is hidden automatically.
This commit is contained in:
Stewart Lord
2011-09-21 04:33:01 +00:00
parent a4acb9b3cb
commit 86c75aca35
5 changed files with 132 additions and 32 deletions

69
images/elephpants.php Normal file
View File

@@ -0,0 +1,69 @@
<?php
/*
Simple script to serve elephpant images in json format.
This script is called directly by the browser to feed the
javascript generated banner of elephpant images.
The structure of the response data is:
[{
title: <image title>,
url: <link to image on flickr>,
data: <base64 encoded image>
},{
...
}]
*/
// determine how many images to serve.
if (isset($_REQUEST['count'])) {
$count = intval($_REQUEST['count']);
} else {
header('HTTP/1.1 400', true, 400);
print json_encode(array(
'error' => "Specify how many elephpants to serve via 'count'."
));
exit;
}
// read out photo metadata
$path = __DIR__ . '/elephpants';
$json = @file_get_contents($path . '/flickr.json');
$photos = json_decode($json, true);
// if no photo data, respond with an error.
if (!$photos || !is_array($photos)) {
header('HTTP/1.1 500', true, 500);
print json_encode(array(
'error' => "No elephpant metadata available."
));
exit;
}
// prepare requested number of elephpants at random.
shuffle($photos);
$elephpants = array();
foreach ($photos as $photo) {
// stop when we have the requested number of photos.
if (count($elephpants) == $count) {
break;
}
// skip photo if file doesn't exist.
if (!is_readable($path . '/' . $photo['filename'])) {
continue;
}
// add photo to response array.
$elephpants[] = array(
'title' => $photo['title'],
'url' => "http://flickr.com/photos/" . $photo['owner'] . "/" . $photo['id'],
'data' => base64_encode(file_get_contents($path . '/' . $photo['filename']))
);
}
print json_encode($elephpants);

View File

@@ -216,12 +216,10 @@ if (isset($shortname) && $shortname) {
</div>
<?php
// if elephpants enabled, insert placeholder nodes
// to be populated with images via javascript.
if (isset($config['elephpants'])) {
print "<div class='elephpants'><div class=images>";
foreach ($elephpants as $image) {
print "<img src='$image'>";
}
print "</div></div>";
print "<div class='elephpants'><div class=images></div></div>";
}
?>

View File

@@ -840,24 +840,6 @@ function site_header_beta($title = '', $config = array())
$STATIC_ROOT = "/";
}
// Prepare elephpant photo-stream.
// FIXME: This needs to be dynamically generated (randomized?)
// and delivered in a single http request (e.g. using data://
// uri scheme).
if (isset($config['elephpants'])) {
$elephpants = array(
'http://farm5.static.flickr.com/4111/5037379813_c727c94d83_s.jpg',
'http://farm6.static.flickr.com/5046/5246051917_77bd222e31_s.jpg',
'http://farm5.static.flickr.com/4116/4856848556_b8f64c1699_s.jpg',
'http://farm5.static.flickr.com/4114/4934705762_e67cc7a5a3_s.jpg',
'http://farm5.static.flickr.com/4081/4934704224_8f6d16ef1c_s.jpg',
'http://farm5.static.flickr.com/4097/4795284575_16f7692c31_s.jpg',
'http://farm5.static.flickr.com/4139/4795926308_4fa1038908_s.jpg',
'http://farm5.static.flickr.com/4135/4795285595_ec6c565c10_s.jpg'
);
$elephpants = array_merge($elephpants, $elephpants, $elephpants, $elephpants, $elephpants, $elephpants);
}
require dirname(__FILE__) ."/header.inc";
}
function site_footer_beta($config = array())

View File

@@ -237,6 +237,58 @@ $(document).ready(function() {
});
});
// load the elephpant images if elephpants div is in the dom.
$(".elephpants .images").first().each(function (idx, node) {
// function to fetch and insert images.
var fetchImages = function() {
// determine how many elephpants are required to fill the
// viewport and subtract for any images we already have.
var count = Math.ceil($(document).width() / 75)
- $(".elephpants .images img").length;
// early exit if we don't need any images.
if (count < 1) {
return;
}
// do the fetch.
$.ajax({
url: '/images/elephpants.php?count=' + count,
dataType: 'json',
success: function(data) {
var photo, image;
for (photo in data) {
photo = data[photo];
link = $('<a>');
link.attr('href', photo.url);
link.attr('title', photo.title);
image = $('<img>');
image.attr('src', 'data:Image;base64,' + photo.data);
$(node).append(link.append(image));
}
},
error: function() {
$(".elephpants").hide();
}
});
}
// begin by fetching the images we need now.
fetchImages();
// fetch more if viewport gets larger.
var deferred = null;
$(window).resize(function() {
window.clearTimeout(deferred);
deferred = window.setTimeout(function(){
fetchImages();
}, 250);
});
});
});
/**

View File

@@ -578,10 +578,9 @@ div.elephpants {
div.elephpants div.images {
height: 75px;
width: 3000px;
position: relative;
left: -1%;
background-color: #333;
text-align: center;
white-space: nowrap;
}
div.elephpants img {
@@ -590,15 +589,15 @@ div.elephpants img {
opacity: 0.5
-moz-opacity: 0.5;
-webkit-opacity: 0.5;
transition: all 0.5s ease-in-out;
-webkit-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
transition: all 0.25s ease-in-out;
-webkit-transition: all 0.25s ease-in-out;
-moz-transition: all 0.25s ease-in-out;
}
div.elephpants:hover img {
opacity: 0.75;
-moz-opacity: 0.75;
-webkit-opacity: 0.75;
opacity: 0.6;
-moz-opacity: 0.6;
-webkit-opacity: 0.6;
transition: all 0.25s ease-in-out;
-webkit-transition: all 0.25s ease-in-out;
-moz-transition: all 0.25s ease-in-out;