Mosaiqy is a jQuery plugin for viewing and zooming photo working on Opera 9+, Firefox 3.6+, Safari 3.2+, Chrome and IE7+. Photos are retrieved from a JSON/JSONP data structure and randomly moved inside the grid. All expensive animations are taken over by your GPU on recent browsers using CSS3 transitions, minimizing the CPU overhead. (for technical detail see README file on github project).
So far, integration demo with Flickr, Instagram and Panoramio were realized. If you'd like to see some other examples with your favourite service (not yet listed here) just let me know:
No bugs were reported so far.
Mosaiqy was specifically designed for jQuery 1.6 or newer and HTML5 pages, for an easy integration with Paul Irish's HTML5 boilerplate.
If you don't use HTML5 boilerplate (as neither do all demo pages) you could run anyway this plugin:
all you need is to choose the HTML5 doctype defining multiple <html> tags
wrapped on conditional comment.
<!doctype html>
<!--[if lt IE 7]> <html class="no-js ie6" lang="en"> <![endif]-->
<!--[if IE 7]> <html class="no-js ie7" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="no-js ie8" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
<head>
...
if you do not load modernizr into your page, please make sure to insert the
snippet below into your <head> section.
If you plan to run this plugin on IE versions prior to 9 you will need to include shiv (you may omit the protocol) and
innerShiv scripts
inside a conditional comment. (Note: if you load jQuery 1.7+ innerShiv is no longer needed).
<head>
<!--[if lt IE 9]>
<script src="//html5shim.googlecode.com/svn/trunk/html5.js"> </script>
<script src="http://jdbartlett.com/innershiv/innershiv.js"> </script>
<![endif]-->
<script>
(function(doc) {
doc.className = doc.className.replace(/(^|\b)no\-js(\b|$)/, 'js');
}(document.documentElement));
</script>
...
</head>
Finally, simply include the CSS file, then jQuery and the javascript plugin (for performance reasons include scripts at the bottom of your document).
<link rel="stylesheet" media="screen" href="lib/lib-css/mosaiqy.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"> </script>
<script src="lib/mosaiqy-1.0.1.min.js" id="mosaiqy-tpl"></script>
The first thing to know is how the plugin works: the blocks on the grid are generated by a HTML5 template (the highlighted rows) and the information about images (path of thumbnail/zoom and description) are retrieved by a JSON/JSONP data structure. This is the javascript snippet I used for the example in this page (you can find it at the bottom of the source code)
<script src="lib/mosaiqy-1.0.1.min.js" id="mosaiqy_tpl">
<div>
<figure><a href="images/zoom/${img}"><img src="images/thumb/${img}" longdesc="...">
<figcaption>${desc}</figcaption></a>
</figure>
</div>
</script>
<script>
$(document).ready(function() {
$('.mosaiqy').mosaiqy({
template : "mosaiqy_tpl",
...
data : [
{ img : "1.jpg", desc: "Rifugio «Città di Fiume»" }
...
]
});
});
</script>
The plugin looks for an element with class .mosaiqy with a nested unordered list ul.
As you can see on the first demo available, the list could be empty or partially filled with list-items in which
you have replicated your template with real data (for SEO purposes or other)
When you call the plugin you can specify some options (listed below). The most important one is data who accept an array of objects, each one containing the information about a single image (thumb and zoom). In this example, every object has img and a desc key (of course you can name your keys as you want). These key are dinamically replaced on the HTML5 template above respectively where the placeholders ${img} and ${desc} occur.
If your data structure is not flat and you need to find a key into nested sub-objects you can use dot-notation. if the JSON is like so
data : [
{
images : {
low_resolution : {
url : "1.jpg"
}
}
},
...
]
like in the instagram integration demo, then the placeholder is ${images.low_resolution.url}.
Some constraints:
<script> element
(I wrote mine in the element that loads the plugin, just to reduce code) which must define
an id attribute specified as the template option value;
<img> element, optionally wrapped in a <a> element (pointing to its zoom) and the
<figcaption> should contain image caption and/or information. This minimum markup is necessary to make the plugin
properly work.You can also add other markup than this or hide the existing one via css but remember that
the template code will be injected into a <li> element, so be sure not to wrap your template in
a list-item (I used a simple <div>).
If you also specify an URL for the longdesc attribute on the thumbnail image, your zoom image will
be automatically linked to that address. This behaviour could be necessary when using the plugin with an external
service integration - like panoramio - where a link to the photo or to the user page is requested by the
terms of service.
loop option is set to true,
the plugin loads a thumbnail
from the json even if the same image is already inside the grid. If avoidDuplicates
is set to true and JSON provides enough different images to load, the plugin will try to avoid
injecting duplicate thumbnails. Since this option performs some extra operation its
value is by default set to false.
Default value: falseavoidDuplicates option)
the plugin stops all sliding effects over the thumbnails. Otherwise JSON is reloaded
continuously on a loop.
Default value: false
<script> elements in which the markup of template has been
defined by the user.Mosaiqy was developed by Fabrizio Calderan, a frontend developer who lives in Italy and works for a digital media company located in the middle of bucolic venetian countryside, only one mile far from the beautiful lagoon of Venice.
For bug report you can contact me at ti.naredlacoizirbaf[ta]yqiasom but please keep in mind that, due to my work commitments, I'm not able to give free support for integration issues. Other contacts: twitter and linkedin
I'd like to (randomly) cite some people whose work gave me the possibility to realize mine.
Alex Sexton, for his article on Using Inheritance Patterns to Organize Large jQuery Applications, Dale Harvey for his beautiful JsDoc template whose elegance and cleanliness definitely convinced me to properly document my Javascript code, Addy Osmany, for the article on CSS3 Animation With jQuery Fallbacks, Adam Luikart (adamesque) for sharing code gists on jQuery deferred objects. Then Paul irish, Robert Casanova, Silvio Cioni, Silvia Nucci, Giulia Alfonsi for suggestions, testing and brainstorming, Roberto Butti for sharing the idea and for integration suggestions and finally thanks to my wife Laura for the patience.
A special mention goes to the melon's cream at 17% I found in a local fair, who gave me the opportunity to reach a couple of times the well-known Ballmer peak helping me in some circustances on writing code. Sometimes I think if I had not documented the plugin, maybe today I couldn't tell how the hell the code works =)