Articles Archive
Articles Search
Director Wiki
 

Making a Magnifying Glass

August 9, 2000
by Gary Rosenzweig

One of the questions I often get asked is how to make a fake magnifying glass in Director. Until Director 8's Imaging Lingo, this was done with Xtras or by faking it with multiple images. Now, with only a few lines of Lingo, you can make the effect.

The first thing you need is an image to magnify. Director can't make pixels out of thin air, so you need to have this image at the resolution at which you want it to appear under the magnifying glass. To make the image that appears on the Stage, use the same member, but scale it down. In the sample below, the member is shown on the Stage at 25% scale. The magnifying glass, however, shows it at 100%.

A Director 8 sample movie is available for download in Mac (1.4 MB) or PC (1.2 MB) format.

The magnifying glass itself is one bitmap image. The glass area starts off as black, and then copyPixels is used to copy a circular area into the glass. The first step in doing this is to determine where the cursor is located in the full image. Director's mapStageToMember() function is perfect for this. If you feed it the sprite number and the mouse location, you get back the location inside the image. This is calculated taking the scaling and positioning of the image into account. So, mapStageToMember() will always get the location right, no matter the sprite is, or how it is stretched. The next step is to determine a rectangular area in the image that is centered on the cursor. We use the rectangle of a third member, the glass mask bitmap, to determine the width and height of the rectangle.

This glass mask member is a copy of the inner portion of the magnifying glass itself -- it is just the glass part, a circle. Not only will we use the rectangle of the glass mask, but we will also use the createMask() function to turn it into a mask to be used by the copyPixels() function. This means that a circular image will be copied from the main image into the magnifying glass image, rather than a rectangular one. Finally, we need to position the magnifying glass directly under the cursor to complete the effect. Here is the complete code from this behavior.

property pGlassImage, pGlassMask, pGlassRect, pRegPoint, pLastLoc, pOrigImage

on beginSprite me

  -- get the image to use as the magnifying glass (next sprite)
  pGlassImage = sprite(me.spriteNum+1).member.image

  -- get the original image
  pOrigImage = duplicate(pGlassImage)

  -- take the matte image from another member
  pGlassMask = member("glass mask").image.createMask()

  -- determine the rect of the glass mask, with the center at 0,0
  pGlassRect = rect(-member("glass mask").width/2,-member("glass mask").height/2,member("glass mask").width/2,member("glass mask").height/2)

  -- get the registration point of the glass
  pRegPoint = sprite(me.spriteNum+1).member.regPoint

end


on exitFrame me

  -- get new mouse location
  ml = the mouseLoc

  -- only update image if the location has changed
  if ml <> pLastLoc then
    
    -- get the relative location inside the image
    loc = mapStageToMember(sprite me.spriteNum, ml)
    
    -- if outside the image, hide glass
    -- otherwise, show glass with new image imprint
    if voidP(loc) then
      sprite(me.spriteNum+1).loc = point(-1000,-1000)
      
    else
      -- get the area inside the image
      sourceRect = rect(loc,loc) + pGlassRect
      
      -- determine the area of the glass to use
      destRect = rect(pRegPoint,pRegPoint) + pGlassRect
      
      -- figure out the mask offset so things line up correctly
      maskOffset = loc - point(pGlassRect.width/2,pGlassRect.height/2)
      
      -- copy pixels from image into glass using the mask
      pGlassImage.copyPixels(pOrigImage, pGlassImage.rect,pOrigImage.rect)
      pGlassImage.copyPixels(sprite(me.spriteNum).member.image, destRect,sourceRect,[#maskImage: pGlassMask, #maskOffset: maskOffset])
      
      -- position the sprite under the cursor
      sprite(me.spriteNum+1).loc = the mouseLoc
      
      -- remember the current location
      pLastLoc = ml
      
    end if
    
  end if

end


on endSprite me

  -- restore original image
  pGlassImage.copyPixels(pOrigImage, pGlassImage.rect,pOrigImage.rect)

end

Notice that I also made a duplicate of the original magnifying glass image. This is then used in two places. The first place is to refresh the magnifying glass just before a new magnified image is inserted. If I did not do this, and the glass were positioned over the edge of the image, you would see leftover pixels from previous positions. I also use this original image to reset the member when the sprite is done. This just keeps it all neat. Now that you have the code, you can change the glass and glass mask members to make any type of magnifying glass you like. You can even use two circles, instead of one, to make binoculars. Another interesting thing is that this code does not rely on any specific scaling or positioning of the original sprite. You can import a huge image and scale it down 10%, or import a small image and scale it at 50%. Either way, the magnifying glass will show it at 100%.

Gary Rosenzweig's new book "Special Edition Using Director 8" is now available. It's the most comprehensive guide to Director ever, including tons of examples and demo movies. It's suitable for novices and experts alike. More information about the book can be found at http://clevermedia.com/resources/bookstore/book5.html. It can be purchased there, or in your local bookstore.

Gary Rosenzweig is the Chief Engineer, founder, and owner of CleverMedia, a game and multimedia development company in Denver, Colorado. He is the author of ten books on Macromedia Director and Flash, including his latest, Special Edition Using Director MX.

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