diff --git a/images/elephpants.php b/images/elephpants.php new file mode 100644 index 000000000..bfcb57a50 --- /dev/null +++ b/images/elephpants.php @@ -0,0 +1,69 @@ +, + url: , + data: + },{ + ... + }] + +*/ + +// 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); diff --git a/include/header.inc b/include/header.inc index f03252b8c..f2e1d1fe2 100644 --- a/include/header.inc +++ b/include/header.inc @@ -216,12 +216,10 @@ if (isset($shortname) && $shortname) { "; - foreach ($elephpants as $image) { - print ""; - } - print ""; + print ""; } ?> diff --git a/include/layout.inc b/include/layout.inc index a7a1edafa..6d8739646 100644 --- a/include/layout.inc +++ b/include/layout.inc @@ -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()) diff --git a/js/common.js b/js/common.js index fac32886e..fd59929cd 100644 --- a/js/common.js +++ b/js/common.js @@ -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 = $(''); + link.attr('href', photo.url); + link.attr('title', photo.title); + image = $(''); + 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); + }); + }); + }); /** diff --git a/styles/theme.css b/styles/theme.css index 602482a6f..cba1c182c 100644 --- a/styles/theme.css +++ b/styles/theme.css @@ -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;