UNPKG

zoomla

Version:

16年专业研发|中文alexa排名第一的CMS品牌-基于dotNET core、功能强大,集成站群、微信开发、小程序与ERP及OA办公系统,支持国际语言和多民族语言,世界五百强与大型门户专用高端网站内核CMS系统

1,331 lines (1,293 loc) 233 kB
/*! * ==================================================== * 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