var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
/**
* @module annie
*/
var annie;
(function (annie) {
/**
* Stage 表示显示 canvas 内容的整个区域,所有显示对象的顶级显示容器
* @class annie.Stage
* @extends annie.Sprite
* @public
* @since 1.0.0
*/
var Stage = /** @class */ (function (_super) {
__extends(Stage, _super);
/**
* 显示对象入口函数
* @method Stage
* @param {string} rootDivId
* @param {number} desW 舞台宽
* @param {number} desH 舞台高
* @param {number} fps 刷新率
* @param {string} scaleMode 缩放模式 StageScaleMode
* @param {number} renderType 渲染模式0:canvas 1:webGl 2:dom
* @public
* @since 1.0.0
*/
function Stage(rootDivId, desW, desH, frameRate, scaleMode, renderType) {
if (rootDivId === void 0) { rootDivId = "annieEngine"; }
if (desW === void 0) { desW = 640; }
if (desH === void 0) { desH = 1040; }
if (frameRate === void 0) { frameRate = 30; }
if (scaleMode === void 0) { scaleMode = "fixedHeight"; }
if (renderType === void 0) { renderType = 0; }
var _this = _super.call(this) || this;
/**
* annie.Stage舞台初始化完成后会触发的事件
* @event annie.Event.ON_INIT_STAGE
* @since 1.0.0
*/
/**
* <h4><font color="red">小游戏不支持 小程序不支持</font></h4>
* annie.Stage舞台尺寸发生变化时触发
* @event annie.Event.RESIZE
* @since 1.0.0
*/
/**
* annie引擎暂停或者恢复暂停时触发,这个事件只能在annie.globalDispatcher中监听
* @event annie.Event.ON_RUN_CHANGED
* @since 1.0.0
*/
/**
* annie.Stage 的多点触碰事件。这个事件只能在annie.Stage对象上侦听
* @event annie.TouchEvent.ON_MULTI_TOUCH
* @type {string}
*/
/**
* <h4><font color="red">小游戏不支持 小程序不支持</font></h4>
* 是否阻止ios端双击后页面会往上弹的效果,因为如果阻止了,可能有些html元素出现全选框后无法取消
* 所以需要自己灵活设置,默认阻止.
* @property iosTouchendPreventDefault
* @type {boolean}
* @default true
* @since 1.0.4
* @public
*/
_this.iosTouchendPreventDefault = true;
/**
* <h4><font color="red">小游戏不支持 小程序不支持</font></h4>
* 是否禁止引擎所在的DIV的鼠标事件或触摸事件的默认行为,默认为true是禁止的。
* @property isPreventDefaultEvent
* @since 1.0.9
* @default true
* @type {boolean}
*/
_this.isPreventDefaultEvent = true;
/**
* <h4><font color="red">小游戏不支持 小程序不支持</font></h4>
* 整个引擎的最上层的div元素,
* 承载canvas的那个div html元素
* @property rootDiv
* @public
* @since 1.0.0
* @type {Html Div}
* @default null
*/
_this.rootDiv = null;
/**
* 当前stage所使用的渲染器
* 渲染器有两种,一种是canvas 一种是webGl
* @property renderObj
* @public
* @since 1.0.0
* @type {IRender}
* @default null
*/
_this.renderObj = null;
/**
* 渲染模式值 只读 CANVAS:0, webGl: 1
* @property renderType
* @readonly
* @public
* @since 1.0.0
* @type {number}
* @default 0
* @readonly
*/
_this.renderType = 0;
_this._viewRect = new annie.Rectangle();
/**
* 开启或关闭多点手势事件 目前仅支持两点 旋转 缩放
* @property isMultiTouch
* @since 1.0.3
* @type {boolean}
*/
_this.isMultiTouch = false;
/**
* 开启或关闭多个手指的鼠标事件
* @property isMultiMouse
* @since 1.1.3
* @type {boolean}
*/
_this.isMultiMouse = false;
/**
* <h4><font color="red">小游戏不支持 小程序不支持</font></h4>
* 当设备尺寸更新,或者旋转后是否自动更新舞台方向
* 默认不开启
* @property autoSteering
* @public
* @since 1.0.0
* @type {boolean}
* @default false
*/
_this.autoSteering = false;
/**
* <h4><font color="red">小游戏不支持 小程序不支持</font></h4>
* 当设备尺寸更新,或者旋转后是否自动更新舞台尺寸
* 默认不开启
* @property autoResize
* @public
* @since 1.0.0
* @type {boolean}
* @default false
*/
_this.autoResize = false;
/**
* 舞台的尺寸宽,也就是我们常说的设计尺寸
* @property desWidth
* @public
* @since 1.0.0
* @default 320
* @type {number}
* @readonly
*/
_this.desWidth = 0;
/**
* 舞台的尺寸高,也就是我们常说的设计尺寸
* @property desHeight
* @public
* @since 1.0.0
* @default 240
* @type {number}
* @readonly
*/
_this.desHeight = 0;
/**
* 舞台在当前设备中的真实高
* @property divHeight
* @public
* @since 1.0.0
* @default 320
* @type {number}
* @readonly
*/
_this.divHeight = 0;
/**
* 舞台在当前设备中的真实宽
* @property divWidth
* @public
* @since 1.0.0
* @default 240
* @readonly
* @type {number}
*/
_this.divWidth = 0;
/**
* 舞台的背景色
* 默认为""就是透明背景
* 可能设置一个颜色值改变舞台背景
* @property bgColor
* @public
* @since 1.0.0
* @type {string} #FFFFFF" 或 RGB(255,255,255) 或 RGBA(255,255,255,255)
*/
_this.bgColor = "";
_this._isFullScreen = true;
_this._scaleMode = "onScale";
//原始为60的刷新速度时的计数器
_this._flush = 0;
// 当前的刷新次数计数器
_this._currentFlush = 0;
_this._lastDpList = {};
//这个是鼠标事件的MouseEvent对象池,因为如果用户有监听鼠标事件,如果不建立对象池,那每一秒将会new Fps个数的事件对象,影响性能
_this._ml = [];
//这个是事件中用到的Point对象池,以提高性能
_this._mp = [];
// 鼠标按下事件的对象池
_this._mouseDownPoint = {};
//html的鼠标或单点触摸对应的引擎事件类型名
_this._mouseEventTypes = {
mousedown: "onMouseDown",
mouseup: "onMouseUp",
mousemove: "onMouseMove",
touchstart: "onMouseDown",
touchmove: "onMouseMove",
touchend: "onMouseUp",
touchcancel: "onMouseUp"
};
//stageMousePoint
_this.sp = new annie.Point();
//localPoint;
_this.lp = new annie.Point();
_this.muliPoints = [];
//当document有鼠标或触摸事件时调用
_this._mP1 = new annie.Point();
//当document有鼠标或触摸事件时调用
_this._mP2 = new annie.Point();
_this.mouseEvent = null;
_this._isMouseClickCanvas = true;
/**
* 当舞台尺寸发生改变时,如果stage autoResize 为 true,则此方法会自己调用;
* 如果设置stage autoResize 为 false 你需要手动调用此方法以更新界面.
* 不管autoResize 的状态是什么,你只要侦听 了stage 的 annie.Event.RESIZE 事件
* 都可以接收到舞台变化的通知。
* @method resize
* @public
* @since 1.0.0
* @return {void}
*/
_this.resize = function () {
var s = this;
var whObj = s.getRootDivWH(s.rootDiv);
if (s.divWidth == 0 || s.divHeight == 0) {
if (whObj.w == 0 || whObj.h == 0)
return;
s.a2x_um = true;
s.divHeight = whObj.h;
s.divWidth = whObj.w;
s.renderObj.reSize(whObj.w * annie.devicePixelRatio, whObj.h * annie.devicePixelRatio);
s.setAlign();
s.dispatchEvent("onInitStage");
}
else if (s.autoResize) {
if (s.divWidth != whObj.w || s.divHeight != whObj.h) {
s.a2x_um = true;
s.divHeight = whObj.h;
s.divWidth = whObj.w;
s.renderObj.reSize(whObj.w * annie.devicePixelRatio, whObj.h * annie.devicePixelRatio);
s.setAlign();
s.dispatchEvent("onResize");
}
}
};
if (annie.debug && !Stage._isLoadedVConsole) {
Stage._isLoadedVConsole = true;
var script_1 = document.createElement("script");
script_1.onload = function () {
new VConsole();
script_1.onload = null;
};
document.head.appendChild(script_1);
script_1.src = "libs/vconsole.min.js";
}
var s = _this;
s.a2x_ua = true;
s.a2x_um = true;
s._instanceType = "annie.Stage";
s.stage = s;
s._isOnStage = true;
s.name = rootDivId;
var div = document.getElementById(rootDivId);
s.renderType = renderType;
s.desWidth = desW;
s.desHeight = desH;
s.rootDiv = div;
s.setFrameRate(frameRate);
s._scaleMode = scaleMode;
s.anchorX = desW >> 1;
s.anchorY = desH >> 1;
//webgl 直到对2d的支持非常成熟了再考虑开启
if (renderType == 0) {
//canvas
s.renderObj = new annie.CanvasRender(s);
}
else {
//webgl
//s.renderObj = new WebGLRender(s);
}
s.renderObj.init(document.createElement('canvas'));
var rc = div;
s.mouseEvent = s._onMouseEvent.bind(s);
rc.addEventListener("mousedown", s.mouseEvent, false);
rc.addEventListener('mousemove', s.mouseEvent, false);
rc.addEventListener('mouseup', s.mouseEvent, false);
rc.addEventListener("touchstart", s.mouseEvent, false);
rc.addEventListener('touchmove', s.mouseEvent, false);
rc.addEventListener('touchend', s.mouseEvent, false);
rc.addEventListener('touchcancel', s.mouseEvent, false);
//同时添加到主更新循环中
Stage.addUpdateObj(s);
return _this;
}
Object.defineProperty(Stage, "pause", {
/**
* 是否暂停
* @property pause
* @static
* @type {boolean}
* @public
* @since 1.0.0
* @default false
*/
get: function () {
return Stage._pause;
},
set: function (value) {
var s = Stage;
if (value != s._pause) {
s._pause = value;
if (value) {
//停止声音
annie.Sound.stopAllSounds();
}
else {
//恢复声音
annie.Sound.resumePlaySounds();
}
//触发事件
annie.globalDispatcher.dispatchEvent("onRunChanged", { pause: value });
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(Stage.prototype, "scaleMode", {
/**
* 舞台的缩放模式
* 默认为空就是无缩放的真实大小
* "noBorder" 无边框模式
* ”showAll" 显示所有内容
* “fixedWidth" 固定宽
* ”fixedHeight" 固定高
* @property scaleMode
* @public
* @since 1.0.0
* @default "onScale"
* @type {string}
* @example
* //动态更改stage的对齐方式示例
* //以下代码放到一个舞台的显示对象的构造函数中
* let s=this;
* s.addEventListener(annie.Event.ADD_TO_STAGE,function(e){
* let i=0;
* s.stage.addEventListener(annie.MouseEvent.CLICK,function(e){
* let aList=[annie.StageScaleMode.EXACT_FIT,annie.StageScaleMode.NO_BORDER,annie.StageScaleMode.NO_SCALE,annie.StageScaleMode.SHOW_ALL,annie.StageScaleMode.FIXED_WIDTH,annie.StageScaleMode.FIXED_HEIGHT]
* let state=e.currentTarget;
* state.scaleMode=aList[i];
* if(i>5){i=0;}
* }
* }
*
*/
get: function () {
return this._scaleMode;
},
set: function (value) {
var s = this;
if (value != s._scaleMode) {
s._scaleMode = value;
s.setAlign();
}
},
enumerable: true,
configurable: true
});
Stage.prototype._render = function (renderObj) {
renderObj.begin(this.bgColor);
_super.prototype._render.call(this, renderObj);
renderObj.end();
};
//刷新mouse或者touch事件
Stage.prototype._initMouseEvent = function (event, cp, sp, identifier, timeStamp) {
event._pd = false;
event.clientX = cp.x;
event.clientY = cp.y;
event.stageX = sp.x;
event.stageY = sp.y;
event.timeStamp = timeStamp;
event.identifier = identifier;
};
//循环刷新页面的函数
Stage.prototype.flush = function () {
var s = this;
//看看是否有resize
if (s._flush == 0) {
s.resize();
s._onUpdateFrame(1);
s._updateMatrix();
s._render(s.renderObj);
}
else {
//将更新和渲染分放到两个不同的时间更新值来执行,这样可以减轻cpu同时执行的压力。
if (s._currentFlush == 0) {
s._currentFlush = s._flush;
s.resize();
}
else {
if (s._currentFlush == s._flush) {
s._onUpdateFrame();
s._updateMatrix();
s._render(s.renderObj);
}
s._currentFlush--;
}
}
};
/**
* 引擎的刷新率,就是一秒中执行多少次刷新
* @method setFrameRate
* @param {number} fps 最好是60的倍数如 1 2 3 6 10 12 15 20 30 60
* @since 1.0.0
* @public
* @return {void}
*/
Stage.prototype.setFrameRate = function (fps) {
var s = this;
s._flush = 60 / fps - 1 >> 0;
if (s._flush < 0) {
s._flush = 0;
}
};
/**
* 引擎的刷新率,就是一秒中执行多少次刷新
* @method getFrameRate
* @since 1.0.0
* @public
* @return {number}
*/
Stage.prototype.getFrameRate = function () {
return 60 / (this._flush + 1);
};
/**
* <h4><font color="red">小游戏不支持 小程序不支持</font></h4>
* 获取引擎所在的div宽高
* @method getRootDivWH
* @public
* @since 1.0.0
* @param {HTMLDivElement} div
* @return {Object}
*/
Stage.prototype.getRootDivWH = function (div) {
var vW = 640;
var vH = 960;
if (div.style.width != "") {
vW = parseInt(div.style.width);
vH = parseInt(div.style.height);
this._isFullScreen = false;
}
else {
this._isFullScreen = true;
vW = document.documentElement.clientWidth;
vH = document.documentElement.clientHeight;
}
return { w: vW, h: vH };
};
Stage.prototype._onMouseEvent = function (e) {
//检查是否有
var s = this, c = s.renderObj.rootContainer, offSetX = 0, offSetY = 0;
if (e.target.id == "_a2x_canvas") {
s._isMouseClickCanvas = true;
if (s.isPreventDefaultEvent) {
if ((e.type == "touchend") && (annie.osType == "ios") && (s.iosTouchendPreventDefault)) {
e.preventDefault();
}
if ((e.type == "touchmove") || (e.type == "touchstart" && annie.osType == "android")) {
e.preventDefault();
}
}
}
else {
s._isMouseClickCanvas = false;
}
if (!s._isFullScreen) {
offSetX = c.getBoundingClientRect().left + c.scrollLeft;
offSetY = c.getBoundingClientRect().top + c.scrollTop;
}
var sd = Stage._dragDisplay;
if (s.isMultiTouch && e.targetTouches && e.targetTouches.length > 1) {
if (e.targetTouches.length == 2) {
//求角度和距离
s._mP1.x = e.targetTouches[0].clientX - offSetX;
s._mP1.y = e.targetTouches[0].clientY - offSetY;
s._mP2.x = e.targetTouches[1].clientX - offSetX;
s._mP2.y = e.targetTouches[1].clientY - offSetY;
var angle = Math.atan2(s._mP1.y - s._mP2.y, s._mP1.x - s._mP2.x) / Math.PI * 180;
var dis = annie.Point.distance(s._mP1, s._mP2);
s.muliPoints.push({ p1: s._mP1, p2: s._mP2, angle: angle, dis: dis });
if (s.muliPoints.length >= 2) {
//如果有事件,抛事件
if (!(s._touchEvent instanceof annie.TouchEvent)) {
s._touchEvent = new annie.TouchEvent(annie.TouchEvent.ON_MULTI_TOUCH);
s._touchEvent.target = s;
}
var len = s.muliPoints.length;
s._touchEvent.rotate = (s.muliPoints[len - 1].angle - s.muliPoints[len - 2].angle) * 2;
s._touchEvent.scale = (s.muliPoints[len - 1].dis - s.muliPoints[len - 2].dis) / (s.divHeight > s.divWidth ? s.desWidth : s.desHeight) * 4;
s._touchEvent.clientPoint1.x = s.muliPoints[len - 1].p1.x * annie.devicePixelRatio;
s._touchEvent.clientPoint2.x = s.muliPoints[len - 1].p2.x * annie.devicePixelRatio;
s._touchEvent.clientPoint1.y = s.muliPoints[len - 1].p1.y * annie.devicePixelRatio;
s._touchEvent.clientPoint2.y = s.muliPoints[len - 1].p2.y * annie.devicePixelRatio;
s.dispatchEvent(s._touchEvent);
s.muliPoints.shift();
}
}
else {
s.muliPoints.length = 0;
}
s._mouseDownPoint = {};
s._lastDpList = {};
if (sd) {
Stage._lastDragPoint.x = Number.MAX_VALUE;
Stage._lastDragPoint.y = Number.MAX_VALUE;
}
}
else {
if (s.muliPoints.length > 0) {
s._touchEvent.rotate = 0;
s._touchEvent.scale = 0;
s._touchEvent.clientPoint1.x = 0;
s._touchEvent.clientPoint2.x = 0;
s._touchEvent.clientPoint1.y = 0;
s._touchEvent.clientPoint2.y = 0;
s.dispatchEvent(s._touchEvent);
s.muliPoints.length = 0;
}
//检查mouse或touch事件是否有,如果有的话,就触发事件函数
if (annie.EventDispatcher._totalMEC > 0) {
var points = void 0;
var item = s._mouseEventTypes[e.type];
var events = [];
var event_1;
//clientPoint
var cp = void 0;
//事件个数
var eLen = void 0;
var identifier = void 0;
if (!e.changedTouches) {
e.identifier = "pc0";
points = [e];
}
else {
if (s.isMultiMouse) {
points = e.changedTouches;
}
else {
var fp = e.changedTouches[0];
if ((s._lastDpList[fp.identifier] != void 0) || (item == "onMouseDown" && !s._lastDpList.isStart)) {
s._lastDpList.isStart = true;
points = [fp];
}
else {
return;
}
}
}
var pLen = points.length;
for (var o = 0; o < pLen; o++) {
eLen = 0;
events.length = 0;
identifier = points[o].identifier;
if (s._mp.length > 0) {
cp = s._mp.shift();
}
else {
cp = new annie.Point();
}
cp.x = (points[o].clientX - offSetX) * annie.devicePixelRatio;
cp.y = (points[o].clientY - offSetY) * annie.devicePixelRatio;
s.globalToLocal(cp, s.sp);
if (sd && sd.stage && sd.parent) {
var x1 = sd.x, y1 = sd.y;
sd.parent.globalToLocal(cp, s.lp);
if (!Stage._isDragCenter) {
if (Stage._lastDragPoint.x != Number.MAX_VALUE) {
x1 += s.lp.x - Stage._lastDragPoint.x;
y1 += s.lp.y - Stage._lastDragPoint.y;
}
Stage._lastDragPoint.x = s.lp.x;
Stage._lastDragPoint.y = s.lp.y;
}
else {
x1 = s.lp.x;
y1 = s.lp.y;
}
s.lp.x = x1;
s.lp.y = y1;
if (Stage._dragBounds.width != Number.MIN_VALUE) {
if (x1 < Stage._dragBounds.x) {
x1 = Stage._dragBounds.x;
}
else if (x1 > Stage._dragBounds.x + Stage._dragBounds.width) {
x1 = Stage._dragBounds.x + Stage._dragBounds.width;
}
if (y1 < Stage._dragBounds.y) {
y1 = Stage._dragBounds.y;
}
else if (y1 > Stage._dragBounds.y + Stage._dragBounds.height) {
y1 = Stage._dragBounds.y + Stage._dragBounds.height;
}
}
sd.x = x1;
sd.y = y1;
}
if (s._ml[eLen] instanceof annie.MouseEvent) {
event_1 = s._ml[eLen];
event_1.type = item;
}
else {
event_1 = new annie.MouseEvent(item);
s._ml[eLen] = event_1;
}
events[events.length] = event_1;
s._initMouseEvent(event_1, cp, s.sp, identifier, e.timeStamp);
eLen++;
if (item == "onMouseDown") {
s._mouseDownPoint[identifier] = cp;
//清空上次存在的显示列表
}
else if (item == "onMouseUp") {
if (s._mouseDownPoint[identifier] instanceof annie.Point) {
if (annie.Point.distance(s._mouseDownPoint[identifier], cp) < 20) {
//click事件
//这个地方检查是所有显示对象列表里是否有添加对应的事件
if (annie.EventDispatcher.getMouseEventCount("onMouseClick") > 0) {
if (s._ml[eLen] instanceof annie.MouseEvent) {
event_1 = s._ml[eLen];
event_1.type = "onMouseClick";
}
else {
event_1 = new annie.MouseEvent("onMouseClick");
s._ml[eLen] = event_1;
}
events[events.length] = event_1;
s._initMouseEvent(event_1, cp, s.sp, identifier);
eLen++;
}
}
}
}
if (eLen > 0) {
//证明有事件那么就开始遍历显示列表。就算有多个事件也不怕,因为坐标点相同,所以只需要遍历一次
var d_1 = s.hitTestPoint(cp, true);
var displayList = [];
if (d_1 instanceof annie.DisplayObject) {
//证明有点击到事件,然后从最底层追上来,看看一路是否有人添加过mouse或touch事件,还要考虑mousechildren和阻止事件方法
//找出真正的target,因为有些父级可能会mouseChildren=false;
do {
if (d_1 instanceof annie.Sprite && d_1.mouseChildren == false) {
//丢掉之前的层级,因为根本没用了
displayList.length = 0;
}
displayList[displayList.length] = d_1;
d_1 = d_1.parent;
} while (d_1 instanceof annie.DisplayObject);
}
else {
displayList[0] = s;
}
var len = displayList.length;
for (var i = len - 1; i >= 0; i--) {
d_1 = displayList[i];
for (var j = 0; j < eLen; j++) {
if (!events[j]._pd && d_1.hasEventListener(events[j].type)) {
events[j].currentTarget = d_1;
events[j].target = displayList[0];
d_1.globalToLocal(cp, s.lp);
events[j].localX = s.lp.x;
events[j].localY = s.lp.y;
d_1.dispatchEvent(events[j]);
}
}
}
//这里一定要反转一下,因为会影响mouseOut mouseOver
displayList.reverse();
for (var i = len - 1; i >= 0; i--) {
d_1 = displayList[i];
for (var j = 0; j < eLen; j++) {
if (!events[j]._pd && d_1.hasEventListener(events[j].type, false)) {
events[j].currentTarget = d_1;
events[j].target = displayList[eLen - 1];
d_1.globalToLocal(cp, s.lp);
events[j].localX = s.lp.x;
events[j].localY = s.lp.y;
d_1.dispatchEvent(events[j], null, false);
}
}
}
//最后要和上一次的遍历者对比下,如果不相同则要触发onMouseOver和onMouseOut
if (item != "onMouseDown") {
if (annie.EventDispatcher.getMouseEventCount("onMouseOver") > 0 || annie.EventDispatcher.getMouseEventCount("onMouseOut") > 0) {
if (s._lastDpList[identifier] instanceof Array) {
//从第二个开始,因为第一个对象始终是stage顶级对象
var len1 = s._lastDpList[identifier].length;
var len2 = displayList.length;
len = len1 > len2 ? len1 : len2;
var isDiff = false;
var overEvent = void 0;
var outEvent = void 0;
for (var i = 1; i < len; i++) {
if (!isDiff) {
if (s._lastDpList[identifier][i] != displayList[i]) {
//好就是这里,需要确定哪些有onMouseOver,哪些有onMouseOut
isDiff = true;
if (s._ml[eLen] instanceof annie.MouseEvent) {
overEvent = s._ml[eLen];
overEvent.type = "onMouseOver";
}
else {
overEvent = new annie.MouseEvent("onMouseOver");
s._ml[eLen] = overEvent;
}
s._initMouseEvent(overEvent, cp, s.sp, identifier);
eLen++;
if (s._ml[eLen] instanceof annie.MouseEvent) {
outEvent = s._ml[eLen];
outEvent.type = "onMouseOut";
}
else {
outEvent = new annie.MouseEvent("onMouseOut");
s._ml[eLen] = outEvent;
}
s._initMouseEvent(outEvent, cp, s.sp, identifier);
}
}
if (isDiff) {
if (s._lastDpList[identifier][i]) {
//触发onMouseOut事件
d_1 = s._lastDpList[identifier][i];
if (!outEvent._pd && d_1.hasEventListener("onMouseOut")) {
outEvent.currentTarget = d_1;
outEvent.target = s._lastDpList[identifier][len1 - 1];
d_1.globalToLocal(cp, s.lp);
outEvent.localX = s.lp.x;
outEvent.localY = s.lp.y;
d_1.dispatchEvent(outEvent);
}
}
d_1 = displayList[i];
if (d_1 instanceof annie.DisplayObject) {
//触发onMouseOver事件
if (!overEvent._pd && d_1.hasEventListener("onMouseOver")) {
overEvent.currentTarget = d_1;
overEvent.target = displayList[len2 - 1];
d_1.globalToLocal(cp, s.lp);
overEvent.localX = s.lp.x;
overEvent.localY = s.lp.y;
d_1.dispatchEvent(overEvent);
}
}
}
}
}
}
s._mp[s._mp.length] = cp;
}
if (item == "onMouseUp") {
delete s._mouseDownPoint[identifier];
delete s._lastDpList[identifier];
s._lastDpList.isStart = false;
if (sd) {
Stage._lastDragPoint.x = Number.MAX_VALUE;
Stage._lastDragPoint.y = Number.MAX_VALUE;
}
}
else {
s._lastDpList[identifier] = displayList;
}
}
}
}
}
};
;
//设置舞台的对齐模式
Stage.prototype.setAlign = function () {
var s = this;
var divH = s.divHeight * annie.devicePixelRatio;
var divW = s.divWidth * annie.devicePixelRatio;
var desH = s.desHeight;
var desW = s.desWidth;
s.anchorX = desW >> 1;
s.anchorY = desH >> 1;
//设备是否为竖屏
var isDivH = divH >= divW;
//内容是否为竖屏内容
var isDesH = desH >= desW;
var scaleY = 1;
var scaleX = 1;
s.x = (divW - desW) >> 1;
s.y = (divH - desH) >> 1;
if (s.autoSteering) {
if (isDesH != isDivH) {
var d_2 = divH;
divH = divW;
divW = d_2;
}
}
if (s._scaleMode != "noScale") {
scaleY = divH / desH;
scaleX = divW / desW;
switch (s._scaleMode) {
case "noBorder":
if (scaleX > scaleY) {
scaleY = scaleX;
}
else {
scaleX = scaleY;
}
break;
case "showAll":
if (scaleX < scaleY) {
scaleY = scaleX;
}
else {
scaleX = scaleY;
}
break;
case "fixedWidth":
scaleY = scaleX;
break;
case "fixedHeight":
scaleX = scaleY;
break;
}
}
s.scaleX = scaleX;
s.scaleY = scaleY;
if (s.autoSteering) {
if (isDesH == isDivH) {
s.rotation = 0;
}
else {
if (desH > desW) {
s.rotation = -90;
}
else {
s.rotation = 90;
}
}
}
else {
s.rotation = 0;
}
s._viewRect.x = (desW - divW / scaleX) >> 1;
s._viewRect.y = (desH - divH / scaleY) >> 1;
s._viewRect.width = desW - s._viewRect.x * 2;
s._viewRect.height = desH - s._viewRect.y * 2;
};
;
Object.defineProperty(Stage.prototype, "viewRect", {
/**
* 舞台在设备里截取后的可见区域,有些时候知道可见区域是非常重要的,因为这样你就可以根据舞台的可见区域做自适应了。
* @property viewRect
* @public
* @readonly
* @since 1.0.0
* @type {annie.Rectangle}
* @default {x:0,y:0,width:0,height:0}
* @readonly
* @example
* //始终让一个对象顶对齐,或者
*/
get: function () {
return this._viewRect;
},
enumerable: true,
configurable: true
});
//刷新所有定时器
Stage.flushAll = function () {
if (!Stage._pause) {
var len = Stage.allUpdateObjList.length;
for (var i = len - 1; i >= 0; i--) {
Stage.allUpdateObjList[i] && Stage.allUpdateObjList[i].flush();
}
}
requestAnimationFrame(Stage.flushAll);
};
/**
* 添加一个刷新对象,这个对象里一定要有一个 flush 函数。
* 因为一但添加,这个对象的 flush 函数会以stage的fps间隔调用
* 如,你的stage是30fps 那么你这个对象的 flush 函数1秒会调用30次。
* @method addUpdateObj
* @param target 要循化调用 flush 函数的对象
* @public
* @static
* @since
* @return {void}
*/
Stage.addUpdateObj = function (target) {
var isHave = false;
var len = Stage.allUpdateObjList.length;
for (var i = 0; i < len; i++) {
if (Stage.allUpdateObjList[i] == target) {
isHave = true;
break;
}
}
if (!isHave) {
Stage.allUpdateObjList.unshift(target);
}
};
/**
* 移除掉已经添加的循环刷新对象
* @method removeUpdateObj
* @param target
* @public
* @static
* @since 1.0.0
* @return {void}
*/
Stage.removeUpdateObj = function (target) {
var len = Stage.allUpdateObjList.length;
for (var i = 0; i < len; i++) {
if (Stage.allUpdateObjList[i] == target) {
Stage.allUpdateObjList.splice(i, 1);
break;
}
}
};
Stage.prototype.destroy = function () {
_super.prototype.destroy.call(this);
var s = this;
Stage.removeUpdateObj(s);
var rc = s.rootDiv;
if (annie.osType != "pc") {
rc.removeEventListener("touchstart", s.mouseEvent, false);
rc.removeEventListener('touchmove', s.mouseEvent, false);
rc.removeEventListener('touchend', s.mouseEvent, false);
rc.removeEventListener('touchcancel', s.mouseEvent, false);
}
else {
rc.removeEventListener("mousedown", s.mouseEvent, false);
rc.removeEventListener('mousemove', s.mouseEvent, false);
rc.removeEventListener('mouseup', s.mouseEvent, false);
}
rc.style.display = "none";
if (rc.parentNode) {
rc.parentNode.removeChild(rc);
}
s.renderObj = null;
};
Stage._pause = false;
Stage._isLoadedVConsole = false;
Stage._dragDisplay = null;
Stage._dragBounds = new annie.Rectangle();
Stage._lastDragPoint = new annie.Point();
Stage._isDragCenter = false;
/**
* 要循环调用 flush 函数对象列表
* @method allUpdateObjList
* @static
* @since 1.0.0
* @type {Array}
*/
Stage.allUpdateObjList = [];
return Stage;
}(annie.Sprite));
annie.Stage = Stage;
})(annie || (annie = {}));