|
|
|
Allowing Users to Skew an Image
Added on 8/30/1999
|
I am setting up a simple page layout program for elementary school students where the kids can move items around on the screen, place text, and learn how to set up a simple page layout for newspaper or magazine print. I want to allow them to scale or distort images and text for effects as well. I can get this to work in Director, but not in authoring mode. Is this possible?
Get the source
Actually, with Director 7 this is not so hard to do. Most people have seen the great 3d effects Director can accomplish with the new quad property, but there are other useful applications for it as well. Many people get overwhelmed at first by the math involved for using Quads to fake 3d, but the basic concept need not be so daunting. All a quad is is a list of four points on a rectangular bounding box. They are as follows...
1 - Top Left
2 - Top Right
3 - Bottom Right
4 - Bottom Left
So by moving around the bounding rectangle in a clockwise motion we are building a list of those points that can be read and set through director. To see a sprites quad property just type...
put sprite(1).quad
into the message window. So how will this help us? Well, in most programs like Freehand, Illustrator, or Page Maker you can click on an image then pull these points around. For this we will need 2 main elements. One or more sprites to be objects and then 4 "targets", one for each corner. For simplicity sake we can set up one behavior that can be dropped on both, and then we simply pick whether this is a point or an editable object. In the beginSprite handler we use the "mod" function to automatically set the points. Using mod is the equivalent of dividing a number by another over and over until you get a remainder. The result is that remainder. For example, 3 mod 2 would return 1. 3 mod 3 would return 0. If all the target points are placed in the score in sequence, then the behavior applied to each, we can use the spriteNum along with the mod function to get the number of the point that the sprite will represent.
So now what. Well, we also set a beginSprite handler for the object that defines its quad. When ever we click on that object we want to have that sprite to become "active" and all 4 handles to jump into place. Then we can grab a handle and move it and that will send a message to the object to update it's quad. When we are done we can click on the background (also holding the same script) and we can move all 4 handle sprites back off the stage. Take a look at the code below and notice how each handler has different conditions depending on whether we have set it as a point, an object, or a background.
--Copyright 1999 Chuck Neal
--chuck@mediamacros.com
--If you find this code helpful, send me an e-mail and let me know. :-)
property whichItem, spriteNum, whichPoint, quadList
global activeSprite
on getPropertyDescriptionList me
p_list = [:]
p_list.addProp(#whichItem, [#format : #symbol, #comment : "Control point or object?", #default : #point, #range : [#point, #object, #background]])
return p_list
end
on editQuad me
if whichItem = #point then
sprite(spriteNum).loc = sprite(activeSprite).quad[whichPoint]
end if
end
on hidePoints me
if whichItem = #point then
sprite(spriteNum).loc = point(-1000, -1000)
end if
end
on mouseDown me
if whichItem = #point then
repeat while the stillDown
sprite(spriteNum).loc = the mouseLoc
sendSprite(activeSprite, #rescaleQuad, whichPoint, sprite(spriteNum).loc)
end repeat
end if
end
on beginSprite me
if whichItem = #point then
whichPoint = (spriteNum mod 4) + 1
sprite(spriteNum).loc = point(-1000,-1000)
else
quadList = sprite(spriteNum).quad
end if
end
on rescaleQuad me, whatHandle, whatPoint
quadList.setAt(whatHandle, whatPoint)
sprite(spriteNum).quad = quadList
updateStage
end
on mouseUp me
if whichItem = #object then
activeSprite = spriteNum
sendAllSprites(#editQuad)
else if whichItem = #background then
sendAllSprites(#hidePoints)
end if
end
on getBehaviorDescription me
return "For this behavior you will need 4 small " & quote & "handle" & quote & " sprites and at least one image, text, or shape sprite. Drop the behavior on the points, the object and on a background sprite. When you click an object the handles will jump into place and dragging them will skew and scale the image. Click the background the hide the handles off screen."
end
The current active sprite is tracked via a global variable and the rest is kept in local properties. Through the use of sendSprite and sendAllSprites, each element can "talk" to the others and copy properties from one to another.
How can you take this to the next step? Well, what about making it 8 handles so you can skew sides rather than just points. Add more editing tools, or rotate it back into 3d space. Play with it and see what you come up with.
|
|