Evenly distribute components relatively their size - actionscript-3

Say there is HGroup which is 100px wide, and there are two images within: image_1 is 20px and image_2 is 30px.
I want image_1 to be centered within first 40 pixels (from pixel 11 to 30) and image_2 within remaining 60 pixels (from pixel 56 to 85) since they divide the whole 100-pixels wide space relatively their size.
Is there a component or property within Spark which allow to do that?

Maybe I'm wrong, but there isn't any method to do this. The instances names have been created for the example:
// container width = 100
var C:HGroupContainer = new HGroupContainer();
this.addChild(C);
const W1:int = 40;
const W2:int = 60;
var r1:Rect1 = new Rect1();
r1.x = (W1 - r1.width) / 2;
this.addChild(r1);
var r2:Rect2 = new Rect2();
r2.x = W1 + (W2 - r2.width) / 2;
this.addChild(r2);
The coordinates x = 0, y = 0 corresponding to the upper-left corner of the images.

You have to wrap the images in HGroups and set the horizontal alignment to center there. That's the Flex way to do it.

Related

Pixi.js - Unable to set sprite width to full width of canvas

Ultimately I want to have a canvas that fills the entire viewport width of the browser and have an image on the canvas fill the entire width of that canvas. I'm taking advantage of pixi.js's displacement filter so that I can create a pseudo 3d effect using a depth map underneath it. The code I'm currently using is
let app = new PIXI.Application();
var w = window.innerWidth;
var h = w / ratio;
app.view.style.width = w + 'px';
app.view.style.height = h + 'px';
document.body.appendChild(app.view);
let img = new PIXI.Sprite.from("images/horses.png");
img.width = w;
img.height = h;
app.stage.addChild(img);
depthMap = new PIXI.Sprite.from("images/horses-depth.png");
depthMap.renderable = false;
depthMap.width = img.width;
depthMap.height = img.height;
img.addChild(depthMap);
app.stage.addChild(depthMap);
displacementFilter = new PIXI.filters.DisplacementFilter(depthMap, 0);
app.stage.filters = [displacementFilter];
Here's a screenshot of it in action.
I even tried manually setting the width to the viewport pixel width on the canvas and the sprite to the actual pixel width of the viewport width and it still wasn't the right size. Manually setting the width for the viewport and sprite to the exact same number also doesn't work; the sprite is inexplicably smaller than the canvas.
I tried to look at the documentation of the sprite class and see if there is something unusual about how sprites handle widths but I couldn't find anything https://pixijs.download/dev/docs/PIXI.Sprite.html
How can I create a pixi.js sprite that fills the entire width of the canvas in order to make both the canvas and the sprite fill the entire viewport width?
pixijs.download
PixiJS API Documentation
Documentation for PixiJS library

AS3 custom TextField text is being drawn outside its textWidth

So this one is a little hard to explain. I have a custom Text class that automatically resizes and sets the width of the text when you change its value. I then take that Text and draw it on a Bitmap to scale it up to make the text look pixelated.
I have a property called maxWidth that allows you to restrict the width of the text if you want it to maintain a certain width. By default the maxWidth is the width of the text's parent so that it doesn't get cut off or expand the parent's boundaries unexpectedly.
So unfortunately when I draw the text it sometimes gets cut off on the right side. Now I've checked all the values and the width and textWidth are showing up as within their maxWidth values, but when I take a look myself through screenshots I see the text is actually about 3 pixels wider than it should be.
Here's an image to better explain what I mean:
I turned on borders so you can easily see what I mean. The word "and" on the first line gets drawn outside its border. Here is the line of code that handles resizing text when you change its bounds.
override protected function checkResize(value:String):void {
var bufferWidth:uint = Math.floor(Number(defaultTextFormat.size) / bufferDivisor) + bufferMin;
var maxWidth:Number = this.maxWidth;
x = y = 0;
if (parent is Stage) {
var stageParent:Stage = Stage(parent);
super.width = stageParent.stageWidth;
super.height = stageParent.stageHeight;
if (maxWidth == 0) maxWidth = stageParent.stageWidth;
}
else {
super.width = parent.width;
super.height = parent.height;
if (maxWidth == 0) maxWidth = parent.width;
}
maxWidth = maxWidth / scale;
text = value;
if (textWidth + bufferWidth <= maxWidth) super.width = textWidth + bufferWidth;
else super.width = maxWidth;
super.height = textHeight + 4;
if (textSnapshot) updateSnapshot();
if (alignRelation) Align.alignTo(textSprite, alignRelation, alignDirection, alignXOffset, alignYOffest);
}
And for this text specifically the width value states it's 512, which is correct since that's the maxWidth. However if you notice the top line in the text, it goes beyond the 512 width border, it actually goes all the way to 515 even though it says its width is 512. Even more bizarre is the textWidth states it's 510.4 even though the first line goes well beyond that amount. I just want to know if I'm doing anything wrong or if there's a way to get a true textWidth value.
This seems to be related to embedding fonts, at least it was when I had the same problem. A workaround is to set the right margin of the text field, like so
var tf:TextFormat = new TextFormat();
tf.rightMargin = 10; // or whatever fixes your problem, e.g. relate it to font size
textField.setTextFormat(tf);

Dynamic sizing in ActionScript (drawRect)?

We can create a rectangle at (0,0) and height and width of 40 with mySprite.graphics.drawRect(0,0,40,40);. However, suppose it is necessary to create a rectangle that fills exactly half the screen (this is for mobile devices, so screen size will vary). How can we accomplish this?
You first need to get the size of the screen, you can use this :
var w = stage.stageWidth;
var h = stage.stageHeight;
Then you can simply draw your rect using theses variables
mySprite.graphics.drawRect(0, 0, w / 2, h / 2);

Coordinate overflow in AS3 when scrolling container object?

Scrolling graph. Currently I show a real-time graph by drawing each piece of data as it is generated. To scroll, I simply move the container object left to compensate and erase all the data left of the bounds.
Simple, fast, surprisingly memory efficient...but is there a concern of the coordinates overflowing as I keep adding contents to the right and scrolling the container left? Is there a limit on the x coordinate of an (empty) object? I'm afraid if I keep scrolling the container left indefinitely and writing to ever increasing x coordinates the program would misbehave eventually. Would this occur? If so, at what max coordinates? Or does AS3 handle this automatically?
I did a test, where I keep drawing an item to a container making it bigger and bigger, and moving it to the left. It stopped getting bigger at 105,000,000 pixels. After that the width reported 0 and the x property reported -107,374,182.4 and wouldn't move beyond that.
If you have bitmap data though, the FP10 limit is 8,191 pixels in width or height, and the total number of pixels cannot exceed 16,777,215 pixels.
Here was my code used to test:
var b:Sprite = new Sprite();
addChild(b);
b.x = stage.stageWidth * .5;
var t:Timer = new Timer(100);
t.addEventListener(TimerEvent.TIMER,tick);
t.start();
var moveAmt:Number = 50;
function tick(e:Event):void {
b.x -= moveAmount;
b.graphics.beginFill(Math.random() * 0xFFFFFF);
b.graphics.drawRect(b.width,0,moveAmount,stage.stageHeight);
b.graphics.endFill();
trace(b.width + " : " + b.x);
}

Setting X Coordinate from Mouse Location

i have a darkBlueRect rectangle sprite and a copy of the same sprite with a larger scale and a lighter color - lightBlueRect.
i'm attempting to shift the location of the lightBlueRect according to the mouse.x location when the mouse is moving over the darkBlueRect. this way if the mouse is on the right of the darkBlueRect than the location of the scaled up lightBlueRect will be on the opposite side and shifted towards the left proportionate to the mouse position and scale. in addition, the lightBlueRect must appear "locked" to the darkBlueRect so lightBlueRect.x must never be more than darkBlueRect.x and lightBlueRect.x + lightBlueRect.width must never be less than darkBlueRect.x + darkBlueRect.width.
the image below depicts 3 states of what i'm attempting to accomplish:
State A: mouse.x is over darkBlueRect.x = 1 and both sprites are aligned to the left.
State B: mouse.x is in the middle of darkBlueRect and both sprites are aligned to the middle.
State C: mouse.x is on the last pixel of darkBlueRect and both sprites are aligned to the right.
for this example, the darkBlueRect.width is equal to 170 and the lightBlueRect.width is equal to 320, or a scale of 1.89.
each time the mouse changes it's x position over darkBlueRect the following is called. however, while my current code works for the most part, it's not exactly correct. when the mouse.x is over darkBlueRect.x = 1, as shown in State A, the lightBlueRect.x is not property aligned with darkBlueRect and appears less than darkBlueRect.x.
var scale:Number = 1.89;
lightBlueRect.x = darkBlueRect.x - Math.round((mouse.x * scale) / darkBlueRect.width * (lightBlueRect.width - darkBlueRect.width));
what equation can i use so that no matter the scale of the lightBlueRect it's first position (mouse over first pixel) and last position (mouse over last pixel) will result in the 2 sprites being aligned as well as property proportionate positioning in between?
[EDIT] the coordinates of the darkBlueRect is {0, 0}, so when the lightBlueRect moves towards the left it is moving into the negative. i could have simply written my code (what doesn't work) like this instead:
var scale:Number = 1.89;
lightBlueRect.x = 0 - Math.round((mouse.x * scale) / darkBlueRect.width * (lightBlueRect.width - darkBlueRect.width));
[EDIT 2]
when the display objects are small, the problem is difficult to notice. however, when they are large the problem becomes move obvious. the problem, here, being that the objects on the left side are misaligned.
also the problem is probably exasperated by the fact that both the lightBlueRect and darkBlueRect are scalable. darkBlueRect is scaled down and lightBlueRect is scaled up.
here is a link to the test displaying the problem. mousing over the shape quickly will obviously result in inaccurate alignment since it's based on frame rate speed, but this is not my concern. still, when you slowly mouse over the shape it will not align correctly on the left side when the mouse is over the first pixel of darkBlueRect: http://www.geoffreymattie.com/test/test.html
[SWF(width = "1000", height = "600", backgroundColor = "0xCCCCCC")]
import flash.display.Sprite;
import flash.events.MouseEvent;
var downScale:Number = 0.48;
var upScale:Number = 2.64;
var darkBlueRect:Sprite = createSprite();
darkBlueRect.scaleX = darkBlueRect.scaleY = downScale;
darkBlueRect.x = stage.stageWidth / 2 - darkBlueRect.width / 2;
darkBlueRect.y = stage.stageHeight / 2 - darkBlueRect.height / 2;
addChild(darkBlueRect);
var lightBlueRect:Sprite = createSprite();
lightBlueRect.scaleX = lightBlueRect.scaleY = upScale;
lightBlueRect.y = stage.stageHeight / 2 - lightBlueRect.height / 2;
lightBlueRect.x = stage.stageWidth;
lightBlueRect.mouseEnabled = false;
addChild(lightBlueRect);
darkBlueRect.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
function mouseMoveEventHandler(evt:MouseEvent):void
{
lightBlueRect.x = darkBlueRect.x + Math.max(0.0, Math.min(darkBlueRect.mouseX / darkBlueRect.width * downScale, 1.0)) * (darkBlueRect.width - lightBlueRect.width);
}
function createSprite():Sprite
{
var result:Sprite = new Sprite();
result.graphics.beginFill(0x0000FF, 0.5);
result.graphics.drawRect(0, 0, 700, 200);
result.graphics.endFill();
return result;
}
i believe the problem is that the scaling of the shapes.
Assuming you have a Clamp function handy, and that width is floating-point so that division works as expected:
lBR.x = dBR.x + Clamp((mouse.x - dBR.x) / dBR.width, 0, 1) * (dBR.width - lBR.width);
(You can define Clamp(x, m, M) = min(max(x, m), M) if you don't have one.)