zoomla
Version:
16年专业研发|中文alexa排名第一的CMS品牌-基于dotNET core、功能强大,集成站群、微信开发、小程序与ERP及OA办公系统,支持国际语言和多民族语言,世界五百强与大型门户专用高端网站内核CMS系统
1,331 lines (1,293 loc) • 233 kB
JavaScript
/*!
* ====================================================
* kity - v2.0.0 - 2014-06-16
* https://github.com/fex-team/kity
* GitHub: https://github.com/fex-team/kity.git
* Copyright (c) 2014 Baidu FEX; Licensed BSD
* ====================================================
*/
(function () {
/**
* cmd 内部定义
*/
// 模块存储
var _modules = {};
function define ( id, deps, factory ) {
_modules[ id ] = {
exports: {},
value: null,
factory: null
};
if ( arguments.length === 2 ) {
factory = deps;
}
if ( _modules.toString.call( factory ) === '[object Object]' ) {
_modules[ id ][ 'value' ] = factory;
} else if ( typeof factory === 'function' ) {
_modules[ id ][ 'factory' ] = factory;
} else {
throw new Error( 'define函数未定义的行为' );
}
}
function require ( id ) {
var module = _modules[ id ],
exports = null;
if ( !module ) {
return null;
}
if ( module.value ) {
return module.value;
}
exports = module.factory.call( null, require, module.exports, module );
// return 值不为空, 则以return值为最终值
if ( exports ) {
module.exports = exports;
}
module.value = module.exports;
return module.value;
}
function use ( id ) {
return require( id );
}
define("animate/animator", [ "animate/timeline", "graphic/eventhandler", "animate/frame", "core/utils", "core/class", "animate/easing", "graphic/shape", "graphic/svg", "graphic/styled", "graphic/data", "graphic/matrix", "graphic/pen", "graphic/box" ], function(require) {
function parseTime(str) {
var value = parseFloat(str, 10);
if (/ms/.test(str)) {
return value;
}
if (/s/.test(str)) {
return value * 1e3;
}
if (/min/.test(str)) {
return value * 60 * 1e3;
}
return value;
}
var Timeline = require("animate/timeline");
var easingTable = require("animate/easing");
var Animator = require("core/class").createClass("Animator", {
constructor: function(beginValue, finishValue, setter) {
if (arguments.length == 1) {
var opt = arguments[0];
this.beginValue = opt.beginValue;
this.finishValue = opt.finishValue;
this.setter = opt.setter;
} else {
this.beginValue = beginValue;
this.finishValue = finishValue;
this.setter = setter;
}
},
start: function(target, duration, easing, delay, callback) {
if (arguments.length === 4 && typeof delay == "function") {
callback = delay;
delay = 0;
}
var timeline = this.create(target, duration, easing, callback);
delay = parseTime(delay);
if (delay > 0) {
setTimeout(function() {
timeline.play();
}, delay);
} else {
timeline.play();
}
return timeline;
},
create: function(target, duration, easing, callback) {
var timeline;
duration = duration && parseTime(duration) || Animator.DEFAULT_DURATION;
easing = easing || Animator.DEFAULT_EASING;
if (typeof easing == "string") {
easing = easingTable[easing];
}
timeline = new Timeline(this, target, duration, easing);
if (typeof callback == "function") {
timeline.on("finish", callback);
}
return timeline;
},
reverse: function() {
return new Animator(this.finishValue, this.beginValue, this.setter);
}
});
Animator.DEFAULT_DURATION = 300;
Animator.DEFAULT_EASING = "linear";
var Shape = require("graphic/shape");
require("core/class").extendClass(Shape, {
animate: function(animator, duration, easing, delay, callback) {
var queue = this._KityAnimateQueue = this._KityAnimateQueue || [];
var timeline = animator.create(this, duration, easing, callback);
function dequeue() {
queue.shift();
if (queue.length) {
setTimeout(queue[0].t.play.bind(queue[0].t), queue[0].d);
}
}
timeline.on("finish", dequeue);
queue.push({
t: timeline,
d: delay
});
if (queue.length == 1) {
setTimeout(timeline.play.bind(timeline), delay);
}
return this;
},
timeline: function() {
return this._KityAnimateQueue[0].t;
},
stop: function() {
var queue = this._KityAnimateQueue;
if (queue) {
while (queue.length) {
queue.shift().stop();
}
}
}
});
return Animator;
});
/**
* Kity Animate Easing modified from jQuery Easing
* Author: techird
* Changes:
* 1. make easing functions standalone
* 2. remove the 'x' parameter
*/
/* ============================================================
* jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
*
* Open source under the BSD License.
*
* Copyright © 2008 George McGinley Smith
* All rights reserved.
* https://raw.github.com/danro/jquery-easing/master/LICENSE
* ======================================================== */
define("animate/easing", [], function(require, exports, module) {
var easings = {
// t: current_time, b: begin_value, c: change_value, d: duration
linear: function(t, b, c, d) {
return c * (t / d) + b;
},
swing: function(t, b, c, d) {
return easings.easeOutQuad(t, b, c, d);
},
ease: function(t, b, c, d) {
return easings.easeInOutCubic(t, b, c, d);
},
easeInQuad: function(t, b, c, d) {
return c * (t /= d) * t + b;
},
easeOutQuad: function(t, b, c, d) {
return -c * (t /= d) * (t - 2) + b;
},
easeInOutQuad: function(t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t + b;
return -c / 2 * (--t * (t - 2) - 1) + b;
},
easeInCubic: function(t, b, c, d) {
return c * (t /= d) * t * t + b;
},
easeOutCubic: function(t, b, c, d) {
return c * ((t = t / d - 1) * t * t + 1) + b;
},
easeInOutCubic: function(t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
return c / 2 * ((t -= 2) * t * t + 2) + b;
},
easeInQuart: function(t, b, c, d) {
return c * (t /= d) * t * t * t + b;
},
easeOutQuart: function(t, b, c, d) {
return -c * ((t = t / d - 1) * t * t * t - 1) + b;
},
easeInOutQuart: function(t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
},
easeInQuint: function(t, b, c, d) {
return c * (t /= d) * t * t * t * t + b;
},
easeOutQuint: function(t, b, c, d) {
return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
},
easeInOutQuint: function(t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
},
easeInSine: function(t, b, c, d) {
return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
},
easeOutSine: function(t, b, c, d) {
return c * Math.sin(t / d * (Math.PI / 2)) + b;
},
easeInOutSine: function(t, b, c, d) {
return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
},
easeInExpo: function(t, b, c, d) {
return t === 0 ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
},
easeOutExpo: function(t, b, c, d) {
return t == d ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
},
easeInOutExpo: function(t, b, c, d) {
if (t === 0) return b;
if (t == d) return b + c;
if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
},
easeInCirc: function(t, b, c, d) {
return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
},
easeOutCirc: function(t, b, c, d) {
return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
},
easeInOutCirc: function(t, b, c, d) {
if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
},
easeInElastic: function(t, b, c, d) {
var s = 1.70158;
var p = 0;
var a = c;
if (t === 0) return b;
if ((t /= d) == 1) return b + c;
if (!p) p = d * .3;
if (a < Math.abs(c)) {
a = c;
s = p / 4;
} else s = p / (2 * Math.PI) * Math.asin(c / a);
return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * 2 * Math.PI / p)) + b;
},
easeOutElastic: function(t, b, c, d) {
var s = 1.70158;
var p = 0;
var a = c;
if (t === 0) return b;
if ((t /= d) == 1) return b + c;
if (!p) p = d * .3;
if (a < Math.abs(c)) {
a = c;
s = p / 4;
} else s = p / (2 * Math.PI) * Math.asin(c / a);
return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * 2 * Math.PI / p) + c + b;
},
easeInOutElastic: function(t, b, c, d) {
var s = 1.70158;
var p = 0;
var a = c;
if (t === 0) return b;
if ((t /= d / 2) == 2) return b + c;
if (!p) p = d * .3 * 1.5;
if (a < Math.abs(c)) {
a = c;
var s = p / 4;
} else var s = p / (2 * Math.PI) * Math.asin(c / a);
if (t < 1) return -.5 * a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * 2 * Math.PI / p) + b;
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * 2 * Math.PI / p) * .5 + c + b;
},
easeInBack: function(t, b, c, d, s) {
if (s == undefined) s = 1.70158;
return c * (t /= d) * t * ((s + 1) * t - s) + b;
},
easeOutBack: function(t, b, c, d, s) {
if (s == undefined) s = 1.70158;
return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
},
easeInOutBack: function(t, b, c, d, s) {
if (s == undefined) s = 1.70158;
if ((t /= d / 2) < 1) return c / 2 * t * t * (((s *= 1.525) + 1) * t - s) + b;
return c / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b;
},
easeInBounce: function(t, b, c, d) {
return c - easings.easeOutBounce(d - t, 0, c, d) + b;
},
easeOutBounce: function(t, b, c, d) {
if ((t /= d) < 1 / 2.75) {
return c * 7.5625 * t * t + b;
} else if (t < 2 / 2.75) {
return c * (7.5625 * (t -= 1.5 / 2.75) * t + .75) + b;
} else if (t < 2.5 / 2.75) {
return c * (7.5625 * (t -= 2.25 / 2.75) * t + .9375) + b;
} else {
return c * (7.5625 * (t -= 2.625 / 2.75) * t + .984375) + b;
}
},
easeInOutBounce: function(t, b, c, d) {
if (t < d / 2) return easings.easeInBounce(t * 2, 0, c, d) * .5 + b;
return easings.easeOutBounce(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
}
};
return easings;
});
define("animate/frame", [], function(require, exports) {
// 原生动画帧方法 polyfill
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || function(fn) {
return setTimeout(fn, 1e3 / 60);
};
// 等待执行的帧的集合,这些帧的方法将在下个动画帧同步执行
var pendingFrames = [];
/**
* 添加一个帧到等待集合中
*
* 如果添加的帧是序列的第一个,至少有一个帧需要被执行,则下一个动画帧需要执行
*/
function pushFrame(frame) {
if (pendingFrames.push(frame) === 1) {
requestAnimationFrame(executePendingFrames);
}
}
/**
* 执行所有等待帧
*/
function executePendingFrames() {
var frames = pendingFrames;
pendingFrames = [];
while (frames.length) {
executeFrame(frames.pop());
}
}
/**
* 请求一个帧,执行指定的动作。动作回调提供一些有用的信息
*
* @param {Function} action
*
* 要执行的动作,该动作回调有一个参数 frame,其中:
*
* frame.time
* 动作执行时的时间戳(ms)
*
* frame.index
* 当前执行的帧的编号(首帧为 0)
*
* frame.dur
* 上一帧至今经过的时间,单位 ms
*
* frame.elapsed
* 从首帧开始到当前帧经过的时间
*
* frame.action
* 指向当前的帧处理函数
*
* frame.next()
* 表示下一帧继续执行。如果不调用该方法,将不会执行下一帧。
*
*/
function requestFrame(action) {
var frame = initFrame(action);
pushFrame(frame);
return frame;
}
/**
* 释放一个已经请求过的帧,如果该帧在等待集合里,将移除,下个动画帧不会执行释放的帧
*/
function releaseFrame(frame) {
var index = pendingFrames.indexOf(frame);
if (~index) {
pendingFrames.splice(index, 1);
}
}
/**
* 初始化一个帧,主要用于后续计算
*/
function initFrame(action) {
var frame = {
index: 0,
time: +new Date(),
elapsed: 0,
action: action,
next: function() {
pushFrame(frame);
}
};
return frame;
}
/**
* 执行一个帧动作
*/
function executeFrame(frame) {
// 当前帧时间错
var time = +new Date();
// 当上一帧到当前帧经过的时间
var dur = time - frame.time;
//
// http://stackoverflow.com/questions/13133434/requestanimationframe-detect-stop
// 浏览器最小化或切换标签,requestAnimationFrame 不会执行。
// 检测时间超过 200 ms(频率小于 5Hz ) 判定为计时器暂停,重置为一帧长度
//
if (dur > 200) {
dur = 1e3 / 60;
}
frame.dur = dur;
frame.elapsed += dur;
frame.time = time;
frame.action.call(null, frame);
frame.index++;
}
// 暴露
exports.requestFrame = requestFrame;
exports.releaseFrame = releaseFrame;
});
define("animate/motionanimator", [ "animate/animator", "animate/timeline", "animate/easing", "core/class", "graphic/shape", "graphic/geometry", "core/utils", "graphic/point", "graphic/vector", "graphic/matrix", "graphic/path", "graphic/svg" ], function(require) {
var Animator = require("animate/animator");
var g = require("graphic/geometry");
var Path = require("graphic/path");
var MotionAnimator = require("core/class").createClass("MotionAnimator", {
base: Animator,
constructor: function(path) {
var me = this;
this.callBase({
beginValue: 0,
finishValue: 1,
setter: function(target, value) {
var path = me.motionPath instanceof Path ? me.motionPath.getPathData() : me.motionPath;
var point = g.pointAtPath(path, value);
target.setTranslate(point.x, point.y);
target.setRotate(point.tan.getAngle());
}
});
this.updatePath(path);
},
updatePath: function(path) {
this.motionPath = path;
}
});
require("core/class").extendClass(Path, {
motion: function(path, duration, easing, delay, callback) {
return this.animate(new MotionAnimator(path), duration, easing, delay, callback);
}
});
return MotionAnimator;
});
define("animate/opacityanimator", [ "animate/animator", "animate/timeline", "animate/easing", "core/class", "graphic/shape", "graphic/svg", "core/utils", "graphic/eventhandler", "graphic/styled", "graphic/data", "graphic/matrix", "graphic/pen", "graphic/box" ], function(require) {
var Animator = require("animate/animator");
var OpacityAnimator = require("core/class").createClass("OpacityAnimator", {
base: Animator,
constructor: function(opacity) {
this.callBase({
beginValue: function(target) {
return target.getOpacity();
},
finishValue: opacity,
setter: function(target, value) {
target.setOpacity(value);
}
});
}
});
var Shape = require("graphic/shape");
require("core/class").extendClass(Shape, {
fxOpacity: function(opacity, duration, easing, delay, callback) {
return this.animate(new OpacityAnimator(opacity), duration, easing, delay, callback);
},
fadeTo: function() {
return this.fxOpacity.apply(this, arguments);
},
fadeIn: function() {
return this.fxOpacity.apply(this, [ 1 ].concat([].slice.call(arguments)));
},
fadeOut: function() {
return this.fxOpacity.apply(this, [ 0 ].concat([].slice.call(arguments)));
}
});
return OpacityAnimator;
});
define("animate/pathanimator", [ "animate/animator", "animate/timeline", "animate/easing", "core/class", "graphic/shape", "graphic/geometry", "core/utils", "graphic/point", "graphic/vector", "graphic/matrix", "graphic/path", "graphic/svg" ], function(require) {
var Animator = require("animate/animator");
var g = require("graphic/geometry");
var PathAnimator = require("core/class").createClass("OpacityAnimator", {
base: Animator,
constructor: function(path) {
this.callBase({
beginValue: function(target) {
this.beginPath = target.getPathData();
return 0;
},
finishValue: 1,
setter: function(target, value) {
target.setPathData(g.pathTween(this.beginPath, path, value));
}
});
}
});
var Path = require("graphic/path");
require("core/class").extendClass(Path, {
fxPath: function(path, duration, easing, delay, callback) {
return this.animate(new PathAnimator(path), duration, easing, delay, callback);
}
});
return PathAnimator;
});
define("animate/rotateanimator", [ "animate/animator", "animate/timeline", "animate/easing", "core/class", "graphic/shape", "graphic/svg", "core/utils", "graphic/eventhandler", "graphic/styled", "graphic/data", "graphic/matrix", "graphic/pen", "graphic/box" ], function(require) {
var Animator = require("animate/animator");
var RotateAnimator = require("core/class").createClass("RotateAnimator", {
base: Animator,
constructor: function(deg, ax, ay) {
this.callBase({
beginValue: 0,
finishValue: deg,
setter: function(target, value, timeline) {
var delta = timeline.getDelta();
target.rotate(delta, ax, ay);
}
});
}
});
var Shape = require("graphic/shape");
require("core/class").extendClass(Shape, {
fxRotate: function(deg, duration, easing, delay, callback) {
return this.animate(new RotateAnimator(deg), duration, easing, delay, callback);
},
fxRotateAnchor: function(deg, ax, ay, duration, easing, delay, callback) {
return this.animate(new RotateAnimator(deg, ax, ay), duration, easing, delay, callback);
}
});
return RotateAnimator;
});
define("animate/scaleanimator", [ "animate/animator", "animate/timeline", "animate/easing", "core/class", "graphic/shape", "graphic/svg", "core/utils", "graphic/eventhandler", "graphic/styled", "graphic/data", "graphic/matrix", "graphic/pen", "graphic/box" ], function(require) {
var Animator = require("animate/animator");
var ScaleAnimator = require("core/class").createClass("ScaleAnimator", {
base: Animator,
constructor: function(sx, sy) {
this.callBase({
beginValue: 0,
finishValue: 1,
setter: function(target, value, timeline) {
var delta = timeline.getDelta();
var kx = Math.pow(sx, delta);
var ky = Math.pow(sy, delta);
target.scale(ky, kx);
}
});
}
});
var Shape = require("graphic/shape");
require("core/class").extendClass(Shape, {
fxScale: function(sx, sy, duration, easing, delay, callback) {
return this.animate(new ScaleAnimator(sx, sy), duration, easing, delay, callback);
}
});
return ScaleAnimator;
});
define("animate/timeline", [ "graphic/eventhandler", "core/utils", "graphic/shapeevent", "core/class", "animate/frame" ], function(require) {
var EventHandler = require("graphic/eventhandler");
var frame = require("animate/frame");
var utils = require("core/utils");
function getPercentValue(b, f, p) {
return utils.paralle(b, f, function(b, f) {
return b + (f - b) * p;
});
}
function getDelta(v1, v2) {
return utils.paralle(v1, v2, function(v1, v2) {
return v2 - v1;
});
}
function TimelineEvent(timeline, type, param) {
this.timeline = timeline;
this.target = timeline.target;
this.type = type;
for (var name in param) {
if (param.hasOwnProperty(name)) {
this[name] = param[name];
}
}
}
var Timeline = require("core/class").createClass("Timeline", {
mixins: [ EventHandler ],
constructor: function(animator, target, duration, easing) {
this.callMixin();
this.target = target;
this.time = 0;
this.duration = duration;
this.easing = easing;
this.animator = animator;
this.beginValue = animator.beginValue;
this.finishValue = animator.finishValue;
this.setter = animator.setter;
this.status = "ready";
},
nextFrame: function(frame) {
if (this.status != "playing") {
return;
}
this.time += frame.dur;
this.setValue(this.getValue());
if (this.time >= this.duration) {
this.timeUp();
}
frame.next();
},
getPlayTime: function() {
return this.rollbacking ? this.duration - this.time : this.time;
},
getTimeProportion: function() {
return this.getPlayTime() / this.duration;
},
getValueProportion: function() {
return this.easing(this.getPlayTime(), 0, 1, this.duration);
},
getValue: function() {
var b = this.beginValue;
var f = this.finishValue;
var p = this.getValueProportion();
return getPercentValue(b, f, p);
},
setValue: function(value) {
this.lastValue = this.currentValue;
this.currentValue = value;
this.setter.call(this.target, this.target, value, this);
},
getDelta: function() {
this.lastValue = this.lastValue === undefined ? this.beginValue : this.lastValue;
return getDelta(this.lastValue, this.currentValue);
},
play: function() {
var lastStatus = this.status;
this.status = "playing";
switch (lastStatus) {
case "ready":
if (utils.isFunction(this.beginValue)) {
this.beginValue = this.beginValue.call(this.target, this.target);
}
if (utils.isFunction(this.finishValue)) {
this.finishValue = this.finishValue.call(this.target, this.target);
}
this.time = 0;
this.frame = frame.requestFrame(this.nextFrame.bind(this));
break;
case "finished":
case "stoped":
this.time = 0;
this.frame = frame.requestFrame(this.nextFrame.bind(this));
break;
case "paused":
this.frame.next();
}
this.fire("play", new TimelineEvent(this, "play", {
lastStatus: lastStatus
}));
return this;
},
pause: function() {
this.status = "paused";
this.fire("pause", new TimelineEvent(this, "pause"));
frame.releaseFrame(this.frame);
return this;
},
stop: function() {
this.status = "stoped";
this.setValue(this.finishValue);
this.rollbacking = false;
this.fire("stop", new TimelineEvent(this, "stop"));
frame.releaseFrame(this.frame);
return this;
},
timeUp: function() {
if (this.repeatOption) {
this.time = 0;
if (this.rollback) {
if (this.rollbacking) {
this.decreaseRepeat();
this.rollbacking = false;
} else {
this.rollbacking = true;
this.fire("rollback", new TimelineEvent(this, "rollback"));
}
} else {
this.decreaseRepeat();
}
if (!this.repeatOption) {
this.finish();
} else {
this.fire("repeat", new TimelineEvent(this, "repeat"));
}
} else {
this.finish();
}
},
finish: function() {
this.setValue(this.finishValue);
this.status = "finished";
this.fire("finish", new TimelineEvent(this, "finish"));
frame.releaseFrame(this.frame);
},
decreaseRepeat: function() {
if (this.repeatOption !== true) {
this.repeatOption--;
}
},
repeat: function(repeat, rollback) {
this.repeatOption = repeat;
this.rollback = rollback;
return this;
}
});
Timeline.requestFrame = frame.requestFrame;
Timeline.releaseFrame = frame.releaseFrame;
return Timeline;
});
define("animate/translateanimator", [ "animate/animator", "animate/timeline", "animate/easing", "core/class", "graphic/shape", "graphic/svg", "core/utils", "graphic/eventhandler", "graphic/styled", "graphic/data", "graphic/matrix", "graphic/pen", "graphic/box" ], function(require) {
var Animator = require("animate/animator");
var TranslateAnimator = require("core/class").createClass("TranslateAnimator", {
base: Animator,
constructor: function(x, y) {
this.callBase({
x: 0,
y: 0
}, {
x: x,
y: y
}, function(target, value, timeline) {
var delta = timeline.getDelta();
target.translate(delta.x, delta.y);
});
}
});
var Shape = require("graphic/shape");
require("core/class").extendClass(Shape, {
fxTranslate: function(x, y, duration, easing, delay, callback) {
return this.animate(new TranslateAnimator(x, y), duration, easing, delay, callback);
}
});
return TranslateAnimator;
});
define("core/browser", [], function() {
var browser = function() {
var agent = navigator.userAgent.toLowerCase(), opera = window.opera, browser;
browser = {
ie: /(msie\s|trident.*rv:)([\w.]+)/.test(agent),
opera: !!opera && opera.version,
webkit: agent.indexOf(" applewebkit/") > -1,
mac: agent.indexOf("macintosh") > -1,
quirks: document.compatMode == "BackCompat"
};
browser.gecko = navigator.product == "Gecko" && !browser.webkit && !browser.opera && !browser.ie;
var version = 0;
// Internet Explorer 6.0+
if (browser.ie) {
version = (agent.match(/(msie\s|trident.*rv:)([\w.]+)/)[2] || 0) * 1;
browser.ie11Compat = document.documentMode == 11;
browser.ie9Compat = document.documentMode == 9;
}
// Gecko.
if (browser.gecko) {
var geckoRelease = agent.match(/rv:([\d\.]+)/);
if (geckoRelease) {
geckoRelease = geckoRelease[1].split(".");
version = geckoRelease[0] * 1e4 + (geckoRelease[1] || 0) * 100 + (geckoRelease[2] || 0) * 1;
}
}
if (/chrome\/(\d+\.\d)/i.test(agent)) {
browser.chrome = +RegExp["$1"];
}
if (/(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(agent) && !/chrome/i.test(agent)) {
browser.safari = +(RegExp["$1"] || RegExp["$2"]);
}
// Opera 9.50+
if (browser.opera) version = parseFloat(opera.version());
// WebKit 522+ (Safari 3+)
if (browser.webkit) version = parseFloat(agent.match(/ applewebkit\/(\d+)/)[1]);
browser.version = version;
browser.isCompatible = !browser.mobile && (browser.ie && version >= 6 || browser.gecko && version >= 10801 || browser.opera && version >= 9.5 || browser.air && version >= 1 || browser.webkit && version >= 522 || false);
return browser;
}();
return browser;
});
/**
* @description 创建一个类
* @param {String} fullClassName 类全名,包括命名空间。
* @param {Plain} defines 要创建的类的特性
* defines.constructor {Function} 类的构造函数,实例化的时候会被调用。
* defines.base {String} 基类的名称。名称要使用全名。(因为base是javascript未来保留字,所以不用base)
* defines.mixin {Array<String>} 要混合到新类的类集合
* defines.<method> {Function} 其他类方法
*
* TODO:
* Mixin 构造函数调用支持
*/
define("core/class", [], function(require, exports) {
// just to bind context
Function.prototype.bind = Function.prototype.bind || function(thisObj) {
var args = Array.prototype.slice.call(arguments, 1);
return this.apply(thisObj, args);
};
// 所有类的基类
function Class() {}
Class.__KityClassName = "Class";
// 提供 base 调用支持
Class.prototype.base = function(name) {
var caller = arguments.callee.caller;
var method = caller.__KityMethodClass.__KityBaseClass.prototype[name];
return method.apply(this, Array.prototype.slice.call(arguments, 1));
};
// 直接调用 base 类的同名方法
Class.prototype.callBase = function() {
var caller = arguments.callee.caller;
var method = caller.__KityMethodClass.__KityBaseClass.prototype[caller.__KityMethodName];
return method.apply(this, arguments);
};
Class.prototype.mixin = function(name) {
var caller = arguments.callee.caller;
var mixins = caller.__KityMethodClass.__KityMixins;
if (!mixins) {
return this;
}
var method = mixins[name];
return method.apply(this, Array.prototype.slice.call(arguments, 1));
};
Class.prototype.callMixin = function() {
var caller = arguments.callee.caller;
var methodName = caller.__KityMethodName;
var mixins = caller.__KityMethodClass.__KityMixins;
if (!mixins) {
return this;
}
var method = mixins[methodName];
if (methodName == "constructor") {
for (var i = 0, l = method.length; i < l; i++) {
method[i].call(this);
}
return this;
} else {
return method.apply(this, arguments);
}
};
Class.prototype.pipe = function(fn) {
if (typeof fn == "function") {
fn.call(this, this);
}
return this;
};
Class.prototype.getType = function() {
return this.__KityClassName;
};
Class.prototype.getClass = function() {
return this.constructor;
};
// 检查基类是否调用了父类的构造函数
// 该检查是弱检查,假如调用的代码被注释了,同样能检查成功(这个特性可用于知道建议调用,但是出于某些原因不想调用的情况)
function checkBaseConstructorCall(targetClass, classname) {
var code = targetClass.toString();
if (!/this\.callBase/.test(code)) {
throw new Error(classname + " : 类构造函数没有调用父类的构造函数!为了安全,请调用父类的构造函数");
}
}
var KITY_INHERIT_FLAG = "__KITY_INHERIT_FLAG_" + +new Date();
function inherit(constructor, BaseClass, classname) {
var KityClass = function(__inherit__flag) {
if (__inherit__flag != KITY_INHERIT_FLAG) {
KityClass.__KityConstructor.apply(this, arguments);
}
this.__KityClassName = KityClass.__KityClassName;
};
KityClass.__KityConstructor = constructor;
KityClass.prototype = new BaseClass(KITY_INHERIT_FLAG);
for (var methodName in BaseClass.prototype) {
if (BaseClass.prototype.hasOwnProperty(methodName) && methodName.indexOf("__Kity") !== 0) {
KityClass.prototype[methodName] = BaseClass.prototype[methodName];
}
}
KityClass.prototype.constructor = KityClass;
return KityClass;
}
function mixin(NewClass, mixins) {
if (false === mixins instanceof Array) {
return NewClass;
}
var i, length = mixins.length, proto, method;
NewClass.__KityMixins = {
constructor: []
};
for (i = 0; i < length; i++) {
proto = mixins[i].prototype;
for (method in proto) {
if (false === proto.hasOwnProperty(method) || method.indexOf("__Kity") === 0) {
continue;
}
if (method === "constructor") {
// constructor 特殊处理
NewClass.__KityMixins.constructor.push(proto[method]);
} else {
NewClass.prototype[method] = NewClass.__KityMixins[method] = proto[method];
}
}
}
return NewClass;
}
function extend(BaseClass, extension) {
if (extension.__KityClassName) {
extension = extension.prototype;
}
for (var methodName in extension) {
if (extension.hasOwnProperty(methodName) && methodName.indexOf("__Kity") && methodName != "constructor") {
var method = BaseClass.prototype[methodName] = extension[methodName];
method.__KityMethodClass = BaseClass;
method.__KityMethodName = methodName;
}
}
return BaseClass;
}
Class.prototype._accessProperty = function() {
return this._propertyRawData || (this._propertyRawData = {});
};
exports.createClass = function(classname, defines) {
var constructor, NewClass, BaseClass;
if (arguments.length === 1) {
defines = arguments[0];
classname = "AnonymousClass";
}
BaseClass = defines.base || Class;
if (defines.hasOwnProperty("constructor")) {
constructor = defines.constructor;
if (BaseClass != Class) {
checkBaseConstructorCall(constructor, classname);
}
} else {
constructor = function() {
this.callBase.apply(this, arguments);
this.callMixin.apply(this, arguments);
};
}
NewClass = inherit(constructor, BaseClass, classname);
NewClass = mixin(NewClass, defines.mixins);
NewClass.__KityClassName = constructor.__KityClassName = classname;
NewClass.__KityBaseClass = constructor.__KityBaseClass = BaseClass;
NewClass.__KityMethodName = constructor.__KityMethodName = "constructor";
NewClass.__KityMethodClass = constructor.__KityMethodClass = NewClass;
// 下面这些不需要拷贝到原型链上
delete defines.mixins;
delete defines.constructor;
delete defines.base;
NewClass = extend(NewClass, defines);
return NewClass;
};
exports.extendClass = extend;
});
define("core/utils", [], function() {
var utils = {
each: function(obj, iterator, context) {
if (obj === null) {
return;
}
if (obj.length === +obj.length) {
for (var i = 0, l = obj.length; i < l; i++) {
if (iterator.call(context, obj[i], i, obj) === false) {
return false;
}
}
} else {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (iterator.call(context, obj[key], key, obj) === false) {
return false;
}
}
}
}
},
extend: function(t) {
var a = arguments, notCover = this.isBoolean(a[a.length - 1]) ? a[a.length - 1] : false, len = this.isBoolean(a[a.length - 1]) ? a.length - 1 : a.length;
for (var i = 1; i < len; i++) {
var x = a[i];
for (var k in x) {
if (!notCover || !t.hasOwnProperty(k)) {
t[k] = x[k];
}
}
}
return t;
},
deepExtend: function(t, s) {
var a = arguments, notCover = this.isBoolean(a[a.length - 1]) ? a[a.length - 1] : false, len = this.isBoolean(a[a.length - 1]) ? a.length - 1 : a.length;
for (var i = 1; i < len; i++) {
var x = a[i];
for (var k in x) {
if (!notCover || !t.hasOwnProperty(k)) {
if (this.isObject(t[k]) && this.isObject(x[k])) {
this.deepExtend(t[k], x[k], notCover);
} else {
t[k] = x[k];
}
}
}
}
return t;
},
clone: function(obj) {
var cloned = {};
for (var m in obj) {
if (obj.hasOwnProperty(m)) {
cloned[m] = obj[m];
}
}
return cloned;
},
copy: function(obj) {
if (typeof obj !== "object") return obj;
if (typeof obj === "function") return null;
return JSON.parse(JSON.stringify(obj));
},
queryPath: function(path, obj) {
var arr = path.split(".");
var i = 0, tmp = obj, l = arr.length;
while (i < l) {
if (arr[i] in tmp) {
tmp = tmp[arr[i]];
i++;
if (i >= l || tmp === undefined) {
return tmp;
}
} else {
return undefined;
}
}
},
getValue: function(value, defaultValue) {
return value !== undefined ? value : defaultValue;
},
flatten: function(arr) {
var result = [], length = arr.length, i;
for (i = 0; i < length; i++) {
if (arr[i] instanceof Array) {
result = result.concat(utils.flatten(arr[i]));
} else {
result.push(arr[i]);
}
}
return result;
},
/**
* 平行地对 v1 和 v2 进行指定的操作
*
* 如果 v1 是数字,那么直接进行 op 操作
* 如果 v1 是对象,那么返回一个对象,其元素是 v1 和 v2 同名的每个元素平行地进行 op 操作的结果
* 如果 v1 是数组,那么返回一个数组,其元素是 v1 和 v2 同索引的每个元素平行地进行 op 操作的结果
*
* @param {Number|Object|Array} v1
* @param {Number|Object|Array} v2
* @param {Function} op
* @return {Number|Object|Array}
*/
paralle: function(v1, v2, op) {
var Class, field, index, name, value;
// 数组
if (v1 instanceof Array) {
value = [];
for (index = 0; index < v1.length; index++) {
value.push(utils.paralle(v1[index], v2[index], op));
}
return value;
}
// 对象
if (v1 instanceof Object) {
// 如果值是一个支持原始表示的实例,获取其原始表示
Class = v1.getClass && v1.getClass();
if (Class && Class.parse) {
v1 = v1.valueOf();
v2 = v2.valueOf();
value = utils.paralle(v1, v2, op);
value = Class.parse(value);
} else {
value = {};
for (name in v1) {
if (v1.hasOwnProperty(name) && v2.hasOwnProperty(name)) {
value[name] = utils.paralle(v1[name], v2[name], op);
}
}
}
return value;
}
// 是否数字
if (false === isNaN(parseFloat(v1))) {
return op(v1, v2);
}
return value;
},
/**
* 创建 op 操作的一个平行化版本
*/
parallelize: function(op) {
return function(v1, v2) {
return utils.paralle(v1, v2, op);
};
}
};
utils.each([ "String", "Function", "Array", "Number", "RegExp", "Object", "Boolean" ], function(v) {
utils["is" + v] = function(obj) {
return Object.prototype.toString.apply(obj) == "[object " + v + "]";
};
});
return utils;
});
/**
* 颜色矩阵运算效果封装
*/
define("filter/effect/colormatrixeffect", [ "filter/effect/effect", "graphic/svg", "core/class", "core/utils" ], function(require, exports, module) {
var Effect = require("filter/effect/effect"), Utils = require("core/utils");
var ColorMatrixEffect = require("core/class").createClass("ColorMatrixEffect", {
base: Effect,
constructor: function(type, input) {
this.callBase(Effect.NAME_COLOR_MATRIX);
this.set("type", Utils.getValue(type, ColorMatrixEffect.TYPE_MATRIX));
this.set("in", Utils.getValue(input, Effect.INPUT_SOURCE_GRAPHIC));
}
});
Utils.extend(ColorMatrixEffect, {
// 类型常量
TYPE_MATRIX: "matrix",
TYPE_SATURATE: "saturate",
TYPE_HUE_ROTATE: "hueRotate",
TYPE_LUMINANCE_TO_ALPHA: "luminanceToAlpha",
// 矩阵常量
MATRIX_ORIGINAL: "10000010000010000010".split("").join(" "),
MATRIX_EMPTY: "00000000000000000000".split("").join(" ")
});
return ColorMatrixEffect;
});
/**
* 高斯模糊效果封装
*/
define("filter/effect/compositeeffect", [ "filter/effect/effect", "graphic/svg", "core/class", "core/utils" ], function(require, exports, module) {
var Effect = require("filter/effect/effect"), Utils = require("core/utils");
var CompositeEffect = require("core/class").createClass("CompositeEffect", {
base: Effect,
constructor: function(operator, input, input2) {
this.callBase(Effect.NAME_COMPOSITE);
this.set("operator", Utils.getValue(operator, CompositeEffect.OPERATOR_OVER));
if (input) {
this.set("in", input);
}
if (input2) {
this.set("in2", input2);
}
}
});
Utils.extend(CompositeEffect, {
// operator 常量
OPERATOR_OVER: "over",
OPERATOR_IN: "in",
OPERATOR_OUT: "out",
OPERATOR_ATOP: "atop",
OPERATOR_XOR: "xor",
OPERATOR_ARITHMETIC: "arithmetic"
});
return CompositeEffect;
});
/**
* 像素级别的矩阵卷积运算效果封装
*/
define("filter/effect/convolvematrixeffect", [ "filter/effect/effect", "graphic/svg", "core/class", "core/utils" ], function(require, exports, module) {
var Effect = require("filter/effect/effect"), Utils = require("core/utils");
var ConvolveMatrixEffect = require("core/class").createClass("ConvolveMatrixEffect", {
base: Effect,
constructor: function(edgeMode, input) {
this.callBase(Effect.NAME_CONVOLVE_MATRIX);
this.set("edgeMode", Utils.getValue(edgeMode, ConvolveMatrixEffect.MODE_DUPLICATE));
this.set("in", Utils.getValue(input, Effect.INPUT_SOURCE_GRAPHIC));
}
});
Utils.extend(ConvolveMatrixEffect, {
MODE_DUPLICATE: "duplicate",
MODE_WRAP: "wrap",
MODE_NONE: "none"
});
return ConvolveMatrixEffect;
});
/*
* 效果类
* 该类型的对象不存储任何内部属性, 所有操作都是针对该类对象所维护的节点进行的
*/
define("filter/effect/effect", [ "graphic/svg", "core/class", "core/utils" ], function(require, exports, module) {
var svg = require("graphic/svg"), Effect = require("core/class").createClass("Effect", {
constructor: function(type) {
this.node = svg.createNode(type);
},
getId: function() {
return this.node.id;
},
setId: function(id) {
this.node.id = id;
return this;
},
set: function(key, value) {
this.node.setAttribute(key, value);
return this;
},
get: function(key) {
return this.node.getAttribute(key);
},
getNode: function() {
return this.node;
},
// 返回该效果的result
toString: function() {
return this.node.getAttribute("result") || "";
}
});
require("core/utils").extend(Effect, {
// 特效名称常量
NAME_GAUSSIAN_BLUR: "feGaussianBlur",
NAME_OFFSET: "feOffset",
NAME_COMPOSITE: "feComposite",
NAME_COLOR_MATRIX: "feColorMatrix",
NAME_CONVOLVE_MATRIX: "feConvolveMatrix",
// 输入常量
INPUT_SOURCE_GRAPHIC: "SourceGraphic",
INPUT_SOURCE_ALPHA: "SourceAlpha",
INPUT_BACKGROUND_IMAGE: "BackgroundImage",
INPUT_BACKGROUND_ALPHA: "BackgroundAlpha",
INPUT_FILL_PAINT: "FillPaint",
INPUT_STROKE_PAINT: "StrokePaint"
});
return Effect;
});
/**
* 高斯模糊效果封装
*/
define("filter/effect/gaussianblureffect", [ "filter/effect/effect", "graphic/svg", "core/class", "core/utils" ], function(require, exports, module) {
var Effect = require("filter/effect/effect"), Utils = require("core/utils");
return require("core/class").createClass("GaussianblurEffect", {
base: Effect,
constructor: function(stdDeviation, input) {
this.callBase(Effect.NAME_GAUSSIAN_BLUR);
this.set("stdDeviation", Utils.getValue(stdDeviation, 1));
this.set("in", Utils.getValue(input, Effect.INPUT_SOURCE_GRAPHIC));
}
});
});
/**
* 偏移效果封装
*/
define("filter/effect/offseteffect", [ "filter/effect/effect", "graphic/svg", "core/class", "core/utils" ], function(require, exports, module) {
var Effect = require("filter/effect/effect"), Utils = require("core/utils");
return require("core/class").createClass("OffsetEffect", {
base: Effect,
constructor: function(dx, dy, input) {
this.callBase(Effect.NAME_OFFSET);
this.set("dx", Utils.getValue(dx, 0));
this.set("dy", Utils.getValue(dy, 0));
this.set("in", Utils.getValue(input, Effect.INPUT_SOURCE_GRAPHIC));
}
});
});
/*
* Effect所用的container
*/
define("filter/effectcontainer", [ "core/class", "graphic/container" ], function(require) {
return require("core/class").createClass("EffectContainer", {
base: require("graphic/container"),
addEffect: function(point, pos) {
return this.addItem.apply(this, arguments);
},
prependEffect: function() {
return this.prependItem.apply(this, arguments);
},
appendEffect: function() {
return this.appendItem.apply(this, arguments);
},
removeEffect: function(pos) {
return this.removeItem.apply(this, arguments);
},
addEffects: func