Mosaiqy

An amazing plugin for jQuery 1.9+ & HTML5

(8.75Kb minified — 3.19Kb minified + gzip)

Hosted on Github

Share if you like it

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).

Demos & service integration

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:

Up

Changelog

Version 1.0.0 release date: , 812 downloads

Version 1.0.1 release date: , 4322 downloads

Note: this version is intended for jQuery 1.6, 1.7 and 1.8.

Version 1.0.2 release date:

This is a maintainance release due to the changes occured in jQuery 1.9.

Tested on jQuery 1.9, 1.10.2, 2.0.0 and 2.0.2

Up

Requirements

Mosaiqy 1.0.2 was specifically designed for jQuery 1.9 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>
...

Unless you're loading 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 (and if you're also including jQuery < 1.7) you will need to include shiv (you may omit the protocol) and innerShiv scripts inside a conditional comment.

<head>
    <!--[if lt IE 9]>
        <script src="//html5shim.googlecode.com/svn/trunk/html5.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.10.2/jquery.min.js"> </script>
<script src="lib/mosaiqy-1.0.2.min.js" id="mosaiqy-tpl"></script>
Up

How to use

The first thing to know is how the plugin works: the blocks on the grid are generated by a HTML5 template (the highlighted rows) handlebars/mustache alike 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.2.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 interpolated with 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:

  1. The template must be defined inside a <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;
  2. The template must contain at least that specific markup. The thumbnail is represented by an <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.

Up

Options

animationDelay
the number of milliseconds between a slide effect and the next one. Default value: 3000 (3s)
animationSpeed
the number of milliseconds of slide effects. Default value: 800 (0.8s)
avoidDuplicates
boolean flag (true or false). If the 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: false
cols
the number of columns of the grid. Default value: 2
fadeSpeed
the number of milliseconds needed for fadeIn/fadeOut effects while opening and closing zoom images.
indexData
the number representing the JSON index from which the plugin should start to retrieve information. This could be useful to skip some initial images or to allow duplication of some thumbnails. Default value: 0
loadTimeout
the number of milliseconds to wait before discarding an image (thumbnail and zoom) due to excessive latency, network errors, 404 and so on. Default value: 7500 (7,5s)
openZoom
boolean flag (true or false). if set to true a click on a thumbnail will open a zoom image. If set to false no zoom will be open. Default value: true
onCloseZoom
if defined this function is called when a zoom image has been closed. An argument representing the <li> jQuery object containing the thumbnail is also passed to the callback.
onOpenZoom
if defined this function is called when a zoom image has been opened. An argument representing the <li> jQuery object containing the thumbnail is also passed to the callback.
loop
boolean flag (true or false). if this option is set to false, when latest JSON image is injected (regarding to avoidDuplicates option) the plugin stops all sliding effects over the thumbnails. Otherwise JSON is reloaded continuously on a loop. Default value: false
rows
the number of rows of the grid. Default value: 2
scrollZoom
boolean flag (true or false). When set to true, on the click event over a thumbnail the plugin will try to scroll the entire page until the thumbnail reaches the top boundary, then the zoom image will be opened. When set to false no scroll is performed. Default value: true
template
the id of the <script> elements in which the markup of template has been defined by the user.
Up

License & Download

Mosaiqy is an opensource project released under the Creative Commons Non-Derivative (CC BY-ND 3.0) license. This means you are free to copy, distribute and transmit the work, to make also commercial use of the work under some restrictions (see carefully the link above).

Note: the original source code is meant for development purposes only since it's 45.7Kb and it contains debug statements, thus it's not suitable for production environment. Use it anyway for check the overall quality of the code and/or when you have to debug your application (look at log messages into the Firefox console or Chrome Toolbar or Opera Dragonfly).

Source code of Mosaiqy and all the code of this site are hosted on github.

Up

About the author

the (nice?) author of this nice plugin

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. Other contacts: twitter and linkedin

Up

Thanks to

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 =)