Contents
Articles
Behaviors
Books
Director News
Director Web Sites
FAQ
Games
Mailing Lists
News Groups
Project Examples
Reviews
Software
Tools
Useful Web Sites
Utilities
Xtras

Don't miss these
PostScript Xtra
Hilite Line
Find Last Label
Open Windows Explorer
cXtraChangeRes
Object Browser
Power Point Viewer
LineHiLiter
Image Xport
TranZtions
 

 

 

Behavior Page turn

Added on 10/9/2000

 

Compatibilities:
behavior D7 D8 Mac PC Shockwave

This item has not yet been rated

Author: JulianSaxe

You may select a second castmember to display the other side of the turned page half way through the animation. The animation may be executed in a series of enterFrame (dependent upon your movie"s framerate) messages or a repeat loop (faster and smoother). This behaviour is a little low on documentation but a few suggestions are mentioned for it"s improvement in the opening comments.

Download PC Source    Download Mac Source
-- Page Turn Behaviour (using sprite quad property)

-- Julian de Saxe
-- catchTheBaddies@mothcity.com
-- Sorry the documentation is so sparse.

-- Planned for next time I visit this script:
-- Add function to turn the page back again.

-- Add functionality to animate on mouseUp;
-- (detecting which corner of the sprite was closest to the mouse event and
-- calculating the lead-in distance based on the distance from the vertical centre of the sprite)
-- ie. The closer to the middle of the page the less the lead-in.

-- Add isOkToAttach handler.

-- This behaviour doesn't work on Flash sprites.
-- But wouldn't it be so cool to do this with an animated flash movie.
-- Dream up a whole children's story book with every page a lushman's Flash movie
-- sitting in a .dxr on a web page with narration and a soundtrack. Click on the corner to turn the page.
-- Write to Macromedia and beg them to support the quad property of a Flash sprite in their next version of Director!

----------------------------------------------------------------------------------------------------
on getBehaviorTooltip
  return "This behavior makes a sprite animate" & RETURN &
    "in a simulated page turn (left or right)."
end getBehaviorTooltip




----------------------------------------------------------------------------------------------------
on getBehaviorDescription
  vDesc = "PAGE TURN"&RETURN&RETURN
  vDesc = vDesc &"A bitmap sprite with this behavior attached will"
  vDesc = vDesc &RETURN& "be animated to simulate a page turning."
  vDesc = vDesc &RETURN& "Drop it on a sprite and indicate the direction"
  vDesc = vDesc &RETURN& "you wish the page to turn (left to right OR"
  vDesc = vDesc &RETURN& "right to left)."
  vDesc = vDesc &RETURN& "Then choose the corner that should begin turning first (TOP or BOTTOM)."
  vDesc = vDesc &RETURN& "This gives the animation the appearance of being turned from"
  vDesc = vDesc &RETURN& "one of the corners."
  vDesc = vDesc &RETURN& "Select the distance that this corner will travel before the other"
  vDesc = vDesc &RETURN& "corner begins to turn."
  vDesc = vDesc &RETURN& "This is expressed as a percentage of the total width of"
  vDesc = vDesc &RETURN& "the sprite."
  vDesc = vDesc &RETURN& "Choose the amplitude of the arc of the curve for the top and bottom"
  vDesc = vDesc &RETURN& "of the page."
  vDesc = vDesc &RETURN& "ie. how high or low the locus of the corner rises or falls below the top or bottom."
  vDesc = vDesc &RETURN& "of the page."
  vDesc = vDesc &RETURN& "The higher the value the further the page appears to rise out of the stage (towards your nose)."
  vDesc = vDesc &RETURN& "Select the speed of the animation."
  vDesc = vDesc &RETURN& "This will vary according to whether you choose to play the animation in a frame"
  vDesc = vDesc &RETURN& "based animation or a repeat loop."
  vDesc = vDesc &RETURN& "If you wish to change castmembers half way through the animation"
  vDesc = vDesc &RETURN& "check the box and select a bitmap castmember from the pop-up menu."
  vDesc = vDesc &RETURN& "NB. This is useful to have the page look as though the other side of the page"
  vDesc = vDesc &RETURN& "is authentic. However, the image of the castmember needs to be reversed in the vertical axis"
  vDesc = vDesc &RETURN& "because the quad property of the sprite at this stage in the animation will reverse the image."
  vDesc = vDesc &RETURN& "back to it's proper appearance."
  vDesc = vDesc &RETURN& "Choose whether you want the animation to be frame based or occur in a repeat loop."
  vDesc = vDesc &RETURN& "Choosing repeat loop makes the animation much faster and smoother and is more consistent"
  vDesc = vDesc &RETURN& "over a range of machines."
  vDesc = vDesc &RETURN& "ps. This behaviour contains no error checking."
  return vDesc
end getBehaviorDescription




----------------------------------------------------------------------------------------------------
property pSprite              -- sprite object reference
property pSpriteRect         -- original rect of sprite

property pCurrentQuad         -- quad point reference
property pOrigQuad              -- original sprite quad values

property pSwitch              --  initially FALSE. Set to TRUE to begin animation
property pFrameOrRpt      -- allows designer to decide to execute animation in repeat loop or frame based
property pMyAnimFactor   -- factor of pi to calculate quad points

property pTurnPage          -- left to right or right to left?
property pLeadCorner      -- leading corner is th corner that starts turning first (top or bottom?)
property pTurnDirection

property pTotalX

property pLeadInTime        -- distance that the first corner travels before the second corner begins to animate.

property pSpeed            -- number of steps
property pTotalDistance          -- the counter ( = 2 * sprite.width)
property pDistance

property pTopAmplitude  --  height (amplitude) of curve (top of page)
property pBottomAmplitude  --  height (amplitude) of curve (bottom of page)

property pOtherPage
property pChangeMember
property pAdvanceWhenFinished



----------------------------------------------------------------------------------------------------
on getPropertyDescriptionList me
  
  if the currentSpriteNum = 0 then exit
  theMember       = sprite(the currentSpriteNum).member
  theMemberNumber = theMember.number
  
  vPDList = [:]
  setaProp vPDList, #pTurnDirection, [#comment: "direction of page turn : ", #format: #string, #range:["LeftToRight","RightToLeft"], #default: "LeftToRight"]
  addProp vPDList, #pLeadCorner, [#comment: "leading corner : ", #format: #string, #range:["Top","Bottom"], #default: "top"]
  addProp vPDList, #pLeadInTime,  [#comment: "lead in time : ", #format: #float, #range:[#min:0,#max:1], #default: 0.25]
  addProp vPDList, #pTopAmplitude, [#comment: "amplitude of top curve : ", #format: #float, #range:[#min:0.0000,#max:1.000], #default: 0.07]
  addProp vPDList, #pBottomAmplitude, [#comment: "amplitude of bottom curve : ", #format: #float, #range:[#min:0,#max:1], #default: 0.22]
  addProp vPDList, #pSpeed, [#comment: "speed of animation : ", #format: #integer, #range:[#min:1,#max:150], #default: 1]
  addProp vPDList, #pChangeMember, [#comment: "change member half way ?  ", #format: #boolean, #default: 0]
  addProp vPDList, #pOtherPage, [#comment: "other side of page (image) : ", #format: #graphic, #default: theMemberNumber+1]
  addProp vPDList, #pFrameOrRpt, [#comment: "how do you want to execute the animation : ", #format: #string, #range:["frame based", "repeat loop"], #default: "frame based"]
  addProp vPDList, #pAdvanceWhenFinished, [#comment: "advance to the next frame when finished : ", #format: #boolean, #default: TRUE]
  return vPDList
end getPropertyDescriptionList




----------------------------------------------------------------------------------------------------
on beginSprite me
  
  mInitialise(me)
end



----------------------------------------------
on enterFrame me
  
  if pSwitch then
    
    if pDistance < pTotalDistance  then
      do pTurnPage
      pSprite.quad = pCurrentQuad   --- draw sprite
      updateStage
      set pDistance = pDistance + pSpeed
      
    else if pDistance >= pTotalDistance then
      set pDistance = pTotalDistance
      do pTurnPage
      pSprite.quad = pCurrentQuad    --- draw sprite
      updateStage
      if pAdvanceWhenFinished then
        go to the frame + 1
      end if
      pSwitch = FALSE
    end if
    
    if pChangeMember then
      if pDistance > pTotalDistance/2 then
        pSprite.member = pOtherPage
        pChangeMember = FALSE
      end if
    end if
  end if
end enterFrame




----------------------------------------------
on endSprite me
  
  puppetSprite pSprite.spriteNum, FALSE
  updateStage
end



----------------------------------------------
on mLeftToRightBottom me
  
  vTopPoint = pOrigQuad[1]
  vBottomPoint = pOrigQuad[4]
  -- move bottom point
  if pDistance <= pTotalX then
    vXb = pDistance
    vYb = pBottomAmplitude*sin((vXb-pTotalX)*pMyAnimFactor)
    vBottomPoint.locH = pSpriteRect.left + abs(vXb)
    vBottomPoint.locV = pSpriteRect.bottom + vYb        -- change operator to alter view.
  else if pDistance > pTotalX then
    vXb = pTotalX
    vYb = pBottomAmplitude*sin((vXb-pTotalX)*pMyAnimFactor)
    vBottomPoint.locH = pSpriteRect.left + abs(vXb)
    vBottomPoint.locV = pSpriteRect.bottom + vYb        -- change operator to alter view.
  end if
  
  -- move top point
  if pDistance >= pLeadInTime AND pDistance <= pTotalDistance then
    set vXt = pDistance - pLeadInTime
    vYt = pTopAmplitude*sin((vXt-pTotalX)*pMyAnimFactor)
    vTopPoint.locH = pSpriteRect.left + abs(vXt)
    vTopPoint.locV = pSpriteRect.top + vYt     -- change operator to alter view.
  end if
  
  pCurrentQuad[1] = vTopPoint
  pCurrentQuad[4] = vBottomPoint
  
end




----------------------------------------------
on mLeftToRightTop me
  
  vTopPoint = pOrigQuad[1]
  vBottomPoint = pOrigQuad[4]
  -- move top point
  if pDistance <= pTotalX then
    set vXt = pDistance
    vYt = pTopAmplitude*sin((vXt-pTotalX)*pMyAnimFactor)
    vTopPoint.locH = pSpriteRect.left + abs(vXt)
    vTopPoint.locV = pSpriteRect.top + vYt    -- change operator to alter view.
  else if pDistance > pTotalX then
    vXt = pTotalX
    vYt = pTopAmplitude*sin((vXt-pTotalX)*pMyAnimFactor)
    vTopPoint.locH = pSpriteRect.left + abs(vXt)
    vTopPoint.locV = pSpriteRect.top + vYt      -- change operator to alter view.
  end if
  
  -- move bottom point
  if pDistance >= pLeadInTime AND pDistance <= pTotalDistance then
    vXb = pDistance - pLeadInTime
    vYb = pBottomAmplitude*sin((vXb-pTotalX)*pMyAnimFactor)
    vBottomPoint.locH = pSpriteRect.left + abs(vXb)
    vBottomPoint.locV = pSpriteRect.bottom + vYb     -- change operator to alter view.
  end if
  
  pCurrentQuad[1] = vTopPoint
  pCurrentQuad[4] = vBottomPoint
  
end




----------------------------------------------
on mRightToLeftTop me
  
  vTopPoint = pOrigQuad[2]
  vBottomPoint = pOrigQuad[3]
  -- move top point
  if pDistance <= pTotalX then
    set vXt = pDistance
    vYt = pTopAmplitude*sin(pMyAnimFactor*(vXt-pTotalX)) --
    vTopPoint.locH = pSpriteRect.right - abs(vXt)
    vTopPoint.locV = pSpriteRect.top + vYt    -- change operator to alter view.
  else if pDistance > pTotalX then
    vXt = pTotalX
    vYt = pTopAmplitude*sin(pMyAnimFactor*(vXt-pTotalX))
    vTopPoint.locH = pSpriteRect.right - abs(vXt)
    vTopPoint.locV = pSpriteRect.top + vYt      -- change operator to alter view.
  end if
  
  -- move bottom point
  if pDistance >= pLeadInTime AND pDistance <= pTotalDistance then
    vXb = pDistance - pLeadInTime
    vYb = pBottomAmplitude*sin(pMyAnimFactor*(vXb-pTotalX))
    vBottomPoint.locH = pSpriteRect.right - abs(vXb)
    vBottomPoint.locV = pSpriteRect.bottom + vYb     -- change operator to alter view.
  end if
  
  pCurrentQuad[2] = vTopPoint
  pCurrentQuad[3] = vBottomPoint
  
end




----------------------------------------------
on mRightToLeftBottom me
  
  vTopPoint = pOrigQuad[2]
  vBottomPoint = pOrigQuad[3]
  -- move bottom point
  if pDistance <= pTotalX then
    vXb = pDistance
    vYb = pBottomAmplitude*sin((vXb-pTotalX)*pMyAnimFactor)
    vBottomPoint.locH = pSpriteRect.right - abs(vXb)
    vBottomPoint.locV = pSpriteRect.bottom + vYb        -- change operator to alter view.
  else if pDistance > pTotalX then
    vXb = pTotalX
    vYb = pBottomAmplitude*sin((vXb-pTotalX)*pMyAnimFactor)
    vBottomPoint.locH = pSpriteRect.right - abs(vXb)
    vBottomPoint.locV = pSpriteRect.bottom + vYb        -- change operator to alter view.
  end if
  
  -- move top point
  if pDistance >= pLeadInTime AND pDistance <= pTotalDistance then
    vXt = pDistance - pLeadInTime
    vYt = pTopAmplitude*sin((vXt-pTotalX)*pMyAnimFactor)
    vTopPoint.locH = pSpriteRect.right - abs(vXt)
    vTopPoint.locV = pSpriteRect.top + vYt     -- change operator to alter view.
    -- test else
  else if pDistance = pTotalDistance then
    vXt = pTotalDistance
    vYt = pTopAmplitude*sin((vXt-pTotalX)*pMyAnimFactor)
    vTopPoint.locH = pSpriteRect.right - abs(vXt)
    vTopPoint.locV = pSpriteRect.top + vYt     -- change operator to alter view.
  end if
  
  pCurrentQuad[2] = vTopPoint
  pCurrentQuad[3] = vBottomPoint
  
end




----------------------------------------------
on mInitialise me
  
  pSprite = sprite (me.spriteNum)
  pSpriteRect = pSprite.rect
  
  pOrigQuad = duplicate(pSprite.quad)
  pCurrentQuad = duplicate(pOrigQuad)
  
  pTotalX = (pSprite.right - pSprite.left)*2 -- twice the width of the sprite (ie total distance travelled in x)
  
  pLeadInTime = integer(pLeadInTime * pSprite.width) -- the 'lead-in' is expressed as a percentage of sprite.width
  
  pTotalDistance = pTotalX + pLeadInTime -- total number of pixels in x (top and bottom)
  pDistance = 0
  pMyAnimFactor = pi/(pTotalX)
  
  pTopAmplitude = integer(pSprite.height * pTopAmplitude) --  amplitude of top corner arc
  pBottomAmplitude = integer(pSprite.height * pBottomAmplitude) --  amplitude of bottom corner arc
  
  pTurnPage = "m"&pTurnDirection&pLeadCorner&&"me" -- handler defined by author parameters
  pSwitch = FALSE
end




----------------------------------------------
on animate me
  
  if pSwitch then
    repeat while pDistance < pTotalDistance
      do pTurnPage
      pSprite.quad = pCurrentQuad   --- draw sprite
      updateStage
      set pDistance = pDistance + pSpeed
      
      if pChangeMember then
        if pDistance > pTotalDistance/2 then
          pSprite.member = pOtherPage
          updateStage
          pChangeMember = FALSE
        end if
      end if
    end repeat
    
    repeat while pDistance >= pTotalDistance
      set pDistance = pTotalDistance
      do pTurnPage
      pSprite.quad = pCurrentQuad    --- draw sprite
      updateStage
      if pAdvanceWhenFinished then
        go to the frame + 1
      end if
      pSwitch = FALSE
      exit repeat
    end repeat
  end if
  return
end



on turnPage me
  
  case pFrameOrRpt of
    "frame based":
      pSwitch = TRUE
    "repeat loop":
      pSwitch = TRUE
      animate me
  end case
end turnPage

 


Contact

MMI
36 South Court Sq
Suite 300
Newnan, GA 30263
USA

Send e-mail