Articles Archive
Articles Search
Director Wiki
 

Panning a large graphic

July 27, 1998
by Pat McClellan

Dear Multimedia Handyman,

Is there a way I can have a panorama which is larger in width than the stage, pan left or right, up or down depending on the direction and velocity of the mouse (similar to QTVR)?

savva / at / savva.com.au

Dear Savva,

Seems like it should be easy, but it's a bit complicated. I guess that's why most people simply opt for using QTVR or one of the other VR options. But, I like a challenge (when I have time to deal with it) so here goes!

The behavior we write should have the following attributes:

An additional feature might be to add hotspots to the graphic. However, that's considerably more complicated so I'll leave that for a future article.

Position can either be altered by setting locH and locV properties, or by altering the rect. Scaling can be altered by setting the height and width properties, or by altering the rect. Since both can be simultaneously set by altering the rect, I opted to use this approach. Using the rect also makes it easy to check the limits of the graphic vis a vis the stage.

One way to approach updating the image properties would be to do it in a repeat loop while the mouse is stillDown. Due to the often discussed problems with using repeat loops (other events are locked out), I decided to use an alternative approach: I use a flag to indicate when the mouse is down or up, and then update on each exitFrame.

In our beginSprite handler, we'll need to set some basic properties: our sprite number, the "speed", the mouseFlag I mentioned, an updateFlag which tells us if the new position for the rect is inside the limits of the stage, and a scale factor. These properties should become more obvious as we proceed into the rest of the code. property pSpeed, mySprite, pStartMouse, pMouseFlag, pUpdateFlag, pDeltaRect, pScaleFactor


on beginSprite me
  set pSpeed = 20
  set mySprite = the spriteNum of me
  set pMouseFlag = 0
  set pUpdateFlag = FALSE
  set pDeltaRect = rect(0,0,0,0)
  set pScaleFactor = 1.00
end

When the mouse is clicked (down), all that happens is that our mouseFlag is set to 1 and the initial position of the mouse is set into our pStartMouse property. On mouseUp, the mouseFlag is turned off.

on mouseDown me
  set pStartMouse = point(the mouseH, the mouseV)
  set pMouseFlag = 1
end
on mouseUp me
  set pMouseFlag = 0
end

As the movie exits each frame, we'll want to first check to assure that the mouse is still over the graphic (stage). If so, then we'll proceed with calculating the position and the scale factor. I've separated these operations into distinct handlers below. Another handler "checkLimits", takes the newly calculated rect and tests to assure that it is within the limits of our stage. If so, the updateFlag is set to TRUE. Back in our exitFrame handler, if the updateFlag is TRUE, then the sprite's current rect is altered by deltaRect (the change calculated in the setPosition handler), and the resulting rect is scaled by the pScaleFactor set in the setScale handler.

on exitFrame me
  if rollOver(mySprite) then
    setScale me
    setPosition me
    checkLimits me
    if pUpdateFlag then
      set currentRect = the rect of ¬
            sprite mySprite
      set newRect = (currentRect + ¬
            pDeltaRect) * pScaleFactor
      set the rect of sprite mySprite = newRect
    else 
      set pStartMouse = point(the mouseH,¬
            the mouseV)
    end if
  else
    set pMouseFlag = 0
  end if
end 
on setScale me
  if the controlDown then
    set pScaleFactor = 1.01
  else if the commandDown then
    set pScaleFactor = 0.99
  else
    set pScaleFactor = 1.00
  end if
end
on setPosition me
  if pMouseFlag = 1 then
    set currentMouse = point(the mouseH, ¬
          the mouseV)
    set deltaMouse = pStartMouse - currentMouse
    set deltaH = getAt (deltaMouse,1)/pSpeed
    set deltaV = getAt (deltaMouse,2)/pSpeed
    set pDeltaRect = rect(deltaH,deltaV,¬
          deltaH, deltaV)
  else
    set pDeltaRect = rect(0,0,0,0)
  end if
end
on checkLimits me
  set currentRect = the rect of sprite mySprite
  set testRect = (currentRect + pDeltaRect) ¬
    * pScaleFactor
  if (the right of testRect > the stageRight) ¬
    AND (the left of testRect < the stageLeft) ¬
        AND (the top of testRect < the stageTop)¬
        AND (the bottom of testRect > the ¬
        stageBottom) then
    set pUpdateFlag = TRUE
  else
    set pUpdateFlag = FALSE
  end if
end

I hope this behavior will get you started. There are many modifications and additions which could enhance the functionality of the behavior. I might suggest changing cursors based on the direction of the mouse motion from the startMouse loc. Good luck with your program.

Patrick McClellan is Director Online's co-founder. Pat is Vice President, Managing Director for Jack Morton Worldwide, a global experiential marketing company. He is responsible for the San Francisco office, which helps major technology clients to develop marketing communications programs to reach enterprise and consumer audiences.

Copyright 1997-2024, Director Online. Article content copyright by respective authors.