Book Image

jQuery HOTSHOT

By : Dan Wellman
Book Image

jQuery HOTSHOT

By: Dan Wellman

Overview of this book

jQuery is used by millions of people to write JavaScript more easily and more quickly. It has become the standard tool for web developers and designers to add dynamic, interactive elements to their sites, smoothing out browser inconsistencies and reducing costly development time.jQuery Hotshot walks you step by step through 10 projects designed to familiarise you with the jQuery library and related technologies. Each project focuses on a particular subject or section of the API, but also looks at something related, like jQuery's official templates, or an HTML5 feature like localStorage. Build your knowledge of jQuery and related technologies.Learn a large swathe of the API, up to and including jQuery 1.9, by completing the ten individual projects covered in the book. Some of the projects that we'll work through over the course of this book include a drag-and-drop puzzle game, a browser extension, a multi-file drag-and-drop uploader, an infinite scroller, a sortable table, and a heat map. Learn which jQuery methods and techniques to use in which situations with jQuery Hotshots.
Table of Contents (18 chapters)
jQuery HOTSHOT
Credits
Foreword
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Splitting an image into pieces


Our next task is to divide the image into a specified number of squares to represent the individual pieces of the puzzle. To do this we'll create a series of smaller elements which each show a different part of the image and which can be manipulated individually.

Prepare for Lift Off

The single step required to complete this task is to create a specified number of puzzle pieces and give each a unique background-position and position in order to recreate the image.

Engage Thrusters

We now want to generate the different pieces that make up the puzzle. We can do this with the following code, which should be added directly after the variables we just defined in sliding-puzzle.js:

for (var x = 0, y = aspectH; x < y; x++) {
    for (var a = 0, b = aspectW; a < b; a++) {
        var top = pieceH * x,
            left = pieceW * a;

        piece.clone()
             .attr("id", idCounter++)
             .css({
                 width: pieceW,
                 height: pieceH,
                 position: "absolute",
                 top: top,
                 left: left,
                 backgroundImage: ["url(", path, ")"].join(""),
                 backgroundPosition: [
                     "-", pieceW * a, "px ", 
                     "-", pieceH * x, "px"
                 ].join("")
        }).appendTo(imgContainer);

        positions.push({ top: top, left: left });
    }
}

Objective Complete - Mini Debriefing

We used a nested set of for loops to create the new puzzle pieces in a grid pattern. The first loop will run for as many rows as required; with a 3:4 aspect-ratio image such as that used in this example, we will need four rows of squares. The inner loop will for run for as many columns as required, which in this case is three.

Within the inner loop we first create two new variables top and left. We need to use these values in a couple of places so it makes sense to create them once and reuse them each time they're required.

The top position is equal to the height of the piece multiplied by the current value of the outer loop's counter variable (x), while the left position is equal to the width of the piece multiplied by the current value of the inner loop's counter variable (a). These variables are used to make the puzzle pieces line up in a grid.

We then copy our stored <div> element using jQuery's clone() method and use the attr() method to set a unique id attribute using the idCounter variable that we initialized in the first part of the project. Notice that we increment the variable at the same time as setting it directly within the attr() method.

We could increment the variable either inside the method as we have done here, or outside of the method; there's no real difference in performance or anything else. I just feel that it's more succinct to update it in situ.

Next we use the css() method to set a style attribute on the new element. We set the width and height of the puzzle piece and position it using our top and left variables, as well as set its backgroundImage and backgroundPosition style properties.

Note

Any style properties that are usually defined using hyphenated words, such as background-image, should be camel-cased when used with jQuery's css() method in conjunction with an object.

The backgroundImage property can be set using our path variable and the rest of the string components of the style, but the backgroundPosition property will need to be calculated individually for each puzzle piece.

The horizontal component of the backgroundPosition style property is equal to the width of the piece multiplied by the value of the inner loop's counter variable (a), while the vertical component is equal to the height of the piece multiplied by the value of the outer loop's counter variable (x).

Once the new element has been created we can add its position to our positions array using JavaScript's push() method, passing in an object containing the top and left positional properties of the element for later use.

Classified Intel

Instead of using standard string concatenation to construct the backgroundImage and backgroundPosition strings, we put the values into an array literal and then joined the array using JavaScript's join() method. By specifying an empty string as the value to use to join the string, we ensure that no additional characters are added to the string.

Joining an array of substrings to form a single string is much faster than building a string using the + operator on substrings, and as we're working repetitively inside a loop, we should optimize the code within the loop as much as possible.