POO Propperty getter / setter vs Function (Theory) - function

So if a getter is finally a function, why not use just a function? I guess to enforce using that function to set/get a value any time needed, any other reason?

A getter is a function (as far as POO languages I know).
The idea is to delegate the ability to modify or to get an attribute to only one function by class, in case of there were special checks to perform before applying the getter or setter.

Properties are used just to improve readability or ease the API, without breaking encapsulation. For example, if you have a Rectangle class and you want to increase by 10 the width of an instance, without properties, you would do something like:
rect.setWidth(rect.getWidth() + 10)
While, using properties, you could just write:
rect.width += 10
Which is clearer. And because properties are functions, you can do all the checks that you need. Moreover, it doesn't even matter if the width is actually stored in the class; maybe the rectangle is stored as a pair of points (i.e. upper-left and lower-right), but the property would handle it. Additionally, you could write properties that access the same data in different ways: for example, you could have width, height, top, bottom, left and right properties, and all of them would affect the same internal data of the class, but would make it easier to use and more readable.

Related

Find element by its calculated properties (e.g. position and size withing ranges) [duplicate]

This question already has answers here:
Get element with a randomized class name
(2 answers)
Closed 4 years ago.
In an attempt to make web scraping with a headless browser more resilient to site changes, I'd like to combine technical properties of the elements with their visual characteristics.
E.g. when looking for a search bar, I'd like to look for a "big (>50% width), visible (:visible) text input field (<input type="text">) in the upper half of the screen/rendered page." Then, when looking for the submit button, I'd like to find a button located near the aforementioned search bar.
Is there any way to set up this kind of search criterion?
AFAICS, CSS selectors and XPath can only search by predefined parameters (tag, id, class, attributes), not by calculated ones.
The best idea I currently have is to search by predefined parameters, then filter the result further by getting size, position and such for each result and comparing them to the desired ranges. This is rather slow oftentimes since I have to use expressions like *[text()="visible text"] to not rely on technical details that are subject to change without notice.
Here are a few examples of ways to find your wanted element. All below examples are based on the assumption that you have an element that looks a little like this (can be different type and css elsewhere, but basically that you have an element somewhere with some styling and some attribute).
<div mycustomattribute="login" style="width:calc(5cm - 3cm)"></div>
Note that the below examples aren't necessarily all I the ways I can give you, it's just the ones I could think of on the fly, if your problem isn't resolved using these I can probably think of one or two more ways to solve your problem.
Selecting using a custom attribute
You can set any attribute you want on any element you want. For example, if you want <div mycustomattribute="hello"> and then querySelect that, it's totally valid.
var test = document.querySelect("div[mycustomattribute=login]")
The above script will select only the div that has an attribute name with the value login. I think you already know of this method but figured I'd mention it because it's by far the easiest, least hacky way of finding a specific element, if you can set an attribute on your element that is.
Select using position
Lets say you want to select the nearest element that is 50 px to the right of the element you selected.
var base = document.querySelect("div[name=login]")
// Get Y coordinate of base element
var y = base.getBoundingClientRect().top;
// Get X coordinate of base element on its right side, since we're gonna look to the right of it
var x = base.getBoundingClientRect().right;
// Find the element that is 50 pixels to the right of our base element
var element = document.elementFromPoint(x + 50, y);
Select using CSS values
This is more tricky but certainly possible. You are correct in that you can't just run querySelector to find an element based on a CSS value (calculated or otherwise), but you can run the calculation yourself to get the value your desired element should have and then just loop through them to get the one you want.
So, for example:
var divs = document.querySelectorAll('div');
var element = null;
for (i = 0; i < divs.length; ++i) {
/* We assume you know the result of the calculated value, either because it's
a static result (e.g. `5cm - 3cm`), or because you rerun the calculation in
javascript to find out what its result is.
Note that you can use whatever style you want here to find the div, like
"visible" or "display" or whatever you want, just set up the proper if
statements.
*/
if(div.style.width = "2cm") {
element = div;
break;
}
}
References
This is a little side note but try to use mozilla instead of w3schools, mozilla is way better for references. I was hesitant too at first to make the jump to mozillas documentation but it really is way better once you learn how to use it.
https://developer.mozilla.org/en-US/docs/Web/API/Document
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
https://developer.mozilla.org/en-US/docs/Web/API/Document/elementFromPoint
https://css-tricks.com/snippets/javascript/loop-queryselectorall-matches/

Object does not rotate around pivot point

I have an object which looks like this:
When I try to rotate it using [INSTANCENAME].rotation += 10;
it still rotates around the middle of the object. Am I doing something wrong?
I've done a little research, and apparently there is no direct way to change the pivot point programmatically, AFAIK. Rather odd, seeing as you can change it in the Flash Pro IDE. (For those reading, the pivot point is NOT the same as the registration point.)
[EDIT: Thinking more about it, I don't think the pivot point actually "exists", at least in the context of a programmable property. It only exists in the context of some tools in the Flash IDE.]
You will need to place your object ALONE inside another object, so that the desired pivot point of the inner object is over the center of the outer object. Then, rotate the outer object.
You can later control your object's "pivot point" by changing the position of the inner object.
Since the outer object's center moves depending on its size, and the position of the inner object determines the size of the outer object, you'd need to apply some math. The x position of the inner object would need to be equal to the distance from the desired pivot point on the inner object to the far right edge of that inner object. The same concept applies to the y position.
This can be accomplished both in the IDE directly, or through code, whichever you choose.
An example of code to change this dynamically. This function is inside the outer object. (You can get pivotX and pivotY off an event listener, if you want.) [Sorry, the code is untested.]
function newPivot(int pivotX, int pivotY):void
{
inner.x = inner.width - pivotX;
inner.y = inner.height - pivotY;
}
I hope that solves your problem!
A very simple way is to do like this.
Convert the image to a symbol(MovieClip). [you might have already done it].
Double Click on the MovieClip/Sprite to enter inside.
Move the Image so that the registration point align towards the pivot.
NB: Applicable only in case of FLASH IDE.

Tweens on same element

If I apply 2 tweens at the same element it will not Tween. Why? Or am I doing something wrong?
_input.tween('opacity', 1);
_input.tween('height', '100px');
// nothing happens
But both work individually.
Fiddle
Element.prototype.tween is an abstraction of Fx.Tween, which creates a new Fx.Tween instance on that element and binds to a single property at a time.
http://mootools.net/docs/core/Fx/Fx.Tween#Element-Properties:tween - you are instatiating two tweens which probably interfere with each other since iirc, the element getter/setter can only work with a single instance - which goes into Element Storage.
you want to use morph instead - http://mootools.net/docs/core/Fx/Fx.Morph and pass an object, i.e.
_input.morph({
opacity: 1,
height: 100
});
morph was meant to modify multiple properties on the same element object on a unified timer.
you could manually do new Fx.Tween(_input, ... ) twice and it will work but it may not be 100% on the same clock for the animation so it may seem choppy

Children of Children of MovieClip not showing up when MovieClip is added to stage?

This problem seems very simple to me, but I've been unable to fix it, or find an answer anywhere.
This is in a class constructor for a class called block, block_maker is the object that called the constructor, an instance of level.
this.bitmap = new Bitmap(this.bitmap_data);
this.addChild(this.bitmap);
this.block_maker.stage_foreground.addChild(this);
In level, stage_foreground is added to the stage, but nothing appears. trace(stage_foreground.numChildren); shows the correct count of children, and var temp = (this.stage_foreground.getChildAt(0)); trace(temp.numChildren); correctly but the children OF the children don't actually show up, the stage just stays blank.
When I change the above code to
this.bitmap = new Bitmap(this.bitmap_data);
this.block_maker.stage_foreground.addChild(this.bitmap);
the blocks appear on the stage, as children of level_instance.stage_foreground, but with this method, the bitmaps aren't appropriately positioned, as they have no position data. I can simply give this.bitmap x and y positions, and it works, but I am curious as to why it won't work when just adding the bitmap as a child to the block and then adding that as a child to stage_foreground.
I've tried replacing this.bitmap with a number of other object classes, such as a temporary MovieClip I made, or a Shape, but nothing shows up, so I know it has nothing to do with it being a Bitmap.
As you stated
This is in a class constructor for a class called block, block_maker
is the object that called the constructor, an instance of level.
this.bitmap = new Bitmap(this.bitmap_data);
this.addChild(this.bitmap);
this.block_maker.stage_foreground.addChild(this);
The level class needs to to extend a display object for it to show up.
In other words
"this"
has to be a display object or extend it in some form.
The reason this doesn't work.
this.block_maker.stage_foreground.addChild(this);
and this does
this.block_maker.stage_foreground.addChild(this.bitmap);
Is because "this" is not a display object but "this.bitmap" is.
The DisplayObject class is the base class for all objects that can be placed on the display list.
First of all, even though it's not neccesary, I'd suggest to make a classname start with a capital letter, and vars always start with a lower-case letter. It's a common 'rule' in AS3 that's mainly to avoid confusion.
The problem most likely lies within you use of this; what you're doing is adding this into this. It seems to me it's not a proper way of coding.
Also, since all of the other attempts didn't work; have you tried to make the var you want ot add a public static var?

AS3 Custom Depth Control

I am trying to create a way of controlling movieclip depths, which movieclip is show above another, so that I can set the depth of a movieclip to any number and they will be displayed with higher values above lower values.
I was thinking of creating a MovieClipDepth class that extends MovieClip with the added property depth, and a Container class that extends DisplayObjectContainer which all objects will be placed inside of.
The Container class will override the addChild method to update the child display order when a child is added.
What I need help with is how do I reorder the children according to
their depth value?
As you can read in the comment below your question, there are several methods for this.
But actually, what you asked "set the depth of a movieclip to any number" can't really be done in AS3. If i'm correct, you could do this in AS2, so...
... how was it ...
_root.createEmptyMovieClip("mc", -1000);
or
_root.createEmptyMovieClip("mc1", 1);
_root.createEmptyMovieClip("mc2", 10);
worked, but does not work in AS3. In AS3 depth starts with 0 and you can't force a DisplayObject to sit on a level what is not continous from zero.
So the depths' of 3 movieclips in a container is only possible with these values: 0, 1, 2.
Depth can't be a negative number for example.
Now, if you want to build a custom depth manager, you can do that, but you have to consider these facts.
So to say, you could create virtual depths.
So I guess, you could override the addChildAt method for example. At the moment, if you would give a wrong number: negative, or higher then the number of children, flash would give back the error:
RangeError: Error #2006: The supplied index is out of bounds.
So mc.addChildAt(newchild, -1000) gives an arror.
But with overriding the method, you could make a trick, so you could store the depths in an array. You could store any numbers and then transform that order for the needs of AS3.
Like pairing the depths with the added children, sorting the array by the depths, then manage the children according to the order.
If you have more questions, feel free to ask, hope this gets you closer to the solution.
I suggest you take a look at this tutorial :
A Tour of Depths Management Methods on the website http://www.flashandmath.com/. I presume you not a newbie .
The link is this:
http://www.flashandmath.com/intermediate/depths/index.html