12Apr/090
How To – Center a image on a canvas in flex
This is the solution for the anoying behaivor of the image control into a canvas or hbox or whatever. If the image is set to be scaled to a maximum width and height and maintaining the aspect ration, it won't center itself even if it has the horizontalCenter set to "0". So...here's how it looks (top) and how it suppose to look (bottom)
Solution
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 | <mx :Script> < ![CDATA[ // Maximum width private var mxw:Number = 500; // Maximum height private var mxh:Number = 250; public function onImageComplete(e:Event):void { var wthMaxRatio:Number = mxw / mxh; // no resize needed if (e.target.contentWidth <= mxw && e.target.contentHeight <= mxh) { e.target.x = (mxw - e.target.contentWidth) / 2; e.target.y = (mxh - e.target.contentHeight) / 2; } else { var wthImgRatio:Number = e.target.contentWidth / e.target.contentHeight; if (wthImgRatio > wthMaxRatio) { // will max out the width e.target.width = mxw; var imgHeight:Number = Math.round( (mxw / e.target.contentWidth) * e.target.contentHeight ); var newY:Number = Math.round( (mxh - imgHeight) / 2 ); e.target.x = 0; e.target.y = newY; } else { // will max out the height e.target.height = mxh; var imgWidth:Number = Math.round( (mxh / e.target.contentHeight) * e.target.contentWidth ); var newX:Number = Math.round( (mxw - imgWidth) / 2 ); e.target.x = newX; e.target.y = 0; } } } ]]> </mx> <mx :Canvas width="500" height="250" verticalScrollPolicy="off" horizontalScrollPolicy="off" backgroundColor="#000000"> <mx :Image id="theimage" maintainAspectRatio="true" scaleContent="true" complete="onImageComplete(event)" /> </mx> |
May 21st, 2009 - 07:01
Lazy way, embed the image in a Canvas and set the verticalCenter/horizontalCenter of the canvas.
May 21st, 2009 - 13:57
@widged
That won’t do. If you want to scale the image, it won’t center
June 17th, 2009 - 13:05
I think the best way to do this is to set the maxWidth/maxHeight attributes instead of the width/heigth.. and stay with the verticalCetner/horizontalCenter=0 .. this works fine.
example:
June 17th, 2009 - 13:28
@guille
no quille, it won’t work. If you set maxWidth and maxHeight to the picture as much as the canvas will permit, if the picture is 10 times larger than the canvas, when it shrinks with the maintainAspectRatio set to true, the image component width and height will be the ones that you set to maxWidth and maxHeight, but the graphic itself inside will be draw to the left, and not to the center. that was the initial problem I enounced. Check it. You’ll see it won’t work.
Generated by FlexWebFormater
August 20th, 2009 - 19:47
I can confirm guille’s word. Nice solution. I came up with same. Anyone got something cleaner (that you know works)?
December 30th, 2009 - 06:44
I have something a little cleaner.
Check it out Flex Image Centering
var ratio:Number = Math.min(image.maxWidth/image.contentWidth,image.maxHeight/image.contentHeight );
image.width = ratio * image.contentWidth;
image.height = ratio * image.contentHeight;
February 26th, 2010 - 22:52
I got completely tripped up by this as well, and ultimately found the solution after several hours of the worst kind of programming rage imaginable.
I finally realized that instead of setting the horizontalAlign and verticalAlign properties on the box (or canvas) that contains the image control, that the image control is treating its image data as a child of itself, and that you can set the vertAlign and horiAlign on the image control with the desired results! Also, go ahead and blow out the height and width of the Image control (100%) while setting real dimensions for the container box, and use scaleContent and maintainAspectRatio and get down wit yo bad self you sexy flex developer!
Thanks for listening.
Jack
March 3rd, 2010 - 15:02
@jaryckon
Damn, homie, u totally killed that sh*t!
Kudos to you for the quick & elegant solution.
width=”100%” height=”100%”
horizontalAlign=”center” verticalAlign=”middle”
Works every time.
April 14th, 2010 - 11:45
your solution didn’t work for me, so this is what I’m using instead.
package com.customClasses
{
import mx.containers.Canvas;
import mx.controls.Image;
/**
* @author Anton.Stepanov
* actionscriptpro_at_gmail
*/
public class ImageThumbPreview extends Canvas
{
private static var DEFAULT_IMAGE_TO_CANVAS_SCALE:Number = 0.8;
private var imgScale:Number = DEFAULT_IMAGE_TO_CANVAS_SCALE;
private var img:Image;
public function ImageThumbPreview()
{
super();
}
public function set imageScale(value:Number):void
{
imgScale = value;
}
public function get imageScale():Number
{
return imgScale
}
public function set thumbImg(value:Image):void
{
if (img) this.removeChild(img);
img = value;
// Maximum width
var mxw:Number = this.width * imgScale;
// Maximum height
var mxh:Number = this.height * imgScale;
// no resize needed
if (img.width <= mxw && img.contentHeight <= mxh)
{
img.x = (mxw – img.contentWidth) / 2;
img.y = (mxh – img.contentHeight) / 2;
}
else
{
var scaleRatio:Number
var scaleRatioX:Number = mxw / img.contentWidth;
var scaleRatioY:Number = mxh / img.contentHeight;
if (scaleRatioX < scaleRatioY)
{
scaleRatio = img.scaleX = img.scaleY = scaleRatioX;
}
else
{
scaleRatio = img.scaleX = img.scaleY = scaleRatioY;
}
img.x = (this.width – (img.contentWidth * scaleRatio)) / 2;
img.y = (this.height – (img.contentHeight * scaleRatio)) / 2;
}
addChild(img);
}
public function get thumbImg():Image {
return img;
}
}
}
January 18th, 2013 - 19:41
This is just what I needed thanks for sharing! I have been looking for some help with the image-flex I have just started getting into it and I don’t understand a lot about it. Any help like this and tips would be so useful. I’m so excited to figure this out and have fun with my pictures!