var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
/**
* @module annieUI
*/
var annieUI;
(function (annieUI) {
/**
* 滚动视图,有些时候你的内容超过了一屏,需要上下或者左右滑动来查看内容,这个时候,你就应该用它了
* @class annieUI.Scroller
* @public
* @extends annie.AObject
* @since 3.1.0
*/
var Scroller = (function (_super) {
__extends(Scroller, _super);
/**
* 初始化
* @method Scroller
* @param {annie.MovieClip} container
* @param {number} viewWidth
* @param {number} viewHeight
* @param {number} scrollWidth
* @param {number} scrollHeight
*/
function Scroller(container, viewWidth, viewHeight, scrollWidth, scrollHeight) {
_super.call(this);
/**
* 是否纵向滚动
* @property isScrollY
* @type {boolean}
* @public
* @since 3.1.5
* @default true;
*/
this.isScrollY = true;
/**
* 是否横向滚动
* @property isScrollX
* @type {boolean}
* @since 3.1.5
* @public
* @default true;
*/
this.isScrollX = true;
/**
* 是否松开鼠标后让其自由缓冲滑动
* @property isMomentum
* @type {boolean}
* @since 3.1.5
* @public
* @default true;
*/
this.isMomentum = true;
/**
* 是否滑到边界后有回弹效果
* @property isBounce
* @type {boolean}
* @since 3.1.5
* @public
* @default true;
*/
this.isBounce = true;
/**
* 回弹的动效时长,单位:ms
* @property bounceTime
* @type {number}
* @public
* @since 3.1.5
* @default 300
*/
this.bounceTime = 300;
/**
* 是否需要横向纵向保护,有些时候你想纵向滑动,但鼠标也轻微的左右飘了,如果不lock刚好左右滑动也被允许的话,则左右也会滑动,横向滑动则相反。
* 如果想鼠标不那么灵敏的话,可以加上一把锁,这样左右滑的时候上下不会滑,上下滑的时候左右不会滑
* @property isLocked
* @type {boolean}
* @public
* @since 3.1.5
* @default 300
*/
this.isLocked = true;
/**
* 锁的像素范围
* @property lockDis
* @type {number}
* @since 3.1.5
* @public
* @default 5
*/
this.lockDis = 5;
this._curX = 0;
this._curY = 0;
this._viewWidth = 0;
this._viewHeight = 0;
this._scrollWidth = 0;
this._scrollHeight = 0;
this.startX = 0;
this.startY = 0;
this.maxScrollX = 0;
this.maxScrollY = 0;
this.endTime = 0;
this.mouseStatus = 0;
this.distX = 0;
this.distY = 0;
this.startTime = 0;
this.absStartX = 0;
this.absStartY = 0;
this.pointX = 0;
this.pointY = 0;
/**
* 滑动衰减系数,值越大衰减越快
* @property deceleration
* @type {number}
* @public
* @since 3.2.1
* @default 0.0006
*/
this.deceleration = 0.0006;
this.destTime = 0;
this.destX = 0;
this.destY = 0;
this.duration = 0;
this._mouseEvent = null;
this._enterFrame = null;
var s = this;
s._instanceType = "annieUI.Scroller";
s._mouseEvent = s.onMouseEvent.bind(s);
s._enterFrame = s.onEnterFrame.bind(s);
s.init(container, viewWidth, viewHeight, scrollWidth, scrollHeight);
}
Object.defineProperty(Scroller.prototype, "curX", {
/**
* 当前滑动的x坐标 更改此参数则需要调用resetPosition()方法生效
* @property curX
* @type {number}
* @since 3.1.5
* @default 0
*/
get: function () {
return this._curX;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Scroller.prototype, "curY", {
/**
* 当前滑动的y坐标 更改此参数则需要调用resetPosition()方法生效
* @property curY
* @type {number}
* @since 3.1.5
* @default 0
*/
get: function () {
return this._curY;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Scroller.prototype, "viewWidth", {
/**
* 当前显示范围的宽
* @property viewWidth
* @type {number}
* @since 3.1.5
* @default 0
* @readonly
*/
get: function () {
return this._viewWidth;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Scroller.prototype, "viewHeight", {
/**
* 当前显示范围的高
* @property viewHeight
* @type {number}
* @since 3.1.5
* @default 0
* @readonly
*/
get: function () {
return this._viewHeight;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Scroller.prototype, "scrollWidth", {
/**
* 当前横向的滑动范围
* @property scrollWidth
* @type {number}
* @since 3.1.5
* @default 0
* @readonly
*/
get: function () {
return this._scrollWidth;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Scroller.prototype, "scrollHeight", {
/**
* 当前纵向的滑动范围
* @property scrollHeight
* @type {number}
* @since 3.1.5
* @default 0
* @readonly
*/
get: function () {
return this._scrollHeight;
},
enumerable: true,
configurable: true
});
/**
* 初始化,也可以反复调用此方法重用scroller
* @method init
* @param {annie.MovieClip} container
* @param {number} viewWidth
* @param {number} viewHeight
* @param {number} scrollWidth
* @param {number} scrollHeight
* @public
* @since 3.1.5
*/
Scroller.prototype.init = function (container, viewWidth, viewHeight, scrollWidth, scrollHeight) {
var s = this;
if (s._container && s._container != container) {
//移除
s._container.removeEventListener(annie.MouseEvent.MOUSE_DOWN, s._mouseEvent, false);
s._container.removeEventListener(annie.MouseEvent.MOUSE_MOVE, s._mouseEvent, false);
s._container.removeEventListener(annie.MouseEvent.MOUSE_UP, s._mouseEvent, false);
s._container.removeEventListener(annie.MouseEvent.MOUSE_OUT, s._mouseEvent);
s._container.removeEventListener(annie.Event.ENTER_FRAME, s._enterFrame);
}
if (s._container != container) {
s._container = container;
container.addEventListener(annie.MouseEvent.MOUSE_DOWN, s._mouseEvent, false);
container.addEventListener(annie.MouseEvent.MOUSE_MOVE, s._mouseEvent, false);
container.addEventListener(annie.MouseEvent.MOUSE_UP, s._mouseEvent, false);
container.addEventListener(annie.MouseEvent.MOUSE_OUT, s._mouseEvent);
container.addEventListener(annie.Event.ENTER_FRAME, s._enterFrame);
}
s.isRunning = false;
s.endTime = 0;
s.setViewWHAndScrollWH(viewWidth, viewHeight, scrollWidth, scrollHeight);
};
/**
* 当更改了viewWidth,viewHeight其中一个或两个同时也更改了scrollWidth,scrollHeight其中的一个或者两个
* 需要调用此方法重置,如果只是单方面更改了viewWidth,viewHeight其中一个或两个,则可以调用setViewWH()
* 如果只是更改了scrollWidth,scrollHeight其中的一个或者两个,则可以调用setScrollWH()
* @method setViewWHAndScrollWH
* @public
* @since 3.1.5
* @param {number} viewWidth
* @param {number} viewHeight
* @param {number} scrollWidth
* @param {number} scrollHeight
*/
Scroller.prototype.setViewWHAndScrollWH = function (viewWidth, viewHeight, scrollWidth, scrollHeight) {
var s = this;
s._viewHeight = viewHeight;
s._viewWidth = viewWidth;
s._scrollWidth = scrollWidth;
s._scrollHeight = scrollHeight;
s._updateViewAndScroll();
};
/**
* 当更改了viewWidth,viewHeight其中一个或两个,需要调用此方法重置.
* @method setViewWH
* @public
* @since 3.1.5
* @param {number} viewWidth
* @param {number} viewHeight
*/
Scroller.prototype.setViewWH = function (viewWidth, viewHeight) {
var s = this;
s._viewHeight = viewHeight;
s._viewWidth = viewWidth;
s._updateViewAndScroll();
};
/**
* 当更改了scrollWidth,scrollHeight其中的一个或者两个,需要调用此方法重置.
* @method setScrollWH
* @public
* @since 3.1.5
* @param {number} scrollWidth
* @param {number} scrollHeight
*/
Scroller.prototype.setScrollWH = function (scrollWidth, scrollHeight) {
var s = this;
s._scrollWidth = scrollWidth;
s._scrollHeight = scrollHeight;
s._updateViewAndScroll();
};
Scroller.prototype._updateViewAndScroll = function () {
var s = this;
s.maxScrollX = s.viewWidth - s.scrollWidth;
s.maxScrollY = s.viewHeight - s.scrollHeight;
if (s.maxScrollX > 0) {
s.maxScrollX = 0;
}
if (s.maxScrollY > 0) {
s.maxScrollY = 0;
}
if (!s.isScrollX) {
s.maxScrollX = 0;
s._scrollWidth = s.viewWidth;
}
if (!s.isScrollY) {
s.maxScrollY = 0;
s._scrollHeight = s.viewHeight;
}
s.resetPosition(200);
};
Scroller.prototype.onEnterFrame = function (e) {
var s = this;
if (s.isRunning) {
var now = Date.now(), newX = void 0, newY = void 0, easing = void 0;
if (now >= s.destTime) {
s.isRunning = false;
s._translate(s.destX, s.destY);
if (!s.resetPosition(s.bounceTime)) {
s.dispatchEvent(annie.Event.ON_SCROLL_STOP);
if (s._curX == 0 && s._curY == 0) {
s.dispatchEvent(annie.Event.ON_SCROLL_TO_HEAD);
}
else if (s._curX == s.maxScrollX && s._curY == s.maxScrollY) {
s.dispatchEvent(annie.Event.ON_SCROLL_TO_END);
}
}
}
else {
now = (now - s.startTime) / s.duration;
easing = s.easingFn(now);
newX = (s.destX - s.startX) * easing + s.startX;
newY = (s.destY - s.startY) * easing + s.startY;
s._translate(newX, newY);
}
}
};
Scroller.prototype.onMouseEvent = function (e) {
var s = this;
if (e.type == annie.MouseEvent.MOUSE_DOWN) {
s.isRunning = false;
s.mouseStatus = 1;
s.distX = 0;
s.distY = 0;
s.startTime = Date.now();
s.startX = s._curX;
s.startY = s._curY;
s.absStartX = s._curX;
s.absStartY = s._curY;
s.pointX = e.localX;
s.pointY = e.localY;
}
else if (e.type == annie.MouseEvent.MOUSE_MOVE) {
if (s.mouseStatus < 1) {
return;
}
var deltaX = e.localX - s.pointX, deltaY = e.localY - s.pointY, timestamp = Date.now(), newX = void 0, newY = void 0, absDistX = void 0, absDistY = void 0;
s.pointX = e.localX;
s.pointY = e.localY;
s.distX += deltaX;
s.distY += deltaY;
absDistX = Math.abs(s.distX);
absDistY = Math.abs(s.distY);
if (timestamp - s.endTime > 300 && (absDistX < 10 && absDistY < 10)) {
return;
}
if (s.isLocked) {
if (absDistX > absDistY + s.lockDis) {
deltaY = 0;
}
else if (absDistY >= absDistX + s.lockDis) {
deltaX = 0;
}
}
deltaX = s.isScrollX ? deltaX : 0;
deltaY = s.isScrollY ? deltaY : 0;
newX = s._curX + deltaX;
newY = s._curY + deltaY;
if (newX > 0 || newX < s.maxScrollX) {
newX = s.isBounce ? s._curX + deltaX / 3 : newX > 0 ? 0 : s.maxScrollX;
}
if (newY > 0 || newY < s.maxScrollY) {
newY = s.isBounce ? s._curY + deltaY / 3 : newY > 0 ? 0 : s.maxScrollY;
}
if (s.mouseStatus == 1) {
s.dispatchEvent(annie.Event.ON_SCROLL_START);
}
s.mouseStatus = 2;
s._translate(newX, newY);
if (timestamp - s.startTime > 300) {
s.startTime = timestamp;
s.startX = s._curX;
s.startY = s._curY;
}
}
else {
s.endTime = Date.now();
var momentumX = void 0, momentumY = void 0, duration = s.endTime - s.startTime, newX = s._curX, newY = s._curY, time = 0, easing = null;
if (s.resetPosition(s.bounceTime)) {
s.mouseStatus = 0;
return;
}
if (s.mouseStatus != 2) {
s.mouseStatus = 0;
return;
}
s.mouseStatus = 0;
s.scrollTo(newX, newY);
if (s.isMomentum && duration < 300) {
momentumX = s.isScrollX ? Scroller.toMomentum(s._curX, s.startX, duration, s.maxScrollX, s.isBounce ? s.viewWidth / 2 : 0, s.deceleration) : {
destination: newX,
duration: 0
};
momentumY = s.isScrollY ? Scroller.toMomentum(s._curY, s.startY, duration, s.maxScrollY, s.isBounce ? s.viewHeight / 2 : 0, s.deceleration) : {
destination: newY,
duration: 0
};
newX = momentumX.destination;
newY = momentumY.destination;
time = Math.max(momentumX.duration, momentumY.duration);
}
if (newX != s._curX || newY != s._curY) {
if (newX > 0 || newX < s.maxScrollX || newY > 0 || newY < s.maxScrollY) {
easing = annie.Tween.quadraticOut;
}
s.scrollTo(newX, newY, time, easing);
return;
}
s.dispatchEvent(annie.Event.ON_SCROLL_STOP);
}
};
Scroller.prototype.destroy = function () {
var s = this;
if (s._container) {
s._container.removeEventListener(annie.MouseEvent.MOUSE_MOVE, s._mouseEvent, false);
s._container.removeEventListener(annie.MouseEvent.MOUSE_DOWN, s._mouseEvent, false);
s._container.removeEventListener(annie.MouseEvent.MOUSE_UP, s._mouseEvent, false);
s._container.removeEventListener(annie.MouseEvent.MOUSE_OUT, s._mouseEvent);
s._container.removeEventListener(annie.Event.ENTER_FRAME, s._enterFrame);
}
s._container = null;
s.easingFn = null;
_super.prototype.destroy.call(this);
};
Scroller.prototype.resetPosition = function (time) {
if (time === void 0) { time = 0; }
var s = this;
var x = s._curX, y = s._curY;
time = time || 0;
if (!s.isScrollX || s._curX > 0) {
x = 0;
}
else if (s._curX < s.maxScrollX) {
x = s.maxScrollX;
}
if (!s.isScrollY || s._curY > 0) {
y = 0;
}
else if (s._curY < s.maxScrollY) {
y = s.maxScrollY;
}
if (x == s._curX && y == s._curY) {
return false;
}
s.scrollTo(x, y, time, null);
return true;
};
/**
* 从设置的x,y坐标滑过来。 注意x y位置是负数,想想为什么
* @method scrollBy
* @param {number} x 从哪个x坐标滑过来
* @param {number} y 从哪个y坐标滑过来
* @param {number} time 滑动时长 ms,0的话没效果直接跳
* @param {Function} easing annie.Tween中指定的缓存方法
* @public
* @since 3.1.5
*/
Scroller.prototype.scrollBy = function (x, y, time, easing) {
if (time === void 0) { time = 0; }
if (easing === void 0) { easing = null; }
var s = this;
x = s._curX + x;
y = s._curY + y;
time = time || 0;
s.scrollTo(x, y, time, easing);
};
/**
* 滑动到设置的x,y坐标。 注意x y位置是负数,想想为什么
* @method scrollTo
* @param {number} x 要滑去的x坐标
* @param {number} y 要滑去的y坐标
* @param {number} time 滑动时长 ms,0的话没效果直接跳
* @param {Function} easing annie.Tween中指定的缓存方法
* @public
* @since 3.1.5
*/
Scroller.prototype.scrollTo = function (x, y, time, easing) {
if (time === void 0) { time = 0; }
if (easing === void 0) { easing = null; }
var s = this;
if (!time) {
s._translate(x, y);
}
else {
easing = easing || annie.Tween.circularOut;
s.startX = s._curX;
s.startY = s._curY;
s.startTime = Date.now();
s.destTime = s.startTime + time;
s.destX = x;
s.destY = y;
s.duration = time;
s.easingFn = easing;
s.isRunning = true;
}
};
Scroller.prototype._translate = function (x, y) {
var s = this;
if (x != Number.NaN && this.isScrollX) {
s._curX = x;
}
if (y != Number.NaN && this.isScrollY) {
s._curY = y;
}
s.dispatchEvent(annie.Event.ON_SCROLL_ING, { posX: s._curX, posY: s._curY });
};
Scroller.toMomentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) {
var distance = current - start, speed = Math.abs(distance) / time, destination, duration;
deceleration = deceleration === undefined ? 0.0006 : deceleration;
destination = current + (speed * speed) / (2 * deceleration) * (distance < 0 ? -1 : 1);
duration = speed / deceleration;
if (destination < lowerMargin) {
destination = wrapperSize ? lowerMargin - (wrapperSize / 2.5 * (speed / 8)) : lowerMargin;
distance = Math.abs(destination - current);
duration = distance / speed;
}
else if (destination > 0) {
destination = wrapperSize ? wrapperSize / 2.5 * (speed / 8) : 0;
distance = Math.abs(current) + destination;
duration = distance / speed;
}
return {
destination: destination,
duration: duration
};
};
;
return Scroller;
}(annie.EventDispatcher));
annieUI.Scroller = Scroller;
})(annieUI || (annieUI = {}));