DHTML Jigsaw Puzzle: IE4; Initialization | WebReference

DHTML Jigsaw Puzzle: IE4; Initialization


The DHTML Lab Jigsaw Puzzle, Part I: IE4
Initializing the puzzle

When creating DHTML that relies on scripting object manipulation, it is advisable to perform checks confirming that all has gone well. In our case, before we can expose the puzzle to the user, we must confirm that the two initial images to be used, the puzzle image and the grid, have loaded. In addition, it would be best to wait until the page itself has finished loading before we initialize our puzzle. To this end, we use the onLoad event handler of the BODY tag and the Image object:

    <BODY onLoad="whenLoaded()"> . . . <DIV ID="elPuzzle"> <IMG NAME="imOrig" ID="elImOrig" SRC="hands.jpg" onLoad="whenLoaded()"> <DIV ID="elGrid"> <IMG NAME="imGrid" ID="elImGrid" SRC="grid.gif" onLoad="whenLoaded()"> </DIV> <DIV ID="elControls"> . . . </DIV> </DIV>

All three instances of onLoad call the same function, whenLoaded(), which we will define as part of our initializtion.

The Script

Our script has many functions to assist in modularity. We will discuss them in the order that the application uses them. First, however, we must initialize several global variables that will be used by more than one function:

    <SCRIPT LANGUAGE="JavaScript"> // track the real puzzle top/left (without border): puzzLeft = puzzTop = null // track the real puzzle width/height (without border): puzzWidth = puzzHeight = null; // how wide is the border? bordWidth = 3; // puzzle pieces across and puzzle pieces down. set default: puzzAcross = puzzDown = 5; // can we drag the puzzle around the page? set default: isPuzzDraggable = true; // does the grid appear when we break puzzle? set default: isGrid = false; // track new puzzles: isNewPuzz = null; // track if pieces have been created for the puzzle? isCreated = null; // track how many pieces have been created: piecesCreated = 0; // counter used in creating pieces: pieceCount = 1; // counter used in tracking rows done when creating pieces: topCount = 0; // is the puzzle broken up into pieces? isBroken = false; // how many pieces have been correctly solved? solvedCount = 1; // which piece is next in line? pieceToSolve = null; // how many times should visibility be toggled to create // flashing effect when piece placed correctly? flashTotal = 5; // track how many times the flashing has occured: flashCount = 0; // how many objects have the onLoad handler assigned to them? loadTotal = 3; // track how many of these objects have loaded: loadCount = 0; // general purpose var for temporary storage // of elements during manipulation: tempEl = null; // assign "space" to a var to avoid possible typos: sp = " ";

Our first function is, of course, the one called by the onLoad handlers: whenLoaded(). In its bare form, it increments the load counter every time it is called. If the total has not yet been reached, it returns:

    function whenLoaded() { loadCount++; if (loadCount

When the load count is reached, and we know that our elements have been created and our primary images loaded, the function executes the remainder of its statements:

    function whenLoaded() { loadCount++; if (loadCount if (isPuzzDraggable) { elPuzzle.draggable = true; elPuzzle.style.cursor = "move"; } else { elPuzzle.draggable = false; dragBut.value = "Drag OFF"; } elPuzzle.clipLeft = elPuzzle.clipTop = 0; initPuzz(); }

The function checks the "draggability" of the puzzle, through the isPuzzDraggable variable. If true, the cursor shape for the puzzle is changed to move, helping the user identify it as draggable. If false, the value of the control button that toggles the puzzle draggability is changed, again to help the user. In both cases, a new property is created for elPuzzle: draggable. This property will be assigned to all elements that can be dragged, that is, the puzzle and the individual pieces. By checking the value of this property, we can determine at any time whether a piece should be dragged or not.

Next, we create two more properties for elPuzzle, clipLeft and clipTop. These will be created for all draggable elements and store the values of the left and top clip of the element. Since our puzzle has not been clipped, we assign a zero value to both properties.

With these overhead tasks completed, we call initPuzz(). This function is called every time we have a new puzzle image:

    function initPuzz() { if (isBroken) {allDone(false)}; puzzWidth = document.images["imOrig"].width; puzzHeight = document.images["imOrig"].height; elPuzzle.style.width = elControls.style.width = puzzWidth; elPuzzle.style.visibility = "visible"; isNewPuzz = true; isCreated = false; pieceToSolve = 1; }

If this function is called when the puzzle has already been broken up, through the image loading SELECT box (see previous page), the allDone() function is called to perform a general cleanup. Since this our first go-through, we'll ignore the first line. The true width and height of the puzzle are assigned to puzzWidth and puzzHeight by retrieving the width and height of the puzzle image. Both elPuzzle and its child element elControls have their width set dynamically to the puzzle width. Now that the correct widths have been assigned, we can show the user the puzzle. We make it visible and assign values to three of our tracking variables. Our displayed puzzle has now taken its correct form:

Screenshot of initialized Puzzle

Now our users are ready to play.

Produced by Peter Belesis and

All Rights Reserved. Legal Notices.
Created: 11/05/97
Revised: 11/13/97

URL: http://www.webreference.com/dhtml/column8/puzzInit.html