How to as3 resize a movieClip and constrain proportions | Actionscript Tutorial

constrain proportions jpgI’ve had that exact task numerous time while scripting actionscript. I have a source image loaded externally or a mc within the program and I need to fit it into a certain area (width x height) but keep the aspect ratio the same or as photoshop calls it “constrain proportions”. I’ve done this with fancy and not so fancy formulas and equations, but finally I had it and created a simple function that would do it every time. Figured it was worth sharing cause if I’ve googled it before then others most likely will too!

This is more than just setting the width and height of an object, because that way the image is easily skewed and the natural proportions are messed up. If you want to just use scale you need to know the dimensions of the image being resized, and that’s just not scalable (no pun intended).

What we have to do is to do both. Assign the width and height to skew it, and then scale it to correct the proportion. So if we want to resize an image when we don’t know it’s current size to fit into a 300 pixel square we set the width and height of that image to 300 and then a bit of logic that can be summed up in one line:

1
mc.scaleX < mc.scaleY ? mc.scaleY = mc.scaleX : mc.scaleX = mc.scaleY;

That says if the x scale is larger than the y scale set the x to the y scale amount, and vice versa. It’s basically setting both scales to the smaller of the two. This works because we don’t know the original size of the image, but actionscript does. scaleX and scaleY are ratios of the current width and height to the originals. A little complicated I know, but that’s why I’ve made the function below. I know how to use it and now I don’t have to think about skewing and then scaling back to keep my aspect ratio or proportion. You should see how to use it just by looking at it:

1
resizeMe(mc:MovieClip, maxW:Number, maxH:Number=0, constrainProportions:Boolean=true)

Pass in the movieClip you want to resize, and the size you want it to fit into. So with the same example above, just do

1
resizeMe(image, 300);

Example

Here’s an interactive example to show what I mean. It loads an external image and you click and drag the mouse around to resize it. To toggle whether you want to constrain proportions use the space bar. Type a url to any image you want to test it with and press load, or hit ‘enter’.

Get Adobe Flash player

Here’s a screenshot of me playing with a photo in here NOT constraining proportions.
constrain proportions jpg

Source (AS3)

The resizing function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//The resizing function
// parameters
// required: mc = the movieClip to resize
// required: maxW = either the size of the box to resize to, or just the maximum desired width
// optional: maxH = if desired resize area is not a square, the maximum desired height. default is to match to maxW (so if you want to resize to 200x200, just send 200 once)
// optional: constrainProportions = boolean to determine if you want to constrain proportions or skew image. default true.
function resizeMe(mc:MovieClip, maxW:Number, maxH:Number=0, constrainProportions:Boolean=true):void{
    maxH = maxH == 0 ? maxW : maxH;
    mc.width = maxW;
    mc.height = maxH;
    if (constrainProportions) {
        mc.scaleX < mc.scaleY ? mc.scaleY = mc.scaleX : mc.scaleX = mc.scaleY;
    }
}

The full source

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
var defaultUrl:String = "http://circlecube.com/wp-content/uploads/2008/11/circlecubelogo4.png";
var image:MovieClip = new MovieClip();
loadImage();
function loadImage(url:String=""):void {
    if (url == "" || url == defaultToLoadString) url = defaultUrl;
    //clear image
    image.visible = false;
    image = new MovieClip();
    //add image
    var ldr:Loader = new Loader();
    var urlReq:URLRequest = new URLRequest(url);
    trace("loading image: " + url);
    ldr.load(urlReq);
    ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, imageCompleteHandler);
    image.addChild(ldr);
    addChild(image);
}

function imageCompleteHandler(e:Event):void {
    resizeMe(image, stage.stageWidth)
}

//The resizing function
// parameters
// required: mc = the movieClip to resize
// required: maxW = either the size of the box to resize to, or just the maximum desired width
// optional: maxH = if desired resize area is not a square, the maximum desired height. default is to match to maxW (so if you want to resize to 200x200, just send 200 once)
// optional: constrainProportions = boolean to determine if you want to constrain proportions or skew image. default true.
function resizeMe(mc:MovieClip, maxW:Number, maxH:Number=0, constrainProportions:Boolean=true):void{
    maxH = maxH == 0 ? maxW : maxH;
    mc.width = maxW;
    mc.height = maxH;
    if (constrainProportions) {
        mc.scaleX < mc.scaleY ? mc.scaleY = mc.scaleX : mc.scaleX = mc.scaleY;
    }
}

var constrainOn:Boolean = true;
var isPressed:Boolean = false;

stage.addEventListener(MouseEvent.MOUSE_MOVE, moved);
stage.addEventListener(MouseEvent.MOUSE_DOWN, pressed);
stage.addEventListener(MouseEvent.MOUSE_UP, released);
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownListener);

function keyDownListener(e:KeyboardEvent) {
    if (e.keyCode == 32){//spacebar
        toggled(e);
    }
    if(e.keyCode == 13){//enter
        loadImagePress(e);
    }
}

function moved(e:Event):void{
    if (isPressed)
    resizeMe(image, mouseX, mouseY, constrainOn);
}
function pressed(e:MouseEvent):void{
    isPressed = true;
    moved(e);
}
function released(e:MouseEvent):void{
    isPressed = false;
}
function toggled(e:Event):void{
    constrainOn = !constrainOn;
    moved(e);
}
var defaultToLoadString:String = "type url of image to load";
toLoad.text = defaultToLoadString;
toLoad.addEventListener(FocusEvent.FOCUS_IN, toLoadFocus);
toLoad.addEventListener(FocusEvent.FOCUS_OUT, toLoadBlur);
function toLoadFocus(e:FocusEvent):void{
    if (toLoad.text == defaultToLoadString)
    toLoad.text = "";
}
function toLoadBlur(e:FocusEvent):void{
    if (toLoad.text == "")
    toLoad.text = defaultToLoadString;
}
loadBtn.addEventListener(MouseEvent.CLICK, loadImagePress);
function loadImagePress(e:Event):void{
    loadImage(toLoad.text);
}

Download

constrainProportions.fla

And as usual, let me know if you’ve got any comments questions or suggestions! Thanks,

This entry was posted in tutorial and tagged , , , , , , , . Bookmark the permalink. Both comments and trackbacks are currently closed.

There are 51 comments

Comments are closed.
  • Recent Posts

    Screenshot 2015-08-03 08.19.16

    Every Browser is the New IE (to me) – daverupert.com

    Maybe one day the Web will be perfect and complete and I will not need to reach for polyfills. However, if that happened I think I’d stop being interested the Web because it would then be a stagnant pond and not a surfable ocean. Source: Every Browser is the New IE (to me) – daverupert.com […]

    Screenshot 2015-07-31 14.15.00

    URL Structure FTW – Pretty and Readable Permalinks

    I noticed that the clearleft.com site has very clever url structure. You can read the urls like a sentence. Like their about section is “/is” and their capabilities is ‘/does’, and their portfolio section is “/made” , so clearleft.com made code for america. Check the urls listed here and you’ll notice that they read like a […]

    promo

    What Is Code? If You Don’t Know, You Need to Read This

    Here’s a great read that may take a while but is a nice trip through programming history through the lens of one who’s been there. The world belongs to people who code. Those who don’t understand will be left behind. Source: What Is Code? If You Don’t Know, You Need to Read This

    Adactio: Journal—Instantiation

    There needs to be a cultural change in how we approach building for the web. Yes, some of the tools we choose are part of the problem, but the bigger problem is that performance still isn’t being recognised as the most important factor in how people feel about websites (and by extension, the web). This […]

    human_time_diff « WordPress Codex

    Determines the difference between two timestamps.The difference is returned in a human readable format such as “1 hour”, “5 mins”, “2 days”. Source: Function Reference/human time diff « WordPress Codex Used this little known, but nice gem today. It’s a core WordPress function that gives human relative time from any other datetime in “U” format. […]

    logo

    Cyclomatic Complexity: Logic in CSS – CSS Wizardry – CSS, OOCSS, front-end architecture, performance and more, by Harry Roberts

    I recently hit upon a way of thinking that made me realise that CSS does include logic, and the fact that it’s rarely viewed as such is probably also why we end up with such poor CSS at all.I found myself explaining compound selectors to a client as being made up of the subject—the thing […]

css.php