123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- import { RAD_TO_DEG, DEG_TO_RAD } from "./const";
- import { Bounds } from "./bounds";
- import { Point } from "./point";
- import { Transform } from "./transform";
- import { Rectangle } from "./rectangle";
- export class DisplayObject {
- tempDisplayObjectParent?:DisplayObject;
- transform = new Transform();
- visible = true;
- parent?:any;
- alpha = 1;
- /**
- * The multiplied alpha of the displayObject.
- */
- worldAlpha = 1;
- /**
- * Which index in the children array the display component was before the previous zIndex sort.
- * Used by containers to help sort objects with the same zIndex, by using previous array index as the decider.
- */
- _lastSortedIndex = 0;
- /**
- * The zIndex of the displayObject.
- * A higher value will mean it will be rendered on top of other displayObjects within the same container.
- */
- _zIndex = 0;
- /**
- * The bounds object, this is used to calculate and store the bounds of the displayObject.
- */
- _bounds = new Bounds();
- _boundsID = 0;
- _lastBoundsID = -1;
- _boundsRect?:Rectangle;
- _localBoundsRect?:Rectangle;
- /**
- * If the object has been destroyed via destroy(). If true, it should not be used.
- */
- _destroyed = false;
- get _tempDisplayObjectParent() {
- if (!this.tempDisplayObjectParent) {
- this.tempDisplayObjectParent = new DisplayObject();
- }
- return this.tempDisplayObjectParent as DisplayObject;
- }
- /**
- * Updates the object transform for rendering.
- * TODO - Optimization pass!
- */
- updateTransform() {
- if (this.parent) {
- this.transform.updateTransform(this.parent.transform);
- // multiply the alphas..
- this.worldAlpha = this.alpha * this.parent.worldAlpha;
- } else {
- this.transform.updateTransform(this._tempDisplayObjectParent.transform);
- this.worldAlpha = this.alpha;
- }
- this._boundsID++;
- }
- /**
- * Recursively updates transform of all objects from the root to this one
- * internal function for toLocal()
- */
- _recursivePostUpdateTransform() {
- if (this.parent) {
- this.parent._recursivePostUpdateTransform();
- this.transform.updateTransform(this.parent.transform);
- } else {
- this.transform.updateTransform(this._tempDisplayObjectParent.transform);
- }
- }
-
- calculateBounds() {
- console.log("please implement me")
- }
- getBounds(skipUpdate:boolean, rect?:Rectangle) {
- if (!skipUpdate) {
- if (!this.parent) {
- this.parent = this._tempDisplayObjectParent;
- this.updateTransform();
- this.parent = undefined;
- } else {
- this._recursivePostUpdateTransform();
- this.updateTransform();
- }
- }
- if (this._boundsID !== this._lastBoundsID) {
- this.calculateBounds();
- this._lastBoundsID = this._boundsID;
- }
- if (!rect) {
- if (!this._boundsRect) {
- this._boundsRect = new Rectangle();
- }
- rect = this._boundsRect;
- }
- return this._bounds.getRectangle(rect);
- }
- getLocalBounds(rect?:Rectangle) {
- const transformRef = this.transform;
- const parentRef = this.parent;
- this.parent = undefined;
- this.transform = this._tempDisplayObjectParent.transform;
- if (!rect) {
- if (!this._localBoundsRect) {
- this._localBoundsRect = new Rectangle();
- }
- rect = this._localBoundsRect;
- }
- const bounds = this.getBounds(false, rect);
- this.parent = parentRef;
- this.transform = transformRef;
- return bounds;
- }
- /**
- * Calculates the global position of the display object.
- */
- toGlobal(position:Point, point:Point, skipUpdate = false) {
- if (!skipUpdate) {
- this._recursivePostUpdateTransform();
- // this parent check is for just in case the item is a root object.
- // If it is we need to give it a temporary parent so that displayObjectUpdateTransform works correctly
- // this is mainly to avoid a parent check in the main loop. Every little helps for performance :)
- if (!this.parent) {
- this.parent = this._tempDisplayObjectParent;
- this.displayObjectUpdateTransform();
- this.parent = undefined;
- } else {
- this.displayObjectUpdateTransform();
- }
- }
- // don't need to update the lot
- return this.worldTransform.apply(position, point);
- }
- /**
- * Calculates the local position of the display object relative to another point.
- *
- * @param {PIXI.IPoint} position - The world origin to calculate from.
- * @param {PIXI.DisplayObject} [from] - The DisplayObject to calculate the global position from.
- * @param {PIXI.IPoint} [point] - A Point object in which to store the value, optional
- * (otherwise will create a new Point).
- * @param {boolean} [skipUpdate=false] - Should we skip the update transform
- * @return {PIXI.IPoint} A point object representing the position of this object
- */
- toLocal(position:Point, from:DisplayObject, point:Point, skipUpdate:boolean) {
- if (from) {
- position = from.toGlobal(position, point, skipUpdate);
- }
- if (!skipUpdate) {
- this._recursivePostUpdateTransform();
- // this parent check is for just in case the item is a root object.
- // If it is we need to give it a temporary parent so that displayObjectUpdateTransform works correctly
- // this is mainly to avoid a parent check in the main loop. Every little helps for performance :)
- if (!this.parent) {
- this.parent = this._tempDisplayObjectParent;
- this.displayObjectUpdateTransform();
- this.parent = undefined;
- } else {
- this.displayObjectUpdateTransform();
- }
- }
- // simply apply the matrix..
- return this.worldTransform.applyInverse(position, point);
- }
- setParent(container:any) {
- if (!container || !container.addChild) {
- throw new Error("setParent: Argument must be a Container");
- }
- container.addChild(this);
- return container;
- }
- setTransform(
- x = 0,
- y = 0,
- scaleX = 1,
- scaleY = 1,
- rotation = 0,
- skewX = 0,
- skewY = 0,
- pivotX = 0,
- pivotY = 0
- ) {
- this.position.x = x;
- this.position.y = y;
- this.scale.x = !scaleX ? 1 : scaleX;
- this.scale.y = !scaleY ? 1 : scaleY;
- this.rotation = rotation;
- this.skew.x = skewX;
- this.skew.y = skewY;
- this.pivot.x = pivotX;
- this.pivot.y = pivotY;
- return this;
- }
- /**
- * Base destroy method for generic display objects. This will automatically
- * remove the display object from its parent Container as well as remove
- * all current event listeners and internal references. Do not use a DisplayObject
- * after calling `destroy()`.
- *
- */
- sortDirty = false;
- destroy() {
- if (this.parent) {
- this.parent.removeChild(this);
- }
- this.parent = undefined;
- this._destroyed = true;
- }
- /**
- * The position of the displayObject on the x axis relative to the local coordinates of the parent.
- * An alias to position.x
- */
- get x() {
- return this.position.x;
- }
- set x( value // eslint-disable-line require-jsdoc
- ) {
- this.transform.position.x = value;
- }
- /**
- * The position of the displayObject on the y axis relative to the local coordinates of the parent.
- * An alias to position.y
- *
- * @member {number}
- */
- get y() {
- return this.position.y;
- }
- set y(
- value // eslint-disable-line require-jsdoc
- ) {
- this.transform.position.y = value;
- }
- /**
- * Current transform of the object based on world (parent) factors.
- *
- * @member {PIXI.Matrix}
- * @readonly
- */
- get worldTransform() {
- return this.transform.worldTransform;
- }
- get localTransform() {
- return this.transform.localTransform;
- }
- /**
- * The coordinate of the object relative to the local coordinates of the parent.
- * Assignment by value since pixi-v4.
- *
- * @member {PIXI.IPoint}
- */
- get position() {
- return this.transform.position;
- }
- set position(
- value // eslint-disable-line require-jsdoc
- ) {
- this.transform.position.copyFrom(value);
- }
- /**
- * The scale factor of the object.
- * Assignment by value since pixi-v4.
- *
- * @member {PIXI.IPoint}
- */
- get scale() {
- return this.transform.scale;
- }
- set scale(
- value // eslint-disable-line require-jsdoc
- ) {
- this.transform.scale.copyFrom(value);
- }
- /**
- * The pivot point of the displayObject that it rotates around.
- * Assignment by value since pixi-v4.
- *
- * @member {PIXI.IPoint}
- */
- get pivot() {
- return this.transform.pivot;
- }
- set pivot( value ) {
- this.transform.pivot.copyFrom(value);
- }
- //保持当前对象位置不变,修改pivot
- setPivotWorldNoChange(x:number, y:number) {
- const targetPivot = { x, y };
- const point = { x: targetPivot.x, y: targetPivot.y };
- this.worldTransform.apply(point as any, point as any);
- this.pivot = targetPivot as any;
- this.position.x = point.x;
- this.position.y = point.y;
- this.updateTransform();
- }
- /**
- * The skew factor for the object in radians.
- * Assignment by value since pixi-v4.
- */
- get skew() {
- return this.transform.skew;
- }
- set skew(
- value // eslint-disable-line require-jsdoc
- ) {
- this.transform.skew.copyFrom(value);
- }
- /**
- * The rotation of the object in radians.
- * 'rotation' and 'angle' have the same effect on a display object; rotation is in radians, angle is in degrees.
- */
- get rotation() {
- return this.transform.rotation;
- }
- set rotation(
- value // eslint-disable-line require-jsdoc
- ) {
- this.transform.rotation = value;
- }
- /**
- * The angle of the object in degrees.
- * 'rotation' and 'angle' have the same effect on a display object; rotation is in radians, angle is in degrees.
- *
- * @member {number}
- */
- get angle() {
- return this.transform.rotation * RAD_TO_DEG;
- }
- set angle(
- value // eslint-disable-line require-jsdoc
- ) {
- this.transform.rotation = value * DEG_TO_RAD;
- }
- /**
- * The zIndex of the displayObject.
- * If a container has the sortableChildren property set to true, children will be automatically
- * sorted by zIndex value; a higher value will mean it will be moved towards the end of the array,
- * and thus rendered on top of other displayObjects within the same container.
- *
- * @member {number}
- */
- get zIndex() {
- return this._zIndex;
- }
- set zIndex(
- value // eslint-disable-line require-jsdoc
- ) {
- this._zIndex = value;
- if (this.parent) {
- this.parent.sortDirty = true;
- }
- }
- get worldVisible() {
- let item:any = this;
- do {
- if (!item.visible) {
- return false;
- }
- item = item.parent;
- } while (item);
- return true;
- }
- getGlobalPosition( point = new Point(),skipUpdate = false ) {
- if (this.parent) {
- this.parent.toGlobal(this.position, point, skipUpdate);
- } else {
- point.x = this.position.x;
- point.y = this.position.y;
- }
- return point;
- }
- displayObjectUpdateTransform = this.updateTransform;
- }
|