My Requirement given below:
I want to span same image across two canvas.
Like I have HBOX with two canvas as childs. I want to drag first canvas
display object into second canvas with half portion of that object in 1st canvas and half in second canvas.
Thanks in advance if someone has any idea.
You can split your image, after dropping it, using, for example, copyPixels() on the BitmapData of your image.
Take this example where I used two images in two Groups :
<s:VGroup x="0" y="0" width="300" height="500">
<s:Group id="group_top" width="200" height="200" >
<s:Image id="img_top" x="0" y="0" width="100%" height="100%"
source="assets/image.jpg"
mouseDown="img_top_mouseDownHandler(event)"
mouseUp="img_top_mouseUpHandler(event)"/>
</s:Group>
<s:Group id="group_bottom" width="200" height="200" >
<s:Image id="img_bottom" x="0" y="0" width="100%" height="100%" source=""/>
</s:Group>
</s:VGroup>
For the dragging and dropping, I used the old startDrag() and stopDrag() just for the example of course, you may need to use another way according to your needs.
protected function img_top_mouseDownHandler(event:MouseEvent):void
{
img_top.startDrag();
}
protected function img_top_mouseUpHandler(event:MouseEvent):void
{
img_top.stopDrag();
img_top.x = img_top.y = 0;
split_image();
}
And to split the image, I did like this :
protected function split_image():void
{
var bitmap_data_source:BitmapData = img_top.bitmapData;
var w:int = bitmap_data_source.width,
h:int = bitmap_data_source.height;
var bitmap_data_top:BitmapData = new BitmapData(w, h);
bitmap_data_top.copyPixels(
bitmap_data_source,
new Rectangle(0, 0, w, h/2),
new Point()
);
var bitmap_data_bottom:BitmapData = new BitmapData(w, h);
bitmap_data_bottom.copyPixels(
bitmap_data_source,
new Rectangle(0, h/2, w, h/2),
new Point()
);
var bitmap_top:Bitmap = new Bitmap(bitmap_data_top);
img_top.source = bitmap_top;
var bitmap_bottom:Bitmap = new Bitmap(bitmap_data_bottom);
img_bottom.source = bitmap_bottom;
}
Hope that can help.
Related
I am stuck trying to center a text (RichEditableText) inside a container. My code so far looks like this
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<mx:Box id="myCustomBox" height="100%" width="100%" initialize="init();">
<fx:Script>
<![CDATA[
import mx.containers.Box;
import mx.containers.HBox;
import mx.containers.VBox;
import mx.controls.Button;
import mx.controls.Image;
import spark.components.RichEditableText;
import flashx.textLayout.elements.ParagraphElement;
import flashx.textLayout.elements.SpanElement;
import flashx.textLayout.elements.TextFlow;
import flashx.textLayout.formats.TextAlign;
[Embed("dialog_error.png")]
private var myImage:Class;
public function init():void {
var img:Image = new Image();
img.source = myImage;
this.addElement(buildPane("Something went wrong", img));
}
private function buildPane(message:String, image:Image):Box{
var exPane:HBox = new HBox();
exPane.percentHeight = 100;
exPane.percentWidth = 100;
exPane.setStyle("horizontalGap","0");
//Image hosting pane
var imPane:VBox = new VBox;
imPane.setStyle("backgroundColor","blue");
imPane.percentHeight = 100;
imPane.explicitWidth = 50;
image.minHeight = 16;
image.minWidth = 16;
imPane.setStyle("paddingLeft",10);
imPane.setStyle("paddingRight",10);
var invisBtn1:Button = new Button();
invisBtn1.percentHeight = 40;
invisBtn1.visible = false;
imPane.addChild(invisBtn1);
image.percentHeight = 20;
imPane.addChild(image);
var invisBtn2:Button = new Button();
invisBtn2.visible = false;
invisBtn2.percentHeight = 40;
imPane.addChild(invisBtn2);
exPane.addChild(imPane);
//Text hosting pane
var txtPane:Box = new Box();
txtPane.setStyle("backgroundColor","yellow");
txtPane.percentHeight = 100;
//txtPane.setStyle("paddingBottom",10);
txtPane.setStyle("paddingLeft",0);
//txtPane.setStyle("paddingTop",30);
txtPane.setStyle("paddingRight",5);
//Specify text alignment
var errMsgLabel:RichEditableText = new RichEditableText;
var textFlow:TextFlow = new TextFlow();
var pCenter:ParagraphElement = new ParagraphElement();
var spanCenter:SpanElement = new SpanElement();
spanCenter.text = message;
pCenter.addChild(spanCenter);
pCenter.textAlign = TextAlign.CENTER;
textFlow.addChild(pCenter);
errMsgLabel.textFlow = textFlow;
errMsgLabel.percentHeight = 100;
errMsgLabel.percentWidth = 100;
errMsgLabel.multiline = true;
txtPane.addChild(errMsgLabel);
exPane.addChild(txtPane);
return exPane;
}
]]>
</fx:Script>
</mx:Box>
</s:WindowedApplication>
I would like the text to be at the same level as the dialog_error icon (Usual X mark icon). So if the text is taller, the icon needs to center itself in the middle of the text. Any pointers would be helpful.
Thank you.
I can think of no good reason why you would be writing all of this in ActionScript instead of MXML. You're just making things harder for yourself.
The whole 100 lines of code in your question can be reduced to this:
<s:HGroup width="100%" gap="0">
<s:VGroup width="50" height="100%" paddingLeft="10" paddingRight="10"
verticalAlign="middle">
<s:Image id="msgIcon" source="#Embed('dialog_error.png')"/>
<s:Button visible="false" includeInLayout="false"/>
<s:Button visible="false" includeInLayout="false"/>
</s:VGroup>
<s:RichEditableText id="errMsgLabel" width="100%"/>
</s:HGroup>
This code also contains the necessary fixes to center the error icon horizontally with respect to the error message's text height.
removed the 100% height on the HGroup; this caused the Image to be centered in the middle of the entire container, not just the text height.
added verticalAlign="middle" to the VGroup containing Image and Buttons; this property will align the content of this container to its vertical center.
added includeInLayout="false" to the invisible Buttons; if you just make the Buttons invisible, they will still take up space in the layout, pushing the Image up a little; setting this property to false will tell the VGroup container to act as if the Buttons really weren't there to do its layout.
removed the 100% height on the RichEditableText so that it is only as high as its text content, otherwise the icon will still be centered to the middle of the entire container.
removed a bunch of redundant containers.
Note that I assumed you applied the background colors only for testing purposes, to see how the containers are laid out.
I understand you want to dynamically change the icon. You can easily achieve this by setting its source property programatically afterwards:
msgIcon.source = otherEmbeddedImage;
Or even better, through data binding:
<s:Image source="{msgIcon}"/>
msgIcon = otherEmbeddedImage;
with the following code,it shows write backgroup now
<s:BorderContainer width="100%" height="80%" backgroundAlpha="0">
<s:Image id="bg" width="100%" height="100%"/>
<s:Image id="img" width="100%" height="100%" />
</s:BorderContainer>
var black:BitmapData = new BitmapData(bg.width,bg.height,false,0X656565);
bg.source = new Bitmap(black);
var bitmap:Bitmap = new Bitmap(data.bytes); //a png BitmapData
img.source = bitmap;
In the statement
var black:BitmapData = new BitmapData(bg.width,bg.height,false,0X656565);
you have already set the transparency to false.
Instead try:
var black:BitmapData = new BitmapData(bg.width,bg.height,true,0X00000000);
The third parameter sets the transparency to true and allows the bitmapData to take 32 bit colors which includes the alpha values also. The 32 bit color for the transparency part is passed in the 4th parameter, with the first two digits after the 0x standing for alpha=0.
Hope this helps
I tried to create a rotating animation of an arc. Even after trying all those examples, I am not able to rotate it around the center. It is getting rotated around the top left corner.
private function init():void
{
var hgroup:Group=new Group();
this.addElement(hgroup);
arc1=new Graphic();
arc1.graphics.lineStyle(12,0xff0000,1,false,"normal",CapsStyle.SQUARE);
draw_arc(arc1,CENTER,CENTER,70,14,288,1);
hgroup.addElement(arc1);
var matrix:Matrix = arc1.transform.matrix;
var rect:Rectangle = arc1.getBounds(arc1.parent);
matrix.translate(- (rect.left + (rect.width/2)), - (rect.top + (rect.height/2)));
matrix.rotate((90/180)*Math.PI);
matrix.translate(rect.left + (rect.width/2), rect.top + (rect.height/2));
var rot:Rotate = new Rotate();
rot.angleBy = 360;
rot.duration = 1000;
rot.target = arc1;
rot.play();
}
public function draw_arc(movieclip:Sprite,center_x:Number,center_y:Number,radius:Number,angle_from:Number,angle_to:Number,precision:Number):void {
var angle_diff:Number=angle_to-angle_from;
var steps:Number=Math.round(angle_diff*precision);
var angle:Number=angle_from;
var px:Number=center_x+radius*Math.cos(angle*deg_to_rad);
var py:Number=center_y+radius*Math.sin(angle*deg_to_rad);
movieclip.graphics.moveTo(px,py);
for (var i:Number=1; i<=steps; i++) {
angle=angle_from+angle_diff/steps*i;
movieclip.graphics.lineTo(center_x+radius*Math.cos(angle*deg_to_rad),center_y+radius*Math.sin(angle*deg_to_rad));
}
}
you need this property:
rot.autoCenterTransform="true"
see the example at the bottom of the documentation: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/effects/Rotate.html
I had a similar issue (with a rotating arrow) and I fixed it like this:
<s:Group width="0" height="0" verticalCenter="0" right="14">
<s:Graphic id="arrow" rotation="90" rotation.selectedStates="0">
<s:Path data="M 0 0 L 5 5 L 0 10 Z" left="-2.5" top="-5">
<s:fill>
<s:SolidColor id="arrowFill"/>
</s:fill>
</s:Path>
</s:Graphic>
</s:Group>
The container Group has its size set to 0 as it serves only as an anchor point for the graphic it contains. The position of this Group is the rotating center point. The Path in the Graphic is positioned so that its anchor point is in its center (i.e. it's 5px wide and 10px heigh, so it's repositioned 2.5px to the left and 5px to the top).
The actual rotation is done through States and Transformations here, but an Effect does the same thing.
I've used this solution before; it works well and is very simple:
http://www.chadupton.com/blog/2008/02/rotate-on-center-in-adobe-flex/
To rotate image at the center you have to specify this properties
rot.autoCenterTransform="true";
rot.applyChangesPostLayout = false;
Here is my problem. I have a s:GridItemRenderer (the spark DataGrid size where I use this, is: 100% x 100%) and here is the function in it:
override public function prepare(hasBeenRecycled:Boolean):void {
myLabel.text = width.toString();
}
and here is the "myLabel" in it:
<s:Label id="myLabel" x="0" y="0" width="100%" height="20" paddingBottom="0" paddingLeft="0" paddingRight="0" paddingTop="0"/>
SO AND THE PROBLEM IS:
When i drag the side of the window, and resize it everything is fine! myLabel is updating, but sometimes the last column doesn't. BUT when I maximize the window, NOTHING happend, BUT the "width" variable is updated, but the myLabel.text doesn't. (so I try to use this.width too, but it isn't take effects)
Iam trying to make clicked position to center in flex.
My code is
<fx:Declarations>
<s:Parallel id="transformer" target="{swe}">
<s:Scale id="scaleby" scaleXBy="0.2" scaleYBy="0.2" autoCenterTransform="false"/>
</s:Parallel>
</fx:Declarations>
<s:Group width="500" height="350" clipAndEnableScrolling="true">
<s:SWFLoader source="CasuarinaBigMap.swf" width="500" height="350" id="swe" click="swe_clickHandler(event)"/>
</s:Group>
protected function swe_clickHandler(event:MouseEvent):void
{
scaleby.transformX = event.mouseX;
scaleby.transformY = event.mouseY;
transformer.play();
}
My qustion is
How can I make clicked point pan into the center of the box?
Pls help.
Thanks.
This ought to do the trick:
<fx:Declarations>
<s:Move id="moveEffect" />
</fx:Declarations>
<s:Group id="mapContainer" width="300" height="300" clipAndEnableScrolling="true"
click="pan(event.localX, event.localY)">
<s:Image id="map" source="#Embed('bigMap.png')" />
</s:Group>
'localX' and 'localY' are the mouse's 'x' and 'y' position relative to the mapContainer.
And now the pan() method:
private function pan(mouseX:Number, mouseY:Number):void {
//calculate the offset from mapContainer's center
var diffX:Number = mapContainer.width/2 - mouseX;
var diffY:Number = mapContainer.height/2 - mouseY;
//move the map through the move effect
moveEffect.xFrom = map.x;
moveEffect.yFrom = map.y;
moveEffect.xTo = diffX;
moveEffect.yTo = diffY;
moveEffect.play([map]);
}
Try using a Move effect instead of a Scale effect.