Приглашаем посетить
Хлебников (hlebnikov.lit-info.ru)

9.4 Practical techniques for moving objects

Table of Contents

Previous Next

9.4 Practical techniques for moving objects

9.4.1 Moving the Pacman

The ability to control the movement of an object is vital for many entertainment industries on the Web. The techniques can be quite complicated. In order to focus on a basic level, only left, right, up, and down straight movements are considered. In terms of the keyboard, the following keys are used to trigger the actions:

"a" key Move left

"w" key Move up

"d" key Move right

"s" key Move down


These keys are located on the left hand side of your keyboard and can be easily controlled by your left hand. Also, these keys exist on all kinds of keyboards including those on laptop computers. The object you are going to create is simple the "Pacman."This object has four different faces and some simple animations. The XHTML page uses these keys to drive them. In order to do that, you need to set up some event listeners to listen to the keystroke. There will be a message box to display the movement and object selections. The animated gif files in Fig. 9.15 are used to create the Pacman.

Figure 9.15. Images for the Pacman

graphics/09fig15.gif


The picRight.gif (picture right) is an animated gif file representing a sequence of actions moving to the right. Others are the sequences representing the movement in the corresponding directions. For example, when you press the "w" key, the image will change to picUp.gif and move upward. This example has two parts. By combining animated gif pictures with motion, some realistic motions can be achieved. The XHTML interface part is listed as follows:



Example: ex09-08.htm - Controlling Moving Object With Keyboard

 1: <?xml version="1.0" encoding="iso-88591"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 3:     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head><title> Moving Object with Keyboard - ex0908.htm </title></head>
 6: <style>
 7:   .butSt{background-color:#aaffaa;font-family:arial;font-weight:bold;
 8:      font-size:14pt;color:#880000;width:250px;height:40px}</style>
 9: <script src="ex0908.js"></script>
10: <body style="background:#dddddd;font-family:arial;font-size:20pt;
11:    color:#000088;font-weight:bold">
12:
13: <div align="center" >Control Moving Object With Keyboard</div>
14: <img src="picRight.gif" id="obj01" name="obj01"
15:    style="font-weight:bold;position:absolute;
16:      top:80px;left:250px;width:100px;height:100px" />
17:
18: <table style="position:absolute;top:100px;left:460px;text-align:left">
19:   <tr><td class="butSt" style="text-align:center">Instructions</td></tr>
20:   <tr><td class="butSt">&nbsp;Press a to move left</td></tr>
21:   <tr><td class="butSt">&nbsp;Press d to move right</td></tr>
22:   <tr><td class="butSt">&nbsp;Press w to move up</td></tr>
23:   <tr><td class="butSt">&nbsp;Press s to move down</td></tr>
24: </table>
25:
26: <span style="font-family:arial;font-size:16pt;font-weight:bold;
27:    position:absolute;top:400px;left:100px;width:150px;height:40px">
28:    Message:</span>
29: <span id="outMsg" name="outMsg" style="font-family:arial;font-size:16pt;
30:    font-weight:bold;background:#aaaaaa;position:absolute;top:400px;
31:    left:200px;width:350px;height:70px;color:#0000ff"></span>
32: </body>
33: </html>

Although we have four images for the Pacman representing four movement directions, only one is displayed at any one time. After the picture, you have a table (lines 1824) to display the movement instructions. Finally, a message area is used to display the current action of the page. Some screen shots of this page are shown in Figs 9.16 and 9.17.

Figure 9.16. ex09-16.htm

graphics/09fig16.jpg


Figure 9.17. Movement with keyboard

graphics/09fig17.jpg


Note that no specific or standard event handlers are used in this page. This example demonstrates that all handlers can be set up by using script. All event listeners and functions are defined inside the external script file called ex09-08.js. The first part of this file is given below.



Example: ex09-08.js - The ECMAScript For ex09-08.htm (Part One)

 1: var IE=document.all?true:false
 2:
 3: if (!IE)
 4: {  //Set up the Event Listener For NS (Netscape is assumed)
 5:    document.addEventListener("mousedown",mouseClk,false)
 6:    document.addEventListener("keypress",onKey,false)
 7: }else {
 8:    document.attachEvent("onmousedown",mouseClk)
 9:    document.attachEvent("onkeypress",onKey)
10: }
11:
12: function mouseClk(e)
13: {
14:   butS =""
15:   if (IE) {
16:      lxPos1 = event.clientX
17:      lyPos1 = event.clientY
18:      butV = event.button
19:      if (butV ==1) butS="Left "
20:      if (butV ==2) butS="Right "
21:   } else {
22:      lxPos1 = e.pageX
23:      lyPos1 = e.pageY
24:      butV = e.which
25:      if (butV ==1) butS="Left "
26:      if (butV ==3) butS="Right "
27:   }
28:   document.getElementById("outMsg").innerHTML= "You Have Click "+
29:     butS+" Mouse <br /> At Top Left Co-ord. ("+lyPos1+","+lxPos1+")"
30: }
31:

First, a detection statement is used to test the type of browser. If the NS browser is detected, we set up the event listeners with the addEventListener() function. Otherwise, the IE event listener function attachEvent()is employed. In either case, we want to listen to both the onmousedown and onkeypress events.

If a mouse-down event occurs, the mouseClk() (lines 1230) function is called. This function is used to capture the mouse position when the corresponding mouse button is pressed. The information is displayed to the message box with id="outMsg". Listening to the mouse down is not the main function of this page. It is here as an example to show how mouse positions and buttons can also be trapped and displayed.

The coding for the object movement is listed in the second part of the script file ex09-08.js.



Listing: Continuation Of The ECMAScript ex09-08.js (Part Two)

32: dirSt=""
33: selectObj = "obj01"
34: ixDelta = 10
35: iyDelta = 10
36: upBd = 20
37: lowBd = 300
38: leftBd = 20
39: rightBd = 330
40:
41: function onKey(e)
42: {
43:   if (IE) {
44:      chV = String.fromCharCode(event.keyCode)
45:   } else {
46:      chV = String.fromCharCode(e.which)
47:   }
48:    if (chV =="a") moveHor(1)
49:    if (chV =="d") moveHor(-1)
50:    if (chV =="w") moveVer(1)
51:    if (chV =="s") moveVer(-1)
52:
53:    document.getElementById("outMsg").innerHTML=

54:         "You Are Moving "+selectObj+ dirSt
55: }
56:

A number of global variables are defined in lines 3239 and their explanations are as follows:

  • dirSt Stores the movement directions "Left," "Right," "Up," and "Down."

  • selectObj Stores the object identity that we are going to move.

  • ixDelta Specifies how far an object should move horizontally.

  • iyDelta Specifies how far an object should move vertically.

  • upBd The upper boundary for the object.

  • lowBd The lower boundary for the object.

  • leftBd The left boundary for the object.

  • rightBd The right boundary for the object.

If a key is pressed, the onKey() function is called. This function uses a variable chV (i.e., character variable) to store the key. The property event.keyCode is an IE property and e.which is a property of NS. They are used to store the ASCII value of the key pressed. The function String.fromCharCode()converts the ASCII value to the character key. For example, if the pressed key is "a," the moveHor(1) function is called and moves the object in the left direction. A function call to moveHor(-1) will move the object to the right. Similarly, the "w" and "s" keys will move the object up and down respectively using the function moveVer().

The definition of the moveHor() and moveVer() functions are specified as follows:



Listing: Continuation Of The ECMAScript ex09-08.js (Part Three)

57: function moveHor(dirV)
58: {
59:   if (dirV ==1)
61:   {
62:     dirSt="Left"
63:     document.getElementById("obj01").src = "picLeft.gif"
64:   } else {
65:     dirSt="Right"
66:     document.getElementById("obj01").src = "picRight.gif"
67:   }
68:   xPos = parseInt(document.getElementById(selectObj).style.left)
69:   if (((xPos > leftBd )&&(dirV ==1 ))||((xPos < rightBd )&&(dirV ==-1 )))
70:  document.getElementById(selectObj).style.left=xPos -(ixDelta* dirV) +"px"
71: }
72:
73: function moveVer(dirV)
74: {
75:   if (dirV ==1)
76:   {
77:     dirSt="Up"
78:     document.getElementById("obj01").src = "picUp.gif"
79:   } else {
80:     dirSt="Down"
81:     document.getElementById("obj01").src = "picDown.gif"
82:   }
83:   yPos = parseInt(document.getElementById(selectObj).style.top)
84:   if (((yPos > upBd )&&(dirV == 1))||((yPos < lowBd )&&(dirV == -1 )))
85:   document.getElementById(selectObj).style.top =yPos -(iyDelta* dirV) +"px"
86: }

Consider the horizontal move function moveHor(). If the variable dirV equals 1, the direction string dirSt is set to "Left" and changes the moving object image to picLeft.gif so that the Pacman's mouth faces in the left direction. If the value of dirV is 1, the Pacman's picture is set to picRight.gif so that the mouth of the Pacman faces right. Next, we get the x-position of the Pacman from the statement as indicated in line 68. If the position is bigger than the left boundary and the moving direction is left, you can move the object in the left direction with a step value ixDelta. You can only move the object to the left when some spaces are available. Similarly, you can only move the object to the right if the position of the object is less than the right boundary (rightBd).

The function moveVer() (i.e., move vertically) is similar to moveHor() and will move the object up and down depending on the direction variable dirV.

9.4.2 A shooting game

Another popular example of moving objects is a shooting game page. To program a shooting game even at a basic level, you will need to combine a number of techniques that you've learned. Almost any game involves:

  • a moving object;

  • a controllable moving object (the gun);

  • shooting action (firing a bullet);

  • hitting the target;

  • counting the number of hits;

  • counting the number of misses;

  • some buttons to control the progress;

  • game-over criteria; and

  • winning conditions.

For simplicity, we are going to use the Pacman's ghost as the moving object. The rule of the game is simple. A moving ball is the "bullet" and ready to fire. No gun is really needed. The bullet can move left and right by using the keyboard and can fire upward at will to hit the ghost. We also have a message area to show the number of hits, missed shots, and the total score. The score is the difference between the hits and the misses. If the total score is a negative number (i.e., more misses than hits), the game is over. You win the game if you have a total score of 5. You also have some buttons to control the progress of the game.

Surprisingly, the whole game can be implemented with a reasonable number of lines of coding. The page contains an XHTML interface page and an external script file. The main purpose of the interface is to design the shooting field scoreboard, and to display the instructions on how to play.



Example: ex09-09.htm - A Shooting Game

 1: <?xml version="1.0" encoding="iso-88591"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 3:     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head><title> A Shooting Game - ex0909.htm </title></head>
 6: <style>
 7:   .tx01St={font-family:arial;font-size:18pt;font-weight:bold}
 8:   .butSt{background-color:#dddddd;font-family:arial;font-weight:bold;
 9:      font-size:18pt;color:#880000;width:60px;height:40px}
10:   .butSt1{background-color:#aaffaa;font-family:arial;font-weight:bold;
11:      font-size:18pt;color:#880000;width:110px;height:40px}
12:
13: </style>
14: <body style="background:#dddddd;font-family:arial;font-size:20pt;
15:    color:#000088;font-weight:bold">
16: <div style="position:absolute;top:15px;left:250px">A Shooting Game</div>
17: <img src="line1.gif" style="position:absolute;
18:     top:50px;left:150px;width:380px;height:6px" />
19: <img src="line1.gif" style="position:absolute;
20:     top:320px;left:150px;width:380px;height:6px" />
21:
22: <table style="font-family:arial;font-size:16pt;color:#888888;
23:        position:absolute;top:100px;left:210px">
24:   <tr><td>Press "a" To Move Left</td></tr>
25:   <tr><td>Press "d" To Move Right</td></tr>
26:   <tr><td>Press "w" To Fire </td></tr>
27:   <tr><td>Total Score 5 To Win </td></tr>
28:   <tr><td>Negative Total Score - Game Over</td></tr>
29: </table>
30:
31:
32: <img src="ghost_r.gif" id="obj01" name="obj01" alt="pic"
33:  style="position:absolute;top:80px;left:250px;width:70px;height:70px" />
34:
35: <img src="bullet1.gif" id="obj00" name="obj00" alt="pic"
36:  style="position:absolute;top:340px;left:350px;width:30px;height:30px" />
37:
38: <table style="position:absolute;top:80px;left:25px">
39:  <tr><td class="tx01St">Scores</td></tr>
40:  <tr><td class="butSt">Hit : </td><td class="butSt">
41:      <span id="obj01Msg" name="obj01Msg">0</span></td></tr>
42:  <tr><td class="butSt">Miss : </td><td class="butSt">
43:      <span id="obj02Msg" name="obj02Msg">0</span></td></tr>
44:  <tr><td class="butSt">Total : </td><td class="butSt">
45:      <span id="obj03Msg" name="obj03Msg">0</span></td></tr>
46:
47:  <tr><td colspan="2"><input type="button" id= "startBut" name="startBut"
48:       class="butSt1" value="Start" onclick="restart()"/></td></tr>
49:  <tr><td colspan="2"><input type="button" class="butSt1" id= "stopBut"
50:       name="stopBut" value="Stop" onclick="stop()"/></td></tr>
51: </table>
52: <script src="ex0909.js"></script>
53: </body>
54: </html>

After the page title in line 16, two straight red lines are used to draw the shooting area. Inside the shooting area, an XHTML table (lines 2229) is used to display the instructions on how to play the game. They are:

  • Press "a" To Move Left

  • Press "d" To Move Right

  • Press "w" To Fire

  • Total Score 5 To Win

  • Negative Total Score Game Over

The moving object defined in lines 3233 is a picture of a ghost (Pacman's ghost), ghost_r.gif. The ghost is designed to move right and left continuously with a different color. The gun is actually a bullet picture specified in lines 3536. The movement of the bullet is controlled by the keyboard and "w" key will fire the bullet upward to hit the target. A table is also used to draw a scoreboard, which stores the information about the number of hits, misses, and total score. At the end of this XHTML table, two buttons are defined. The Stop button (lines 4950) is used to suspend the game at any time. Once the game is stopped or suspended, another button (the Start button) will appear to allow the user to continue the game. Some screen shots of this page are given in Figs 9.189.21.

Figure 9.18. ex09-09.htm

graphics/09fig18.jpg


Figure 9.21. Game over

graphics/09fig21.jpg


Figure 9.19. Hitting the target

graphics/09fig19.jpg


Figure 9.20. You win

graphics/09fig20.jpg


The included program file ex09-09.js is the heart of this page, providing all the functionalities for the object movements, bullet controls, firing, impact, and score counting. The first part of this file is listed as follows:



Example: ex09-09.js - ExampleThe ECMAScript For ex09-09.htm (Part One)

 1: var IE=document.all?true:false
 2: if (!IE) {
 3:    document.addEventListener("keypress",onKey,false)
 4: }else {
 5:    document.attachEvent("onkeypress",onKey)
 6: }
 7:
 8: function onKey(e)
 9: {
10:   if (IE) {
11:      chV = String.fromCharCode(event.keyCode)
12:   } else {
13:      chV = String.fromCharCode(e.which)
14:   }
15:   if (chV =="a") moveHor(1)
16:   if (chV =="d") moveHor(-1)
17:   if (chV == "w") fireBall()
18: }
19:
20: var selectObj = "obj00"
21: var working = 1
22: document.getElementById("startBut").style.visibility="hidden"
23:
24: function resetPos()
25: {
26:   document.getElementById(selectObj).style.top = 340 +"px"
27:   document.getElementById(selectObj).style.left = 350 +"px"
28:   document.getElementById("startBut").style.visibility="visible"
29: }
30:
31: function restart()
32: {
33:  working =1
34:  resetPos()
35:  document.getElementById("startBut").style.visibility="hidden"
36: }
37:
38: function stop()
39: {
40:  working =0
41:  document.getElementById("startBut").style.visibility="visible"
42: }
43:

The first line of this program file is to detect the browser and then set up the event listener depending on the browser type (IE or NS). The listener will listen to any keyboard event and call the onKey() function as defined in lines 818. Inside this function, the String.fromCharCode() function is used to convert the keycode to a character. If the character equals "a," the function moveHor(1) is called to move the bullet to the left. The argument 1 signals the function to move the bullet to the left. If the keystroke is a "d" character, the moveHor(-1) function moves the bullet to the right. A "w" key will call the fireBall() function to fire the bullet.

After the event listener, some global variables are used to set up events and the environment. The variable selectObj="obj00" is to set the bullet object so that it corresponds to the keyboard input. We set the variable working=1 (line 21) to start the program. Whenever the program or the motion starts, the Start button is hidden to avoid some misuse of the button. The resetPos() function is to reset the position of the bullet. The restart() function (lines 3136) is called whenever the Start button is clicked by a mouse. The stop function is used to suspend the program at any time.

The second part of the program controls the impact and the score counting.



Listing: Continuation Of The ECMAScript ex09-09.js (Part Two)

44: hitScore = 0
45: missScore =0
46: totalScore = 0
47:
48: widthX0 = 30
49: heightY0 = 30
50: widthX1 = 50
51: heightY1 = 50
52:
53: function hitT()
54: {
55:   xPos1 = parseInt(document.getElementById("obj01").style.left)
56:   yPos1 = parseInt(document.getElementById("obj01").style.top)
57:
58:   xPos = parseInt(document.getElementById(selectObj).style.left)
59:   yPos = parseInt(document.getElementById(selectObj).style.top)
60:
61:   if ( ((xPos1 < xPos ) && (xPos < (xPos1+widthX1)) &&
62:    ((yPos1 + heightY1) > yPos) && (yPos > yPos1)) ||
63:    ((xPos1 < (xPos+ widthX0) ) && (xPos < (xPos1+widthX1)) &&
64:    ((yPos1 + heightY1) > yPos) && (yPos > yPos1)) ||
65:    ((xPos1 < xPos ) && (xPos < (xPos1+widthX1)) &&
66:    ((yPos1 + heightY1) > (yPos+heightY0)) && ((yPos+heightY0) > yPos1)) ||
67:    ((xPos1 < (xPos+ widthX0) ) && (xPos < (xPos1+widthX1)) &&
68:    ((yPos1 + heightY1) > (yPos+heightY0)) && ((yPos+heightY0) > yPos1)) )
69:   {
70:      hitScore++
71:      document.getElementById("obj01Msg").innerHTML = hitScore
72:      totalScore = hitScore - missScore
73:      document.getElementById("obj03Msg").innerHTML = totalScore
74:      if (totalScore > 4)
75:      {
76:           document.getElementById("obj03Msg").innerHTML = "You Win"
77:           document.getElementById("startBut").style.visibility="hidden"
78:           document.getElementById("stopBut").style.visibility="hidden"
79:           stop()
80:       }
81:       return true
82:   } else {
83:       return false
84:   }
85: }
86:

Again, variables are introduced when needed. First, we set all the score variables to zero. To control the hit and impact, some collision criteria are needed. The dimensions of the bullet are widthX0=30 and heightY0=30 (pixels) and it has a rectangular shape. The dimensions of the target are widthX1=50 and heightY1=50 (pixels). The collision moment of two objects occurs when:

  • the top left corner of the bullet is inside the target dimension;

  • the top right corner of the bullet is inside the target dimension;

  • the bottom left corner of the bullet is inside the target dimension; and

  • the bottom right corner of the bullet is inside the target dimension.

This is a long conditional if statement and is illustrated in lines 6168. Once there is an impact, the hitScore (number of hits) and the totalScore (total score) are updated. If the totalScore is 5, the player wins and the game will stop.

Another important part of the program is to control the firing of the bullet. The bullet will move left, right, and upward to hit the target.



Listing: Continuation Of The ECMAScript ex09-09.js (Part Three)

87:
88: ixDelta = 10
89: iyDelta = 20
90: leftBd = 200
91: rightBd = 500
92:
93: function moveHor(dirV)
94: {
95:  if (working ==1) {
96:    xPos = parseInt(document.getElementById(selectObj).style.left)
97:    if (((xPos > leftBd ) && (dirV ==1 )) ||
98:       ((xPos < rightBd ) && (dirV ==-1 )))
99:     document.getElementById(selectObj).style.left=
100:       xPos - (ixDelta* dirV)+"px"
101:  }
102: }
103:
104: function fireBall()
105: {
106:   if (working==1)
107: {
108:   xPos = parseInt(document.getElementById(selectObj).style.left)
109:   yPos = parseInt(document.getElementById(selectObj).style.top)
110:
111:   if (yPos < 20)
112:   {
113:     working = 0
114:     resetPos()
115:     missScore++
116:     document.getElementById("obj02Msg").innerHTML = missScore
117:     totalScore = hitScore - missScore
118:     if (totalScore > -1)
119:       document.getElementById("obj03Msg").innerHTML = totalScore
120:     else {
121:       document.getElementById("obj03Msg").innerHTML = "Game Over"
122:       document.getElementById("startBut").style.visibility="hidden"
123:       document.getElementById("stopBut").style.visibility="hidden"
124:     }
125:   } else {
126:       yPos = yPos - iyDelta
127:       document.getElementById(selectObj).style.top = yPos +"px"
128:       if (hitT())stop()
129:   }
130:   setTimeout("fireBall()",20)
131:  }
132: }
133:

The movement of the bullet cannot be less than 200 pixels from the left boundary or more than 500 pixels from the left. Also, the bullet can only move 10 pixels horizontally each time. These are the restrictions on the bullet and applied inside the function moveHor(). This function has an argument dirV to control the left or the right movement of the bullet. When dirV=1, the bullet moves to the right and when dirV=-1, it moves in the left direction.

When the "w" key is pressed, the function fireBall() is called. This function will fire the bullet and try to hit the target. If the variable working is not 1, nothing will happen. This arrangement is to make sure that the game can be stopped completely at any time.

The position of the bullet is captured by the xPos and yPos variables (lines 108109). If yPos is less than 20 pixels, the bullet has reached the top and hence misses the target. In this case, the working variable is set to 0, which resets the bullet position and increments the missScore (the number of misses). If the missScore is negative, both the Start and Stop buttons will be hidden and the game is over. Otherwise, the missScore and totalScore are updated. If the bullet has not yet reached the top, the bullet will continue to move upward by the statements given in lines 126127. For each step, a call to the function hitT() is needed to test whether the target is hit. The setTimeout() function in line 130 makes sure that this function will be called every 20 millitseconds and continues the movement until the bullet reaches the top or hits the target.

The final part of the program is much easier. It contains only one function, moveLeft(), used to move the target object to the left and right continuously.



Listing: Continuation Of The ECMAScript ex09-09.js (Part Four)

134:
135: llxPos = 0
136: iixDelta = 10
137: dirVar = 1
138: function MoveLeft()
139: {
140:  if (working ==1)
141:  {
142:   llxPos = parseInt(document.getElementById("obj01").style.left)
143:   if (llxPos < leftBd)
144:   {
145:     dirVar = 1
146:     document.getElementById("obj01").src = "ghost_r.gif"
147:   }
148:
149:   if (llxPos > rightBd )
150:   {
151:     dirVar = -1
152:     document.getElementById("obj01").src = "ghost_l.gif"
153:   }
154:     document.getElementById("obj01").style.left =
155:           (llxPos + iixDelta * dirVar) + "px"
156:  }
157: }
158: setInterval("MoveLeft()",50)
159: restart()

Inside the moveLeft() function, the current left position of the target is obtained by the statement in line 142. If the position is less than the left boundary (leftBd), the direction of movement is changed to the right (dirVar=1) and the target picture to ghost_r.gif. If the left position is more than the right boundary (rightBd), on the other hand, the movement changes to the opposite direction and uses the ghost_l.gif picture as the moving target. The direction dirVar and the step variable iixDelta are used to update the position of the target.

Finally, by calling this function continuously as illustrated in line 158, we have a moving target on the page. The restart() function at the end of this program activates the bullet and ready for firing. As a final remark, since there is no code to stop the left and right keys after firing, this means that you can still control the bullet to move left or right in a path to hit the target.

9.4.3 Dragging and dropping objects

Dragging is an essential technique in any window-based operating system. From organizing icons to performing some real applications, holding down the mouse button on an object and dragging it somewhere else is a daily working routine. Have you ever considered how it works? In fact, the basic procedures to implement drag and drop operations are to:

  • select the object using a mouse-down event;

  • move the mouse while holding the mouse down;

  • change the object's position along with the mouse movement; and

  • release the object when the mouse button is up.

One simple implementation of these tasks on the Web is to use onmousedown and onmouseup event handlers on the object. Defining the handlers this way means they will have effect only when the object is activated. This means that the handlers only exist when you touch the object. Therefore there is no need to pick up the object from the higher level. For this application, it may be more convenient to set up handlers at the document level (i.e., using XHTML attributes) to trap any mouse movements.

To construct an example, let's consider three objects. The first object is an information board to display which object you have picked and the position to drop the object. The second object is a logo picture and the final one is a moving object. All three objects can be dragged and dropped anywhere inside the page.

The interface part of the page is listed in ex09-10.htm.



Example: ex09-10.htm - Drag And Drop Objects

 1: <?xml version="1.0" encoding="iso-88591"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 3:     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head><title> Drag and Drop Objects - ex0910.htm </title></head>
 6: <body style="background:#dddddd;font-family:arial;font-size:20pt;
 7:    color:#000088;font-weight:bold">
 8: <div style="text-align:center">Drap And Drop Objects</div>
 9:
10: <table id="obj000" style="font-family:arial;font-size:18pt;color:#880000;
11:    position:absolute;top:100px;left:20px;width:300px;height:60px"
12:    onmousedown="mouseDownEvent(0)" onmouseup="mouseUpEvent()">
13:  <tr><td>Picked Object :</td>
14:      <td style="color:#000088"><span id="objPick"></span></td></tr>
15:  <tr><td>Mouse Position:</td>
16:      <td style="color:#000088"><span id="mPos"></span></td></tr>
17: </table>
18:
19: <img id="obj001" src="logo_web.jpg" alt="pic"
20:    style="position:absolute;top:60px;left:360px;width:120px;height:80px"
21:    onmousedown="mouseDownEvent(1)" onmouseup="mouseUpEvent()" />
22:
23: <img id="obj002" src="picRight_y.gif" alt="pic"
24:    style="position:absolute;top:250px;left:240px;width:60px;height:60px"
25:    onmousedown="mouseDownEvent(2)" onmouseup="mouseUpEvent()" />
26:
27: </body>
28: <script src="ex09-10.js"></script>
29: </html>

This page contains three objects with identities obj000, obj001, and obj002. The obj000, defined in lines 1017, is an XHTML table to display the "Picked Object" and current "Mouse Position." The second and third objects are pictures defined with the image elements as given in lines 19 and 23. All objects are designed with drag and drop features.

The three objects have onmousedown and onmouseup standard event handlers attached to them. The first one is in line 12:



onmousedown = "mouseDownEvent(0)"

When a user touches this object and holds down the left mouse button, the function mouseDownEvent(0) is called with 0 as argument. The argument sets the selected object as obj000. If the user moves the mouse while holding down the mouse button, another mouse move event will move the selected object along with the mouse. The onmousedown events for the other two objects are similar; the onmouseup event is simply to release the selected object. All these functionalities are implemented in the external program file ex09-10.js. Before listing the program file, some screen shots of the page are shown in Figs 9.22 and 9.23.

Figure 9.22. ex09-10.htm

graphics/09fig22.jpg


Figure 9.23. Drag and drop

graphics/09fig23.jpg


The first part of this program file is listed as follows:



Example: ex09-10.js - The ECMAScript For ex09-10.htm (Part One)

 1: var IE = document.all?true:false
 2:
 3: llxPos = 0
 4: iixDelta = 10
 5: dirVar = 1
 6: working =1
 7: function MoveLeft()
 8: {
 9:  if (working ==1)
10:  {
11:   llxPos = parseInt(document.getElementById("obj002").style.left)
12:   if (llxPos < 200)
13:   {
14:     dirVar = 1
15:     document.getElementById("obj002").src = "picRight_y.gif"
16:   }
17:
18:   if (llxPos >= 450 )
19:   {
20:     dirVar = -1
21:     document.getElementById("obj002").src = "picLeft_g.gif"
22:   }
23:   document.getElementById("obj002").style.left =
24:         (llxPos + iixDelta * dirVar) + "px"
25:  }
26: }
27: setInterval("MoveLeft()",50)
28:
29: var selectObj = null
30: function mouseDownEvent(objId)
31: {
32:   if (objId ==2) working = 0
33:   selectObj="obj00"+objId
34:   document.getElementById("objPick").innerHTML= selectObj
35: }
36:
37: function mouseUpEvent()
38: {
39:   if (selectObj != null)
40:   {
41:    working =1
42:    selectObj = null;
43:   // document.getElementById("objPick").innerHTML= ""
44:   // document.getElementById("mPos").innerHTML= ""
45:    return(false)
46:  }
47: }
48:

After the familiar browser detection statement in line 1, the first function MoveLeft() is defined in lines 726. We have already come across this function several times. In this case, it is used to move the object obj002 to the right and left continuously.

The onmousedown event function mouseDownEvent(objId) is defined in lines 3035. If the input argument objId equals 2, that means you have picked up the moving object obj002. In this case, we need to stop the movement by setting the variable working=0 before dragging and dropping it in another location. The string concatenation statement



SelectObj = "obj00" + objId

is a common way to construct the identity of an object. Once the identity of the selected object is known, the information is displayed to the display board. When the mouse button is released, the mouseUpEvent()is called to release the selected object and reset the information on the display board.

The main function of this example is to control the mouse movement and is listed in the second part of the program file ex09-10.js.



Listing: Continuation Of the ECMAScript ex09-10.js (Part Two)

49: var objW = 0
50: var objH = 0
51: function mouseMoveEvent(e)
52: {
53:   if (selectObj != null)
54:   {
55:     if (IE)
56:     {
57:      lxPos = event.clientX
58:      lyPos = event.clientY
59:     } else {
60:      lxPos = e.pageX
61:      lyPos = e.pageY
62:     }
63:     document.getElementById("mPos").innerHTML= "("+lxPos+","+lyPos+")"
64:     objW = parseInt(document.getElementById(selectObj).style.width)
65:     objH = parseInt(document.getElementById(selectObj).style.height)
66:
67:     document.getElementById(selectObj).style.left = lxPos - objW/2 +"px"
68:     document.getElementById(selectObj).style.top = lyPos - objH/2 +"px"
69:   }
70:   return(false)
71: }
72:
73: document.onmousemove=mouseMoveEvent

The mouseMoveEvent() function (lines 5171) is called if even a tiny movement of the mouse is detected. This function may be called hundreds if not thousands of times even for a simple mouse operation. The implementation and operation of this function should be kept to a minimum to save system resources. Thus this function will do nothing if no object is picked. If the mouse touches an object, the position of the mouse is captured in lines 5663. This information is displayed in the display board as usual at the top left coordinate. In order to catch the center of the selected object, we calculate its width and height as shown in lines 6465. Finally, the center position of the selected object is updated to the new mouse position. This effect is known as "drag and drop."

    Table of Contents

    Previous Next