How to resize an image on drag? - actionscript-3

I have a couple of images I want to use in a drag and drop game. I've got this working through the actionscript code snippets but I also need these images to be able to resize by dragging an arrow or something similar at the bottom corner. I can either get the dragging working by not including the resize code and vice versa.
this.addEventListener(MouseEvent.MOUSE_MOVE, resize);
this.addEventListener(MouseEvent.MOUSE_UP, stopDragging, true);
this.addEventListener(MouseEvent.MOUSE_DOWN, startDragging, true);
function startDragging(E:MouseEvent):void {
resize1.startDrag();
}
function stopDragging(E:MouseEvent):void {
resize1.stopDrag();
}
function resize(E:MouseEvent):void {
item1_mc.width = resize1.x - item1_mc.x;
item1_mc.height = resize1.y - item1_mc.y;
}
Does anyone have any idea how to fix this? I know my image resize code is primitive at the moment but that can be changed to scaling soon enough.

You have to split your image movieclip (or whatever you have) into two parts - one draggable and one resizeable like that
myImageWidget (this is your parent movicelip)
|
|- imageMC (this will hold the image and will be the draggable object)
|- arrowMC (this is your arrow that will be OVER your image and will be used to resize)
Then IN YOUR "myImageWidget" you need something like this (get rid of all "this.", it makes no sense :)
// image MC will listen for clicks and start dragging
imageMC.addEventListener(MouseEvent.MOUSE_UP, stopDragging, true);
imageMC.addEventListener(MouseEvent.MOUSE_DOWN, startDragging, true);
// arrow MC will listen for clicks and start resizing
arrowMC.addEventListener(MouseEvent.MOUSE_UP, stopResizing, true);
arrowMC.addEventListener(MouseEvent.MOUSE_DOWN, startResizing, true);
function startDragging(E:MouseEvent):void
{
startDrag();
}
function stopDragging(E:MouseEvent):void
{
stopDrag();
}
function startResizing(E:MouseEvent):void
{
addEventListener(MouseEvent.MOUSE_MOVE, resize);
}
function stopResizing(E:MouseEvent):void
{
removeEventListener(MouseEvent.MOUSE_MOVE, resize);
}
function resize(E:MouseEvent):void
{
// you will adjust this to local coordinates since you are inside of the imageWidget
width = mouseX;
height = mouseY;
}

Related

Flash reverse timeline

Worked with flash cs6 and as3.
I wanted to make menu like this link. When mouse_over on the menu, the blue rectangle moves to the right; and when mouse_up, the animation reversed.
I made the blue rectangle in a movieclip menuBlueHome. There, I made the rectangle moves from left to right (from frame 1 to 10). At frame 10, I made action script:
stop();
I was still working with home menu when I faced this problem. When I hover the home menu, the blue rectangle moves to the right and reversed straightaway before mouse_up. Here is the code outside the mc:
var menuBlueHome: MovieClip;
menuBlueHome.stop();
var direct: String;
btnHome.addEventListener(MouseEvent.MOUSE_OVER,onOverHome);
btnHome.addEventListener(MouseEvent.MOUSE_OUT,onLeaveHome);
btnHome.addEventListener(MouseEvent.CLICK,onClickHome);
function onOverHome(e:MouseEvent):void{
androidHome.visible = true;
menuBlueHome.play();
}
function onLeaveHome(e:MouseEvent):void{
androidHome.visible = false;
addEventListener(Event.ENTER_FRAME,onFrameHome);
}
function onClickHome(e:MouseEvent):void{
gotoAndStop(1);
}
function onFrameHome(event:Event):void {
if(menuBlueHome.currentFrame > 9) {
direct = "backward";
}
var backAmount:Number = menuBlueHome.currentFrame -1;
if(direct == "backward") {
menuBlueHome.gotoAndStop(backAmount);
}
}
Did I make something wrong with the code? Thanks for your help.
Try with this code:
function onLeaveHome(e:MouseEvent):void{
androidHome.visible = false;
menuBlueHome.removeEventListener(Event.ENTER_FRAME, onFrameHome);
menuBlueHome.addEventListener(Event.ENTER_FRAME, onFrameHome);
}
function onFrameHome(event:Event):void {
var backAmount:Number = menuBlueHome.currentFrame - 1;
menuBlueHome.gotoAndStop(backAmount);
if(backAmount == 1) menuBlueHome.removeEventListener(Event.ENTER_FRAME, onFrameHome);
}
Here you have and example.
But, I recommend you to do your code more dynamic, here you have another example.

Flash Senocular Transform Tool - controls are not showing on the tool

I am having trouble with the controls showing up for my transform tool. When I click my image I get the bounding box (to scale or rotate the image), but when I hover over the corner I do not get the cursor to transform it.
I am using these files:
TransformTool.as
TransformToolControl.as
TransformToolCursor.as
This is my code to call the transform tool:
var tool:TransformTool = new TransformTool();
addChild(tool);
And this later on to make the tool show up when the image is clicked and make the tool disappear when the stage is clicked:
tmpImage.addEventListener(MouseEvent.CLICK, select);
function select(e:MouseEvent):void {
tool.target = e.currentTarget as Sprite;
stage.addEventListener(MouseEvent.MOUSE_DOWN, deselect);
}
function deselect(e:MouseEvent):void {
tool.target = null;
tmpImage.addEventListener(MouseEvent.CLICK, select);
}
My image selection for the bounding box to appear and disappear work perfectly. All my code works as expected.... except the actual controls on the bounding box. Please help!
Edit
The concept is the user can click an image from a menu and drag a new instance of that image to the stage. Then the user can click the new instance and should be able to rotate or scale it. Then they can click off the image to make the bounding box disappear. (They can add as many images to the stage that they want).
Here is some code that shows the basic click, create new instance, and drag process I have implemented.
//sb1 is the menu area that contains a group of images
//hill is one of the images the user can add to the stage
sb1.hill.addEventListener(MouseEvent.MOUSE_DOWN, createCopy);
var i:int=0;
var tmpImage:Sprite; //to store which image is being dragged currently
function createCopy(e:MouseEvent):void {
tmpImage = new Hill_mc();
tmpImage.name = "hillChild"+(i++); //increment every copy
container.addChild(tmpImage);
tmpImage.x = mouseX-470;
tmpImage.y = mouseY-270;
tmpImage.startDrag();
tmpImage.addEventListener(MouseEvent.MOUSE_DOWN, onDown); //add the mouse down to this new object
stage.addEventListener(MouseEvent.MOUSE_UP, onUp); //since the mouse is currently down, we need to listen for mouse up to tell the current copy to stop dragging
}
//this will be called when click a copy
function onDown(e:MouseEvent):void {
tmpImage = Sprite(e.currentTarget); //get a reference to the one that was clicked, so we know which object to stop dragging on the global mouse up.
container.addEventListener(MouseEvent.MOUSE_UP, onUp); //listen for the mouse up
tmpImage.startDrag();
}
function onUp(e:MouseEvent):void {
container.removeEventListener(MouseEvent.MOUSE_UP,onUp);
if (tmpImage.hitTestObject(thesubmenu1)) {
container.removeChild(tmpImage);
}
else {
tmpImage.stopDrag();
}
tmpImage.addEventListener(MouseEvent.CLICK, select);
}
function select(e:MouseEvent):void {
tool.target = e.currentTarget as Sprite;
tmpImage.addEventListener(MouseEvent.MOUSE_DOWN, deselect);
}
function deselect(e:MouseEvent):void {
tool.target = null;
tmpImage.addEventListener(MouseEvent.CLICK, select);
}
EDIT
I found this code and placed it in my TransformTool.as. I feel like it's so close and that there must be something called incorrectly because I get an error for a null object reference:
public function select(event:Event):void {
// the selected object will either be the
// event target or current target. The current
// target is checked first followed by target.
// The parent of the target must match the
// parent of the tool to be selected this way.
if (event.currentTarget != this
&& event.currentTarget.parent == parent){
setTarget(event.currentTarget as DisplayObject, event);
}else if (event.target != this
&& event.target.parent == parent){
setTarget(event.target as DisplayObject, event);
}
}
/**
* Helper selection handler for deselecting target objects. Set this
* handler as the listener for an event that would cause the
* deselection of a target object.
* It is not required that you use this event handler. It is only a
* helper function that can optionally be used to help ease
* development.
*/
public function deselect(event:Event):void {
if (_target != null && event.eventPhase == EventPhase.AT_TARGET){
setTarget(null, null);
}
}
You give too little information to determine what exactly is wrong.
However, there is a very good sample code that does exactly what you want here :
http://www.senocular.com/demo/TransformToolAS3/TransformTool.html
(Click on the link at the bottom of the image.)
I am sure that you are going to make it with this.
EDIT :
Try to use the built-in handlers. I would do something like this :
Instead of this :
tmpImage.addEventListener(MouseEvent.CLICK, select);
function select(e:MouseEvent):void {
tool.target = e.currentTarget as Sprite;
stage.addEventListener(MouseEvent.MOUSE_DOWN, deselect);
}
function deselect(e:MouseEvent):void {
tool.target = null;
tmpImage.addEventListener(MouseEvent.CLICK, select);
}
Do this :
tmpImage.addEventListener(MouseEvent.MOUSE_DOWN, tool.select);
stage.addEventListener(MouseEvent.MOUSE_DOWN, tool.deselect);
EDIT :
If you do not have the handlers, I am not sure :) but I would recommand removing event listeners in each method as they might be interfering with each other.
tmpImage.addEventListener(MouseEvent.CLICK, select);
function select(e:MouseEvent):void {
tmpImage.removeEventListener(MouseEvent.CLICK, select);
tool.target = e.currentTarget as Sprite;
stage.addEventListener(MouseEvent.MOUSE_DOWN, deselect);
}
function deselect(e:MouseEvent):void {
stage.removeEventListener(MouseEvent.MOUSE_DOWN, deselect);
tool.target = null;
tmpImage.addEventListener(MouseEvent.CLICK, select);
}

Changing text dynamically with drag / drop in Flash CS6 (AS3)

I have some incredibly simple code that works fine in letting me drag a "slider" button horizontally. However, I also want the text that appears above the object to change depending upon what the x-coordinate is of the object I'm dragging.
Here's the simple code:
var rectangle:Rectangle = new Rectangle(31,944,179,0);
Button.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag);
function fl_ClickToDrag(event:MouseEvent):void
{
Button.startDrag(false, rectangle);
}
Button.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
function fl_ReleaseToDrop(event:MouseEvent):void
{
Button.stopDrag();
gotoAndPlay(20);
}
What I'm wanting to do is have the system determine where the "Button" is in terms of its x-coordinate, and if the x-coordinate is higher than, say, 50, for the text above the "Button" to say "50+", and if the x-coordinate is higher than 100 for the text to change to "100+". I'm also not sure if the x-coordinate should be relative to the rectangle or relative to the entire screen.
Any and all help is appreciated.
You can use a boolean var to indicate if your button is dragged and if, then update your text field like this :
var is_dragged:Boolean = false;
var rectangle:Rectangle = new Rectangle(0, 100, stage.stageWidth - button.width, 0);
stage.addEventListener(Event.ENTER_FRAME, _onEnterFrame);
function _onEnterFrame(e:Event):void {
if(is_dragged){
text_field.text = String(Math.round(button.x / 50) * 50) + '+';
}
}
button.addEventListener(MouseEvent.MOUSE_DOWN, button_onPress);
function button_onPress(e:MouseEvent):void {
button.startDrag(false, rectangle);
is_dragged = true;
}
button.addEventListener(MouseEvent.MOUSE_UP, button_onRelease);
function button_onRelease(e:MouseEvent):void {
button.stopDrag();
is_dragged = false;
}
You can see this code working here.
Hope that can help.

unselect sprite clicking somewhere else on stage or other movieclips

In my scenario I have a sprite "imgSprite" with dynamically loaded image. I have drawn a small box near bottom left corner inside this sprite named "rectangle". The imageSprite is also drag/drop able. When I click on the image I set it to show rectangle but I can not figure out how to hide it clicking somewhere outside imgSpirte.
var imgSprite:Sprite = new Sprite();
imgSprite.addChild(image);
MovieClip(root).addChild(imgSprite);
/* DELETE BUTTON */
var rectangle:Sprite = new Sprite();
rectangle.graphics.beginFill(0xFF0000);
rectangle.graphics.drawRect(0, 0, 20,20);
rectangle.graphics.endFill();
rectangle.y=imgSprite.y+imgSprite.height;
rectangle.x=imgSprite.x-20;
imgSprite.addChild(rectangle);
rectangle.addEventListener(MouseEvent.CLICK, function() {
rectangle.parent.parent.removeChild(imgSprite);
});
imgSprite.addEventListener("mouseDown", function() {
imgSprite.startDrag();
rectangle.visible = true;
});
stage.addEventListener("mouseUp", function() {
imgSprite.stopDrag();
});
/*
imgSprite.addEventListener("mouseOut", function() {
var timer = setInterval(deSelect,3000);
function deSelect(){
rectangle.visible = false;
clearInterval(timer);
}
});
*/
You can try a temporary listener for stage. Say, like this:
if (rectangle) rectangle.visible=false; // or it won't trigger
imgSprite.addEventListener("mouseDown",onMouseDown);
function onMouseDown(e:MouseEvent):void {
if (rectangle) if (!rectangle.visible)
stage.addEventListener("mouseDown",removeRectangle);
imgSprite.startDrag();
rectangle.visible=true;
e.stopPropagation(); // this is needed to not get the rectangle removed as soon as you click on imgSprite
}
function removeRectangle(e:MouseEvent):void {
if (rectangle) rectangle.visible=false;
stage.removeEventListener("mouseDown",removeRectangle);
}
It works like this: As soon as you click on the imgSprite, a listener gets assigned to stage and the rectangle is made visible. If you click on imgSprite again, the rectangle is already visible, so no extra listeners are added. Also e.stopPropagation() prevents an existing listener to get triggered and get the rectangle hidden. And as soon as you click elsewhere but on imgSprite, the listener gets triggered, removes itself from stage, and hides rectangle.

Actionscript Image with clickable spots

Can any one help in suggesting a solution for the following:
i have a large image, consider it as a map, i want to put this image in a viewer that is smaller than the image and i have to be able to scroll the image by clicking and dragging it.
and i want to put in this image a clickable spots in a specified x and y coordinated, and be able to click the spots.
when clicking any spot in the image, the image will be changed with a new spots.. and so on..
can you help in suggesting what is the best object to load the image in and be able to do all the mentioned points.
Thanks in advance.
This is easier than you think. You have a few goals to consider:
"i want to put this image in a viewer that is smaller than the image": You dont need anything special to do this. The concept of this is simply that you have a mask overlay where you want the large image visible.
var viewer:Sprite = new Sprite; //200x200
var imageMask:Sprite = new Sprite; //200x200
var imageContainer:Sprite = new Sprite; //400x500
imageContainer.mask = imageMask;
viewer.addChild(imageContainer);
//this will allow you to visibly see only 200x200 of the
//imageContainer at any time
"i have to be able to scroll the image by clicking and dragging it": This is a little more logic as the imageContainer will have to move in the -(negative) direction of the mouse. Add some listeners to check for mouse actions, and drag as required.
var allowDrag:Boolean = false;
imageContainer.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
imageContainer.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
imageContainer.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
function onMouseDown(e:Event):void{
allowDrag = true;
}
function onMouseUp(e:Event):void{
allowDrag = false;
}
function onMouseMove(e:Event):void{
//return if not dragging
if(!allowDrag) return;
//move the imageContainer in a -(negative) direction of the mouse
//use an index relative to the size of the viewer and imageContainer
var speed:Number = 0.5;
imageContainer.x -= (viewer.width/imageContainer.width)*speed;
imageContainer.y -= (viewer.height/imageContainer.height)*speed;
//clean the positions so the image remains within the viewer
if(imageContainer.x > 0) imageContainer.x = 0;
if(imageContainer.x < -viewer.width) imageContainer.x = -viewer.width;
if(imageContainer.y > 0) imageContainer.y = 0;
if(imageContainer.y < -viewer.height) imageContainer.y = -viewer.height;
}
"i want to put in this image a clickable spots in a specified x and y coordinated, and be able to click the spots": This also requires a little more thinking. In this case what you want to do is create [hotspots] on the image that are clickable, when clicked = do actions.
//USAGE
//define the click area coords
var clickCoords:Rectangle = new Rectangle();
clickCoords.x = 10; //starts at x 10
clickCoords.y = 10; //starts at y 10
clickCoords.width = 100; //100 wide
clickCoords.height = 100; //100 tall
//add the click listener
var clickArea:Sprite = hotSpot(imageContainer,clickCoords);
clickArea.addEventListener(MouseEvent.CLICK, onHotSoptClick);
//hot spot factory
function hotSpot(target:Sprite,coords:Rectangle):Sprite{
//create the hotspot
var hs:Sprite = new Sprite;
hs.graphics.beginFill(0,0);
hs.graphics.drawRect(0,0,coords.width,coords.height);
hs.graphics.endFill();
//add the hotspot to the target
hs.x = coords.x;
hs.y = coords.y;
target.addChild(hs);
}
function onHotSoptClick(e:MouseEvent):void{
//do something
}
IMPORTANT:
You may want to keep a list of hot spots you create so you can do garbage cleanup, and you plan on dynamically generating hotspots per image... then YOU MUST keep an active list of hot spots and remove when not in use.
You can catch the events MouseDown, MouseUp, MouseMove, MouseOut, on your viewing window, this way you can control exactly what do you want to do.
Here is the pseudo-code:
reset()
{
isDown=false;
downPointX=0;
downPointY=0;
distanceX=0;
distanceY=0;
}
onMouseDown()
{
isDown=true;
downPointX=mouseX;
downPointY=mouseY;
}
onMouseUp()
{
if(distanceX+distanceY==0 and isDown)
click(downPointX,downPointY);
reset();
}
onMouseMove()
{
if isDown then
distanceX=mouseX-downPointX;
distanceY=mouseY-downPointY;
drag(distanceX,distanceY);
endif;
}
onMouseOut()
{
reset();
}
drag(distanceX,distanceY)
{
change your map coordinates
}
click(downPointX,downPointY)
{
if(inSpot(downPointX,downPointY)==true)
changeMap();
endif;
}
changeMap()
{
change your maps and spots
}
avoid implementing any event for your spots sprites or you can get unexpected results.
You can check these for more information
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Sprite.html#eventSummary