web手势库AlloyFinger运用( 控制CANVAS中图片移动、缩放、旋转)
来源:互联网 发布:梦龙网络计划编制软件 编辑:程序博客网 时间:2024/06/06 23:16
web手势库AlloyFinger(alloy_finger.js),针对多点触控设备编程的Web手势组件,快速帮助你的web程序增加手势支持
非常灵活,省去了自己写相应操作的代码,就能控制元素移动、缩放、旋转了
http://alloyteam.github.io/AlloyFinger/example/canvas/此网址的案例就是控制CANVAS中多张图片操作的,此案例实现不仅引用了alloy_finger.js,另外引用了alloy_paper.js
不过我想要将文件域中上传的图片画入CANVAS中,且控制上传的图片移动、缩放、旋转有就问题,一是上传图片传递的url问题,二是只有在页面加载完成时画入的图片手势行为有效,延时设置画入图片或将上传的图片画入画布的,手势行为都会报错,于是改了下alloy_paper.js的代码
修改一(针对上传图片处理的):
1299行加了一个方法
复制以下方法
"loadRes": function(arr) {
this.resCount = arr.length;
for (var i = 0; i < arr.length; i++) {
var type=this._getTypeByExtension(arr[i].src.match(this.FILE_PATTERN)[5]);
if (type === "audio") {
this.loadAudio(arr[i].id, arr[i].src);
} else if (type === "js") {
this.loadScript(arr[i].src);
} else if (type === "img") {
this.loadImage(arr[i].id, arr[i].src);
}
}
},
改为
"loadRes2": function(arr) {
this.resCount = arr.length;
for (var i = 0; i < arr.length; i++) {
this.loadImage(arr[i].id, arr[i].src);
}
},
修改二(针对手势行为报错处理):
原3988行(改后3994行)注释取消(//this.adjustLayout();)
this.adjustLayout();
案例:代言海报下载
结合插件实现的例子如下:
HTML代码部分:
<!DOCTYPE html><html><head> <meta charset="utf-8"> <title>Canvas+AlloyFinger —— test</title> <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/> <style>@charset "utf-8";@media screen and (min-width:320px) and (max-width:359px){html{font-size:12px;}body{ font-size:1.2rem;}}@media screen and (min-width:360px) and (max-width:374px){html{font-size:13.5px;}}@media screen and (min-width:375px) and (max-width:383px){html{font-size:14.07px;}}@media screen and (min-width:384px) and (max-width:392px){html{font-size:14.38px;}}@media screen and (min-width:393px) and (max-width:410px){html{font-size:14.75px;}}@media screen and (min-width:411px) and (max-width:413px){html{font-size:15.41px;}}@media screen and (min-width:414px) and (max-width:479px){html{font-size:15.52px;}}@media screen and (min-width:480px) and (max-width:511px){html{font-size:18px;}}@media screen and (min-width:512px) and (max-width:639px){html{font-size:19.19px;}}@media screen and (min-width:640px){html{font-size:24px;}}*{ margin:0; padding:0; box-sizing:border-box;}html , body{ display:block; width:100%; height:100%; max-width:640px; min-width:320px; margin:0 auto;}canvas{ width:100%; height:100%; vertical-align:middle;}#c1{ display:block; width:90%; height:25rem; border-radius:.5rem; border:#e1e1e1 solid 1px; position:fixed; left:50%; top:.5rem; margin-left:-45%;}.canvasBg{ width:2.5rem; height:2.8rem; line-height:1.4rem; text-align:center; font-size:.8rem; color:#fff; border-top-left-radius:.2rem; border-bottom-left-radius:.2rem; background-color:rgba(0,0,0,.7); position:fixed; right:0; top:24rem; cursor:pointer;}#showImg{ display:block; width:90%; margin:.5rem auto; border:#f00 dashed 5px; display:none;}#showImgBtn{width:5rem; height:5rem; line-height:5rem; text-align:center; border-radius:50%; background-color:#eee; position:absolute; left:50%; margin-left:-2.5rem; bottom:1rem;} </style></head><body><script type="text/javascript" src="http://code.jquery.com/jquery-2.0.0.min.js"></script><script src="alloy_file/alloy_paper.js"></script><script src="alloy_file/alloy_finger.js"></script><canvas id="c1"></canvas><input type="file" id="upfile" accept="image/*" style="display:none;" /><div class="canvasBg">上传<br>图片</div><img id="showImg" src="" /><div id="showImgBtn">生成图片</div><script>function getObjectURL(file) { var url = null ; if (window.createObjectURL!=undefined) { // basic url = window.createObjectURL(file) ; } else if (window.URL!=undefined) { // mozilla(firefox) url = window.URL.createObjectURL(file) ; } else if (window.webkitURL!=undefined) { // webkit or chrome url = window.webkitURL.createObjectURL(file) ; } return url ; } $('.canvasBg').on('click',function(){$('#upfile').trigger('click');});var c1 = document.getElementById("c1"); c1.width = 640;c1.height = 640 / $('#c1').width() * $('#c1').height();var ctx1 = c1.getContext("2d");$('#upfile').on('change',function(){upimgurl = getObjectURL(this.files[0]); upimg = new Image(); upimg.src = upimgurl; upimg.onload = function(){ ctx1.clearRect(0,0,c1.width,c1.height); var Stage = AlloyPaper.Stage, Bitmap = AlloyPaper.Bitmap,Loader=AlloyPaper.Loader; var stage = new Stage("#c1"); stage.autoUpdate=false; var ld = new Loader(); ld.loadRes2([{ id: "test", src: upimgurl }, ]); ld.complete(function () { var bmp = new Bitmap(ld.get("test")); bmp.originX = 0.5; bmp.originY = 0.5; bmp.x = stage.width / 2; bmp.y = stage.height / 2; stage.add(bmp); //stage.update();updateStage(); var initScale = 1; new AlloyFinger(bmp, { multipointStart: function () { initScale = bmp.scaleX; }, rotate: function (evt) { bmp.rotation += evt.angle; //stage.update();updateStage(); }, pinch: function (evt) { bmp.scaleX = bmp.scaleY = initScale * evt.scale; //stage.update();updateStage(); }, pressMove: function (evt) { bmp.x += evt.deltaX; bmp.y += evt.deltaY; evt.preventDefault(); //stage.update();updateStage(); } }); });//将上传的图片画入canvas圆中function updateStage(){ctx1.beginPath();if(c1.width > c1.height){ctx1.arc(c1.width/2 , c1.height/2 , c1.height/2 , 0 , 2*Math.PI);}else{ctx1.arc(c1.width/2 , c1.height/2 , c1.width/2 , 0 , 2*Math.PI);}ctx1.save();ctx1.clip();stage.update();ctx1.restore();whiteText();}}; });function whiteText(){ctx1.font = 'bold 40px "PingFangSC-Regular","sans-serif","STHeitiSC-Light","微软雅黑","Microsoft YaHei"';ctx1.fillStyle = '#f00'; ctx1.textBaseline="middle"; ctx1.textAlign="center"; ctx1.fillText('测试文字',c1.width/2,c1.height/2);}$('#showImgBtn').on('click',function(){$('#showImg').attr('src',c1.toDataURL("image/jpg"));$('#showImg').show();$('#c1').hide();});</script></body></html>
alloy_finger.js代码:
/* AlloyFinger v0.1.2 * By dntzhang * Github: https://github.com/AlloyTeam/AlloyFinger */;(function() { function getLen(v) { return Math.sqrt(v.x * v.x + v.y * v.y); } function dot(v1, v2) { return v1.x * v2.x + v1.y * v2.y; } function getAngle(v1, v2) { var mr = getLen(v1) * getLen(v2); if (mr === 0) return 0; var r = dot(v1, v2) / mr; if (r > 1) r = 1; return Math.acos(r); } function cross(v1, v2) { return v1.x * v2.y - v2.x * v1.y; } function getRotateAngle(v1, v2) { var angle = getAngle(v1, v2); if (cross(v1, v2) > 0) { angle *= -1; } return angle * 180 / Math.PI; } var AlloyFinger = function (el, option) { el.addEventListener("touchstart", this.start.bind(this), false); el.addEventListener("touchmove", this.move.bind(this), false); el.addEventListener("touchend", this.end.bind(this), false); el.addEventListener("touchcancel",this.cancel.bind(this),false); this.preV = { x: null, y: null }; this.pinchStartLen = null; this.scale = 1; this.isDoubleTap = false; this.rotate = option.rotate || function () { }; this.touchStart = option.touchStart || function () { }; this.multipointStart = option.multipointStart || function () { }; this.multipointEnd=option.multipointEnd||function(){}; this.pinch = option.pinch || function () { }; this.swipe = option.swipe || function () { }; this.tap = option.tap || function () { }; this.doubleTap = option.doubleTap || function () { }; this.longTap = option.longTap || function () { }; this.singleTap = option.singleTap || function () { }; this.pressMove = option.pressMove || function () { }; this.touchMove = option.touchMove || function () { }; this.touchEnd = option.touchEnd || function () { }; this.touchCancel = option.touchCancel || function () { }; this.delta = null; this.last = null; this.now = null; this.tapTimeout = null; this.touchTimeout = null; this.longTapTimeout = null; this.swipeTimeout=null; this.x1 = this.x2 = this.y1 = this.y2 = null; this.preTapPosition={x:null,y:null}; }; AlloyFinger.prototype = { start: function (evt) { if(!evt.touches)return; this.now = Date.now(); this.x1 = evt.touches[0].pageX; this.y1 = evt.touches[0].pageY; this.delta = this.now - (this.last || this.now); this.touchStart(evt); if(this.preTapPosition.x!==null){ this.isDoubleTap = (this.delta > 0 && this.delta <= 250&&Math.abs(this.preTapPosition.x-this.x1)<30&&Math.abs(this.preTapPosition.y-this.y1)<30); } this.preTapPosition.x=this.x1; this.preTapPosition.y=this.y1; this.last = this.now; var preV = this.preV, len = evt.touches.length; if (len > 1) { this._cancelLongTap(); var v = { x: evt.touches[1].pageX - this.x1, y: evt.touches[1].pageY - this.y1 }; preV.x = v.x; preV.y = v.y; this.pinchStartLen = getLen(preV); this.multipointStart(evt); } this.longTapTimeout = setTimeout(function(){ this.longTap(evt); }.bind(this), 750); }, move: function (evt) { if(!evt.touches)return; var preV = this.preV, len = evt.touches.length, currentX = evt.touches[0].pageX, currentY = evt.touches[0].pageY; this.isDoubleTap=false; if (len > 1) { var v = { x: evt.touches[1].pageX - currentX, y: evt.touches[1].pageY - currentY }; if (preV.x !== null) { if (this.pinchStartLen > 0) { evt.scale = getLen(v) / this.pinchStartLen; this.pinch(evt); } evt.angle = getRotateAngle(v, preV); this.rotate(evt); } preV.x = v.x; preV.y = v.y; } else { if (this.x2 !== null) { evt.deltaX = currentX - this.x2; evt.deltaY = currentY - this.y2; }else{ evt.deltaX = 0; evt.deltaY = 0; } this.pressMove(evt); } this.touchMove(evt); this._cancelLongTap(); this.x2 = currentX; this.y2 = currentY; if (evt.touches.length > 1) { this._cancelLongTap(); evt.preventDefault(); } }, end: function (evt) { if(!evt.changedTouches)return; this._cancelLongTap(); var self = this; if( evt.touches.length<2){ this.multipointEnd(evt); } this.touchEnd(evt); //swipe if ((this.x2 && Math.abs(this.x1 - this.x2) > 30) || (this.y2 && Math.abs(this.preV.y - this.y2) > 30)) { evt.direction = this._swipeDirection(this.x1, this.x2, this.y1, this.y2); this.swipeTimeout = setTimeout(function () { self.swipe(evt); }, 0) } else { this.tapTimeout = setTimeout(function () { self.tap(evt); // trigger double tap immediately if (self.isDoubleTap) { self.doubleTap(evt); clearTimeout(self.touchTimeout); self.isDoubleTap = false; }else{ self.touchTimeout=setTimeout(function(){ self.singleTap(evt); },250); } }, 0) } this.preV.x = 0; this.preV.y = 0; this.scale = 1; this.pinchStartLen = null; this.x1 = this.x2 = this.y1 = this.y2 = null; }, cancel:function(evt){ clearTimeout(this.touchTimeout); clearTimeout(this.tapTimeout); clearTimeout(this.longTapTimeout); clearTimeout(this.swipeTimeout); this.touchCancel(evt); }, _cancelLongTap: function () { clearTimeout(this.longTapTimeout); }, _swipeDirection: function (x1, x2, y1, y2) { return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down') } }; if (typeof module !== 'undefined' && typeof exports === 'object') { module.exports = AlloyFinger; }else { window.AlloyFinger = AlloyFinger; }})();
修改后的alloy_paper.js代码:
/* Alloy Game Engine * By AlloyTeam http://www.alloyteam.com/ * Github: https://github.com/AlloyTeam/AlloyGameEngine * MIT Licensed. */;(function (root, factory) { if (typeof define === 'function' && define.amd) { define([], factory); } else if (typeof exports === 'object') { module.exports = factory(); } else { root.AlloyPaper = factory(); }}(this, function () {'use strict';// The base Class implementation (does nothing)var Class = function () { };// Create a new Class that inherits from this classClass.extend = function (prop) { var _super = this.prototype; var prototype = Object.create(_super); // Copy the properties over onto the new prototype for (var name in prop) { if (name != "statics") { // Check if we're overwriting an existing function prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" ? (function (temp_name, fn) { return function () { var tmp = this._super; // Add a new ._super() method that is the same method // but on the super-class this._super = _super[temp_name]; // The method only need to be bound temporarily, so we // remove it when we're done executing var ret = fn.apply(this, arguments); this._super = tmp; return ret; }; })(name, prop[name]) : prop[name]; } } // The dummy class constructor function _Class() { // All construction is actually done in the init method this.ctor.apply(this, arguments); } //继承父类的静态属性 for (var key in this) { if (this.hasOwnProperty(key) && key != "extend") _Class[key] = this[key]; } // Populate our constructed prototype object _Class.prototype = prototype; _Class.prototype._super = Object.create(_super); //静态属性和方法 if (prop.statics) { for (var key in prop.statics) { if (prop.statics.hasOwnProperty(key)) { _Class[key] = prop.statics[key]; if (key == "ctor") { //提前执行静态构造函数 _Class[key](); } } } } // Enforce the constructor to be what we expect _Class.prototype.constructor = _Class; // And make this class extendable _Class.extend = Class.extend; return _Class;};window.Class = Class;//AlloyPapervar AlloyPaper={};AlloyPaper.DefaultCursor = "default";AlloyPaper.Cache = {};AlloyPaper.TWEEN = Class.extend({ "statics": { "ctor": function() { if (Date.now === undefined) { Date.now = function() { return new Date().valueOf(); }; } this._tweens = []; }, "REVISION": "14", "getAll": function() { return this._tweens; }, "removeAll": function() { this._tweens = []; }, "add": function(tween) { this._tweens.push(tween); }, "remove": function(tween) { var i = this._tweens.indexOf(tween); if (i !== -1) { this._tweens.splice(i, 1); } }, "update": function(time) { if (this._tweens.length === 0) return false; var i = 0; time = time !== undefined ? time : typeof window !== "undefined" && window.performance !== undefined && window.performance.now !== undefined ? window.performance.now() : Date.now(); while (i < this._tweens.length) { if (this._tweens[i].update(time)) { i++; } else { this._tweens.splice(i, 1); } } return true; }, "Tween": function(object) { var _object = object; var _valuesStart = {}; var _valuesEnd = {}; var _valuesStartRepeat = {}; var _duration = 1e3; var _repeat = 0; var _yoyo = false; var _isPlaying = false; var _reversed = false; var _delayTime = 0; var _startTime = null; var _easingFunction = AlloyPaper.TWEEN.Easing.Linear.None; var _interpolationFunction = AlloyPaper.TWEEN.Interpolation.Linear; var _chainedTweens = []; var _onStartCallback = null; var _onStartCallbackFired = false; var _onUpdateCallback = null; var _onCompleteCallback = null; var _onStopCallback = null; var _paused = false, _passTime = null; for (var field in object) { _valuesStart[field] = parseFloat(object[field], 10); } this.toggle = function() { if (_paused) { this.play(); } else { this.pause(); } }; this.pause = function() { _paused = true; var pauseTime = typeof window !== "undefined" && window.performance !== undefined && window.performance.now !== undefined ? window.performance.now() : Date.now(); _passTime = pauseTime - _startTime; }; this.play = function() { _paused = false; var nowTime = typeof window !== "undefined" && window.performance !== undefined && window.performance.now !== undefined ? window.performance.now() : Date.now(); _startTime = nowTime - _passTime; }; this.to = function(properties, duration) { if (duration !== undefined) { _duration = duration; } _valuesEnd = properties; return this; }; this.start = function(time) { AlloyPaper.TWEEN.add(this); _isPlaying = true; _onStartCallbackFired = false; _startTime = time !== undefined ? time : typeof window !== "undefined" && window.performance !== undefined && window.performance.now !== undefined ? window.performance.now() : Date.now(); _startTime += _delayTime; for (var property in _valuesEnd) { if (_valuesEnd[property] instanceof Array) { if (_valuesEnd[property].length === 0) { continue; } _valuesEnd[property] = [_object[property]].concat(_valuesEnd[property]); } _valuesStart[property] = _object[property]; if (_valuesStart[property] instanceof Array === false) { _valuesStart[property] *= 1; } _valuesStartRepeat[property] = _valuesStart[property] || 0; } return this; }; this.stop = function() { if (!_isPlaying) { return this; } AlloyPaper.TWEEN.remove(this); _isPlaying = false; if (_onStopCallback !== null) { _onStopCallback.call(_object); } this.stopChainedTweens(); return this; }; this.stopChainedTweens = function() { for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) { _chainedTweens[i].stop(); } }; this.delay = function(amount) { _delayTime = amount; return this; }; this.repeat = function(times) { _repeat = times; return this; }; this.yoyo = function(yoyo) { _yoyo = yoyo; return this; }; this.easing = function(easing) { _easingFunction = easing; return this; }; this.interpolation = function(interpolation) { _interpolationFunction = interpolation; return this; }; this.chain = function() { _chainedTweens = arguments; return this; }; this.onStart = function(callback) { _onStartCallback = callback; return this; }; this.onUpdate = function(callback) { _onUpdateCallback = callback; return this; }; this.onComplete = function(callback) { _onCompleteCallback = callback; return this; }; this.onStop = function(callback) { _onStopCallback = callback; return this; }; this.update = function(time) { if (_paused) return true; var property; if (time < _startTime) { return true; } if (_onStartCallbackFired === false) { if (_onStartCallback !== null) { _onStartCallback.call(_object); } _onStartCallbackFired = true; } var elapsed = (time - _startTime) / _duration; elapsed = elapsed > 1 ? 1 : elapsed; var value = _easingFunction(elapsed); for (property in _valuesEnd) { var start = _valuesStart[property] || 0; var end = _valuesEnd[property]; if (end instanceof Array) { _object[property] = _interpolationFunction(end, value); } else { if (typeof end === "string") { end = start + parseFloat(end, 10); } if (typeof end === "number") { _object[property] = start + (end - start) * value; } } } if (_onUpdateCallback !== null) { _onUpdateCallback.call(_object, value); } if (elapsed == 1) { if (_repeat > 0) { if (isFinite(_repeat)) { _repeat--; } for (property in _valuesStartRepeat) { if (typeof _valuesEnd[property] === "string") { _valuesStartRepeat[property] = _valuesStartRepeat[property] + parseFloat(_valuesEnd[property], 10); } if (_yoyo) { var tmp = _valuesStartRepeat[property]; _valuesStartRepeat[property] = _valuesEnd[property]; _valuesEnd[property] = tmp; } _valuesStart[property] = _valuesStartRepeat[property]; } if (_yoyo) { _reversed = !_reversed; } _startTime = time + _delayTime; return true; } else { if (_onCompleteCallback !== null) { _onCompleteCallback.call(_object); } for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) { _chainedTweens[i].start(time); } return false; } } return true; }; }, "Easing": { "Linear": { "None": function(k) { return k; } }, "Quadratic": { "In": function(k) { return k * k; }, "Out": function(k) { return k * (2 - k); }, "InOut": function(k) { if ((k *= 2) < 1) return.5 * k * k; return -.5 * (--k * (k - 2) - 1); } }, "Cubic": { "In": function(k) { return k * k * k; }, "Out": function(k) { return --k * k * k + 1; }, "InOut": function(k) { if ((k *= 2) < 1) return.5 * k * k * k; return.5 * ((k -= 2) * k * k + 2); } }, "Quartic": { "In": function(k) { return k * k * k * k; }, "Out": function(k) { return 1 - --k * k * k * k; }, "InOut": function(k) { if ((k *= 2) < 1) return.5 * k * k * k * k; return -.5 * ((k -= 2) * k * k * k - 2); } }, "Quintic": { "In": function(k) { return k * k * k * k * k; }, "Out": function(k) { return --k * k * k * k * k + 1; }, "InOut": function(k) { if ((k *= 2) < 1) return.5 * k * k * k * k * k; return.5 * ((k -= 2) * k * k * k * k + 2); } }, "Sinusoidal": { "In": function(k) { return 1 - Math.cos(k * Math.PI / 2); }, "Out": function(k) { return Math.sin(k * Math.PI / 2); }, "InOut": function(k) { return.5 * (1 - Math.cos(Math.PI * k)); } }, "Exponential": { "In": function(k) { return k === 0 ? 0 : Math.pow(1024, k - 1); }, "Out": function(k) { return k === 1 ? 1 : 1 - Math.pow(2, -10 * k); }, "InOut": function(k) { if (k === 0) return 0; if (k === 1) return 1; if ((k *= 2) < 1) return.5 * Math.pow(1024, k - 1); return.5 * (-Math.pow(2, -10 * (k - 1)) + 2); } }, "Circular": { "In": function(k) { return 1 - Math.sqrt(1 - k * k); }, "Out": function(k) { return Math.sqrt(1 - --k * k); }, "InOut": function(k) { if ((k *= 2) < 1) return -.5 * (Math.sqrt(1 - k * k) - 1); return.5 * (Math.sqrt(1 - (k -= 2) * k) + 1); } }, "Elastic": { "In": function(k) { var s, a = .1, p = .4; if (k === 0) return 0; if (k === 1) return 1; if (!a || a < 1) { a = 1; s = p / 4; } else s = p * Math.asin(1 / a) / (2 * Math.PI); return -(a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p)); }, "Out": function(k) { var s, a = .1, p = .4; if (k === 0) return 0; if (k === 1) return 1; if (!a || a < 1) { a = 1; s = p / 4; } else s = p * Math.asin(1 / a) / (2 * Math.PI); return a * Math.pow(2, -10 * k) * Math.sin((k - s) * (2 * Math.PI) / p) + 1; }, "InOut": function(k) { var s, a = .1, p = .4; if (k === 0) return 0; if (k === 1) return 1; if (!a || a < 1) { a = 1; s = p / 4; } else s = p * Math.asin(1 / a) / (2 * Math.PI); if ((k *= 2) < 1) return -.5 * (a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p)); return a * Math.pow(2, -10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p) * .5 + 1; } }, "Back": { "In": function(k) { var s = 1.70158; return k * k * ((s + 1) * k - s); }, "Out": function(k) { var s = 1.70158; return --k * k * ((s + 1) * k + s) + 1; }, "InOut": function(k) { var s = 1.70158 * 1.525; if ((k *= 2) < 1) return.5 * (k * k * ((s + 1) * k - s)); return.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2); } }, "Bounce": { "In": function(k) { return 1 - AlloyPaper.TWEEN.Easing.Bounce.Out(1 - k); }, "Out": function(k) { if (k < 1 / 2.75) { return 7.5625 * k * k; } else if (k < 2 / 2.75) { return 7.5625 * (k -= 1.5 / 2.75) * k + .75; } else if (k < 2.5 / 2.75) { return 7.5625 * (k -= 2.25 / 2.75) * k + .9375; } else { return 7.5625 * (k -= 2.625 / 2.75) * k + .984375; } }, "InOut": function(k) { if (k < .5) return AlloyPaper.TWEEN.Easing.Bounce.In(k * 2) * .5; return AlloyPaper.TWEEN.Easing.Bounce.Out(k * 2 - 1) * .5 + .5; } } }, "Interpolation": { "Linear": function(v, k) { var m = v.length - 1, f = m * k, i = Math.floor(f), fn = AlloyPaper.TWEEN.Interpolation.Utils.Linear; if (k < 0) return fn(v[0], v[1], f); if (k > 1) return fn(v[m], v[m - 1], m - f); return fn(v[i], v[i + 1 > m ? m : i + 1], f - i); }, "Bezier": function(v, k) { var b = 0, n = v.length - 1, pw = Math.pow, bn = AlloyPaper.TWEEN.Interpolation.Utils.Bernstein, i; for (i = 0; i <= n; i++) { b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i); } return b; }, "CatmullRom": function(v, k) { var m = v.length - 1, f = m * k, i = Math.floor(f), fn = AlloyPaper.TWEEN.Interpolation.Utils.CatmullRom; if (v[0] === v[m]) { if (k < 0) i = Math.floor(f = m * (1 + k)); return fn(v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m], f - i); } else { if (k < 0) return v[0] - (fn(v[0], v[0], v[1], v[1], -f) - v[0]); if (k > 1) return v[m] - (fn(v[m], v[m], v[m - 1], v[m - 1], f - m) - v[m]); return fn(v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2], f - i); } }, "Utils": { "Linear": function(p0, p1, t) { return (p1 - p0) * t + p0; }, "Bernstein": function(n, i) { var fc = AlloyPaper.TWEEN.Interpolation.Utils.getFactorial(); return fc(n) / fc(i) / fc(n - i); }, "getFactorial": function() { return function() { var a = [1]; return function(n) { var s = 1, i; if (a[n]) return a[n]; for (i = n; i > 1; i--) s *= i; return a[n] = s; }; }(); }, "CatmullRom": function(p0, p1, p2, p3, t) { var v0 = (p2 - p0) * .5, v1 = (p3 - p1) * .5, t2 = t * t, t3 = t * t2; return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1; } } } }});//begin-------------------AlloyPaper.Dom---------------------beginAlloyPaper.Dom = Class.extend({ "statics": { "get": function(selector) { this.element = document.querySelector(selector); return this; }, "on": function(type, fn) { this.element.addEventListener(type, fn, false); return this; } }});//end-------------------AlloyPaper.Dom---------------------end//begin-------------------AlloyPaper.FPS---------------------beginAlloyPaper.FPS = Class.extend({ "statics": { "get": function() { if (!this.instance) this.instance = new this(); this.instance._computeFPS(); return this.instance; } }, "ctor": function() { this.last = new Date(); this.current = null; this.lastMeasured=new Date(); this.fpsList = []; this.totalValue = 0; this.value = 60; }, "_computeFPS": function() { this.current = new Date(); if (this.current - this.last > 0) { var fps = Math.ceil(1e3 / (this.current - this.last)); this.fpsList.push(fps); this.totalValue += fps; this.last = this.current; } if (this.current - this.lastMeasured > 1000) { this.value =Math.ceil( this.totalValue / this.fpsList.length); this.totalValue = 0; this.fpsList.length = 0; this.lastMeasured = this.current; } }});//end-------------------AlloyPaper.FPS---------------------endAlloyPaper.Keyboard = Class.extend({ "statics": { "ctor": function() { var KeyboardJS = {}, locales = {}, locale, map, macros, activeKeys = [], bindings = [], activeBindings = [], activeMacros = [], aI, usLocale; usLocale = { map: { "3": ["cancel"], "8": ["backspace"], "9": ["tab"], "12": ["clear"], "13": ["enter"], "16": ["shift"], "17": ["ctrl"], "18": ["alt", "menu"], "19": ["pause", "break"], "20": ["capslock"], "27": ["escape", "esc"], "32": ["space", "spacebar"], "33": ["pageup"], "34": ["pagedown"], "35": ["end"], "36": ["home"], "37": ["left"], "38": ["up"], "39": ["right"], "40": ["down"], "41": ["select"], "42": ["printscreen"], "43": ["execute"], "44": ["snapshot"], "45": ["insert", "ins"], "46": ["delete", "del"], "47": ["help"], "91": ["command", "windows", "win", "super", "leftcommand", "leftwindows", "leftwin", "leftsuper"], "92": ["command", "windows", "win", "super", "rightcommand", "rightwindows", "rightwin", "rightsuper"], "145": ["scrolllock", "scroll"], "186": ["semicolon", ";"], "187": ["equal", "equalsign", "="], "188": ["comma", ","], "189": ["dash", "-"], "190": ["period", "."], "191": ["slash", "forwardslash", "/"], "192": ["graveaccent", "`"], "219": ["openbracket", "["], "220": ["backslash", "\\"], "221": ["closebracket", "]"], "222": ["apostrophe", "'"], "48": ["zero", "0"], "49": ["one", "1"], "50": ["two", "2"], "51": ["three", "3"], "52": ["four", "4"], "53": ["five", "5"], "54": ["six", "6"], "55": ["seven", "7"], "56": ["eight", "8"], "57": ["nine", "9"], "96": ["numzero", "num0"], "97": ["numone", "num1"], "98": ["numtwo", "num2"], "99": ["numthree", "num3"], "100": ["numfour", "num4"], "101": ["numfive", "num5"], "102": ["numsix", "num6"], "103": ["numseven", "num7"], "104": ["numeight", "num8"], "105": ["numnine", "num9"], "106": ["nummultiply", "num*"], "107": ["numadd", "num+"], "108": ["numenter"], "109": ["numsubtract", "num-"], "110": ["numdecimal", "num."], "111": ["numdivide", "num/"], "144": ["numlock", "num"], "112": ["f1"], "113": ["f2"], "114": ["f3"], "115": ["f4"], "116": ["f5"], "117": ["f6"], "118": ["f7"], "119": ["f8"], "120": ["f9"], "121": ["f10"], "122": ["f11"], "123": ["f12"] }, macros: [["shift + `", ["tilde", "~"]], ["shift + 1", ["exclamation", "exclamationpoint", "!"]], ["shift + 2", ["at", "@"]], ["shift + 3", ["number", "#"]], ["shift + 4", ["dollar", "dollars", "dollarsign", "$"]], ["shift + 5", ["percent", "%"]], ["shift + 6", ["caret", "^"]], ["shift + 7", ["ampersand", "and", "&"]], ["shift + 8", ["asterisk", "*"]], ["shift + 9", ["openparen", "("]], ["shift + 0", ["closeparen", ")"]], ["shift + -", ["underscore", "_"]], ["shift + =", ["plus", "+"]], ["shift + (", ["opencurlybrace", "opencurlybracket", "{"]], ["shift + )", ["closecurlybrace", "closecurlybracket", "}"]], ["shift + \\", ["verticalbar", "|"]], ["shift + ;", ["colon", ":"]], ["shift + '", ["quotationmark", '"']], ["shift + !,", ["openanglebracket", "<"]], ["shift + .", ["closeanglebracket", ">"]], ["shift + /", ["questionmark", "?"]]] }; for (aI = 65; aI <= 90; aI += 1) { usLocale.map[aI] = String.fromCharCode(aI + 32); usLocale.macros.push(["shift + " + String.fromCharCode(aI + 32) + ", capslock + " + String.fromCharCode(aI + 32), [String.fromCharCode(aI)]]); } registerLocale("us", usLocale); getSetLocale("us"); enable(); KeyboardJS.enable = enable; KeyboardJS.disable = disable; KeyboardJS.activeKeys = getActiveKeys; KeyboardJS.releaseKey = removeActiveKey; KeyboardJS.pressKey = addActiveKey; KeyboardJS.on = createBinding; KeyboardJS.clear = removeBindingByKeyCombo; KeyboardJS.clear.key = removeBindingByKeyName; KeyboardJS.locale = getSetLocale; KeyboardJS.locale.register = registerLocale; KeyboardJS.macro = createMacro; KeyboardJS.macro.remove = removeMacro; KeyboardJS.key = {}; KeyboardJS.key.name = getKeyName; KeyboardJS.key.code = getKeyCode; KeyboardJS.combo = {}; KeyboardJS.combo.active = isSatisfiedCombo; KeyboardJS.combo.parse = parseKeyCombo; KeyboardJS.combo.stringify = stringifyKeyCombo; function enable() { if (window.addEventListener) { window.document.addEventListener("keydown", keydown, false); window.document.addEventListener("keyup", keyup, false); window.addEventListener("blur", reset, false); window.addEventListener("webkitfullscreenchange", reset, false); window.addEventListener("mozfullscreenchange", reset, false); } else if (window.attachEvent) { window.document.attachEvent("onkeydown", keydown); window.document.attachEvent("onkeyup", keyup); window.attachEvent("onblur", reset); } } function disable() { reset(); if (window.removeEventListener) { window.document.removeEventListener("keydown", keydown, false); window.document.removeEventListener("keyup", keyup, false); window.removeEventListener("blur", reset, false); window.removeEventListener("webkitfullscreenchange", reset, false); window.removeEventListener("mozfullscreenchange", reset, false); } else if (window.detachEvent) { window.document.detachEvent("onkeydown", keydown); window.document.detachEvent("onkeyup", keyup); window.detachEvent("onblur", reset); } } function reset(event) { activeKeys = []; pruneMacros(); pruneBindings(event); } function keydown(event) { var keyNames, keyName, kI; keyNames = getKeyName(event.keyCode); if (keyNames.length < 1) { return; } event.isRepeat = false; for (kI = 0; kI < keyNames.length; kI += 1) { keyName = keyNames[kI]; if (getActiveKeys().indexOf(keyName) != -1) event.isRepeat = true; addActiveKey(keyName); } executeMacros(); executeBindings(event); } function keyup(event) { var keyNames, kI; keyNames = getKeyName(event.keyCode); if (keyNames.length < 1) { return; } for (kI = 0; kI < keyNames.length; kI += 1) { removeActiveKey(keyNames[kI]); } pruneMacros(); pruneBindings(event); } function getKeyName(keyCode) { return map[keyCode] || []; } function getKeyCode(keyName) { var keyCode; for (keyCode in map) { if (!map.hasOwnProperty(keyCode)) { continue; } if (map[keyCode].indexOf(keyName) > -1) { return keyCode; } } return false; } function createMacro(combo, injectedKeys) { if (typeof combo !== "string" && (typeof combo !== "object" || typeof combo.push !== "function")) { throw new Error("Cannot create macro. The combo must be a string or array."); } if (typeof injectedKeys !== "object" || typeof injectedKeys.push !== "function") { throw new Error("Cannot create macro. The injectedKeys must be an array."); } macros.push([combo, injectedKeys]); } function removeMacro(combo) { var macro, mI; if (typeof combo !== "string" && (typeof combo !== "object" || typeof combo.push !== "function")) { throw new Error("Cannot remove macro. The combo must be a string or array."); } for (mI = 0; mI < macros.length; mI += 1) { macro = macros[mI]; if (compareCombos(combo, macro[0])) { removeActiveKey(macro[1]); macros.splice(mI, 1); break; } } } function executeMacros() { var mI, combo, kI; for (mI = 0; mI < macros.length; mI += 1) { combo = parseKeyCombo(macros[mI][0]); if (activeMacros.indexOf(macros[mI]) === -1 && isSatisfiedCombo(combo)) { activeMacros.push(macros[mI]); for (kI = 0; kI < macros[mI][1].length; kI += 1) { addActiveKey(macros[mI][1][kI]); } } } } function pruneMacros() { var mI, combo, kI; for (mI = 0; mI < activeMacros.length; mI += 1) { combo = parseKeyCombo(activeMacros[mI][0]); if (isSatisfiedCombo(combo) === false) { for (kI = 0; kI < activeMacros[mI][1].length; kI += 1) { removeActiveKey(activeMacros[mI][1][kI]); } activeMacros.splice(mI, 1); mI -= 1; } } } function createBinding(keyCombo, keyDownCallback, keyUpCallback) { var api = {}, binding, subBindings = [], bindingApi = {}, kI, subCombo; if (typeof keyCombo === "string") { keyCombo = parseKeyCombo(keyCombo); } for (kI = 0; kI < keyCombo.length; kI += 1) { binding = {}; subCombo = stringifyKeyCombo([keyCombo[kI]]); if (typeof subCombo !== "string") { throw new Error("Failed to bind key combo. The key combo must be string."); } binding.keyCombo = subCombo; binding.keyDownCallback = []; binding.keyUpCallback = []; if (keyDownCallback) { binding.keyDownCallback.push(keyDownCallback); } if (keyUpCallback) { binding.keyUpCallback.push(keyUpCallback); } bindings.push(binding); subBindings.push(binding); } api.clear = clear; api.on = on; return api; function clear() { var bI; for (bI = 0; bI < subBindings.length; bI += 1) { bindings.splice(bindings.indexOf(subBindings[bI]), 1); } } function on(eventName) { var api = {}, callbacks, cI, bI; if (typeof eventName !== "string") { throw new Error("Cannot bind callback. The event name must be a string."); } if (eventName !== "keyup" && eventName !== "keydown") { throw new Error('Cannot bind callback. The event name must be a "keyup" or "keydown".'); } callbacks = Array.prototype.slice.apply(arguments, [1]); for (cI = 0; cI < callbacks.length; cI += 1) { if (typeof callbacks[cI] === "function") { if (eventName === "keyup") { for (bI = 0; bI < subBindings.length; bI += 1) { subBindings[bI].keyUpCallback.push(callbacks[cI]); } } else if (eventName === "keydown") { for (bI = 0; bI < subBindings.length; bI += 1) { subBindings[bI].keyDownCallback.push(callbacks[cI]); } } } } api.clear = clear; return api; function clear() { var cI, bI; for (cI = 0; cI < callbacks.length; cI += 1) { if (typeof callbacks[cI] === "function") { if (eventName === "keyup") { for (bI = 0; bI < subBindings.length; bI += 1) { subBindings[bI].keyUpCallback.splice(subBindings[bI].keyUpCallback.indexOf(callbacks[cI]), 1); } } else { for (bI = 0; bI < subBindings.length; bI += 1) { subBindings[bI].keyDownCallback.splice(subBindings[bI].keyDownCallback.indexOf(callbacks[cI]), 1); } } } } } } } function removeBindingByKeyCombo(keyCombo) { var bI, binding, keyName; for (bI = 0; bI < bindings.length; bI += 1) { binding = bindings[bI]; if (compareCombos(keyCombo, binding.keyCombo)) { bindings.splice(bI, 1); bI -= 1; } } } function removeBindingByKeyName(keyName) { var bI, kI, binding; if (keyName) { for (bI = 0; bI < bindings.length; bI += 1) { binding = bindings[bI]; for (kI = 0; kI < binding.keyCombo.length; kI += 1) { if (binding.keyCombo[kI].indexOf(keyName) > -1) { bindings.splice(bI, 1); bI -= 1; break; } } } } else { bindings = []; } } function executeBindings(event) { var bI, sBI, binding, bindingKeys, remainingKeys, cI, killEventBubble, kI, bindingKeysSatisfied, index, sortedBindings = [], bindingWeight; remainingKeys = [].concat(activeKeys); for (bI = 0; bI < bindings.length; bI += 1) { bindingWeight = extractComboKeys(bindings[bI].keyCombo).length; if (!sortedBindings[bindingWeight]) { sortedBindings[bindingWeight] = []; } sortedBindings[bindingWeight].push(bindings[bI]); } for (sBI = sortedBindings.length - 1; sBI >= 0; sBI -= 1) { if (!sortedBindings[sBI]) { continue; } for (bI = 0; bI < sortedBindings[sBI].length; bI += 1) { binding = sortedBindings[sBI][bI]; bindingKeys = extractComboKeys(binding.keyCombo); bindingKeysSatisfied = true; for (kI = 0; kI < bindingKeys.length; kI += 1) { if (remainingKeys.indexOf(bindingKeys[kI]) === -1) { bindingKeysSatisfied = false; break; } } if (bindingKeysSatisfied && isSatisfiedCombo(binding.keyCombo)) { activeBindings.push(binding); for (kI = 0; kI < bindingKeys.length; kI += 1) { index = remainingKeys.indexOf(bindingKeys[kI]); if (index > -1) { remainingKeys.splice(index, 1); kI -= 1; } } for (cI = 0; cI < binding.keyDownCallback.length; cI += 1) { if (binding.keyDownCallback[cI](event, getActiveKeys(), binding.keyCombo) === false) { killEventBubble = true; } } if (killEventBubble === true) { event.preventDefault(); event.stopPropagation(); } } } } } function pruneBindings(event) { var bI, cI, binding, killEventBubble; for (bI = 0; bI < activeBindings.length; bI += 1) { binding = activeBindings[bI]; if (isSatisfiedCombo(binding.keyCombo) === false) { for (cI = 0; cI < binding.keyUpCallback.length; cI += 1) { if (binding.keyUpCallback[cI](event, getActiveKeys(), binding.keyCombo) === false) { killEventBubble = true; } } if (killEventBubble === true) { event.preventDefault(); event.stopPropagation(); } activeBindings.splice(bI, 1); bI -= 1; } } } function compareCombos(keyComboArrayA, keyComboArrayB) { var cI, sI, kI; keyComboArrayA = parseKeyCombo(keyComboArrayA); keyComboArrayB = parseKeyCombo(keyComboArrayB); if (keyComboArrayA.length !== keyComboArrayB.length) { return false; } for (cI = 0; cI < keyComboArrayA.length; cI += 1) { if (keyComboArrayA[cI].length !== keyComboArrayB[cI].length) { return false; } for (sI = 0; sI < keyComboArrayA[cI].length; sI += 1) { if (keyComboArrayA[cI][sI].length !== keyComboArrayB[cI][sI].length) { return false; } for (kI = 0; kI < keyComboArrayA[cI][sI].length; kI += 1) { if (keyComboArrayB[cI][sI].indexOf(keyComboArrayA[cI][sI][kI]) === -1) { return false; } } } } return true; } function isSatisfiedCombo(keyCombo) { var cI, sI, stage, kI, stageOffset = 0, index, comboMatches; keyCombo = parseKeyCombo(keyCombo); for (cI = 0; cI < keyCombo.length; cI += 1) { comboMatches = true; stageOffset = 0; for (sI = 0; sI < keyCombo[cI].length; sI += 1) { stage = [].concat(keyCombo[cI][sI]); for (kI = stageOffset; kI < activeKeys.length; kI += 1) { index = stage.indexOf(activeKeys[kI]); if (index > -1) { stage.splice(index, 1); stageOffset = kI; } } if (stage.length !== 0) { comboMatches = false; break; } } if (comboMatches) { return true; } } return false; } function extractComboKeys(keyCombo) { var cI, sI, kI, keys = []; keyCombo = parseKeyCombo(keyCombo); for (cI = 0; cI < keyCombo.length; cI += 1) { for (sI = 0; sI < keyCombo[cI].length; sI += 1) { keys = keys.concat(keyCombo[cI][sI]); } } return keys; } function parseKeyCombo(keyCombo) { var s = keyCombo, i = 0, op = 0, ws = false, nc = false, combos = [], combo = [], stage = [], key = ""; if (typeof keyCombo === "object" && typeof keyCombo.push === "function") { return keyCombo; } if (typeof keyCombo !== "string") { throw new Error('Cannot parse "keyCombo" because its type is "' + typeof keyCombo + '". It must be a "string".'); } while (s.charAt(i) === " ") { i += 1; } while (true) { if (s.charAt(i) === " ") { while (s.charAt(i) === " ") { i += 1; } ws = true; } else if (s.charAt(i) === ",") { if (op || nc) { throw new Error("Failed to parse key combo. Unexpected , at character index " + i + "."); } nc = true; i += 1; } else if (s.charAt(i) === "+") { if (key.length) { stage.push(key); key = ""; } if (op || nc) { throw new Error("Failed to parse key combo. Unexpected + at character index " + i + "."); } op = true; i += 1; } else if (s.charAt(i) === ">") { if (key.length) { stage.push(key); key = ""; } if (stage.length) { combo.push(stage); stage = []; } if (op || nc) { throw new Error("Failed to parse key combo. Unexpected > at character index " + i + "."); } op = true; i += 1; } else if (i < s.length - 1 && s.charAt(i) === "!" && (s.charAt(i + 1) === ">" || s.charAt(i + 1) === "," || s.charAt(i + 1) === "+")) { key += s.charAt(i + 1); op = false; ws = false; nc = false; i += 2; } else if (i < s.length && s.charAt(i) !== "+" && s.charAt(i) !== ">" && s.charAt(i) !== "," && s.charAt(i) !== " ") { if (op === false && ws === true || nc === true) { if (key.length) { stage.push(key); key = ""; } if (stage.length) { combo.push(stage); stage = []; } if (combo.length) { combos.push(combo); combo = []; } } op = false; ws = false; nc = false; while (i < s.length && s.charAt(i) !== "+" && s.charAt(i) !== ">" && s.charAt(i) !== "," && s.charAt(i) !== " ") { key += s.charAt(i); i += 1; } } else { i += 1; continue; } if (i >= s.length) { if (key.length) { stage.push(key); key = ""; } if (stage.length) { combo.push(stage); stage = []; } if (combo.length) { combos.push(combo); combo = []; } break; } } return combos; } function stringifyKeyCombo(keyComboArray) { var cI, ccI, output = []; if (typeof keyComboArray === "string") { return keyComboArray; } if (typeof keyComboArray !== "object" || typeof keyComboArray.push !== "function") { throw new Error("Cannot stringify key combo."); } for (cI = 0; cI < keyComboArray.length; cI += 1) { output[cI] = []; for (ccI = 0; ccI < keyComboArray[cI].length; ccI += 1) { output[cI][ccI] = keyComboArray[cI][ccI].join(" + "); } output[cI] = output[cI].join(" > "); } return output.join(" "); } function getActiveKeys() { return [].concat(activeKeys); } function addActiveKey(keyName) { if (keyName.match(/\s/)) { throw new Error("Cannot add key name " + keyName + " to active keys because it contains whitespace."); } if (activeKeys.indexOf(keyName) > -1) { return; } activeKeys.push(keyName); } function removeActiveKey(keyName) { var keyCode = getKeyCode(keyName); if (keyCode === "91" || keyCode === "92") { activeKeys = []; } else { activeKeys.splice(activeKeys.indexOf(keyName), 1); } } function registerLocale(localeName, localeMap) { if (typeof localeName !== "string") { throw new Error("Cannot register new locale. The locale name must be a string."); } if (typeof localeMap !== "object") { throw new Error("Cannot register " + localeName + " locale. The locale map must be an object."); } if (typeof localeMap.map !== "object") { throw new Error("Cannot register " + localeName + " locale. The locale map is invalid."); } if (!localeMap.macros) { localeMap.macros = []; } locales[localeName] = localeMap; } function getSetLocale(localeName) { if (localeName) { if (typeof localeName !== "string") { throw new Error("Cannot set locale. The locale name must be a string."); } if (!locales[localeName]) { throw new Error("Cannot set locale to " + localeName + " because it does not exist. If you would like to submit a " + localeName + " locale map for KeyboardJS please submit it at https://github.com/RobertWHurst/KeyboardJS/issues."); } map = locales[localeName].map; macros = locales[localeName].macros; locale = localeName; } return locale; } this.Keyboard = KeyboardJS; }, "on": function(keyCombo, onDownCallback, onUpCallback) { this.Keyboard.on(keyCombo, onDownCallback, onUpCallback); }, "getActiveKeys": function() { return this.Keyboard.activeKeys(); } }});//begin-------------------AlloyPaper.Loader---------------------beginAlloyPaper.Loader = Class.extend({ "ctor": function() { this.res = {}; this.loadedCount = 0; this.resCount = -1; this.FILE_PATTERN = /(\w+:\/{2})?((?:\w+\.){2}\w+)?(\/?[\S]+\/|\/)?([\w\-%\.]+)(?:\.)(\w+)?(\?\S+)?/i; this.ns = 6; this.sounds = []; for (var i = 0; i < this.ns; i++) this.sounds.push([]); this.playing = []; }, "get": function(id) { return this.res[id]; }, "loadRes2": function(arr) { this.resCount = arr.length; for (var i = 0; i < arr.length; i++) {this.loadImage(arr[i].id, arr[i].src); } }, "loadRes": function(arr) { this.resCount = arr.length; for (var i = 0; i < arr.length; i++) { var type=this._getTypeByExtension(arr[i].src.match(this.FILE_PATTERN)[5]); if (type === "audio") { this.loadAudio(arr[i].id, arr[i].src); } else if (type === "js") { this.loadScript(arr[i].src); } else if (type === "img") { this.loadImage(arr[i].id, arr[i].src); } } }, "loadImage": function(id, src) { var img = document.createElement("img"); var self = this; img.onload = function() { self._handleLoad(this, id); img.onreadystatechange = null; }; img.onreadystatechange = function() { if (img.readyState == "loaded" || img.readyState == "complete") { self._handleLoad(this, id); img.onload = null; } }; img.onerror = function() {}; img.src = src; }, "loadAudio": function(id, src) { var tag = document.createElement("audio"); tag.autoplay = false; this.res[id] = tag; tag.src = null; tag.preload = "auto"; tag.onerror = function() {}; tag.onstalled = function() {}; var self = this; var _audioCanPlayHandler = function() { self.playing[id] = 0; for (var i = 0; i < self.ns; i++) { self.sounds[i][id] = new Audio(src); } self.loadedCount++; self.handleProgress&&self.handleProgress(self.loadedCount, self.resCount); self._clean(this); this.removeEventListener && this.removeEventListener("canplaythrough", _audioCanPlayHandler, false); self.checkComplete(); }; tag.addEventListener("canplaythrough", _audioCanPlayHandler, false); tag.src = src; if (tag.load != null) { tag.load(); } }, "loadScript": function (url) { var script = document.createElement("script"); script.type = "text/javascript"; var self = this; if (script.readyState) { //IE script.onreadystatechange = function () { if (script.readyState == "loaded" || script.readyState == "complete") { script.onreadystatechange = null; self._handleLoad(); } }; } else { //Others script.onload = function () { self._handleLoad(); }; } script.src = url; document.getElementsByTagName("head")[0].appendChild(script); }, "checkComplete": function() { if (this.loadedCount === this.resCount) { this.handleComplete(); } }, "complete": function(fn) { this.handleComplete = fn; }, "progress": function(fn) { this.handleProgress = fn; }, "playSound": function (id, volume) { var sound = this.sounds[this.playing[id]][id]; sound.volume = volume === undefined ? 1 : volume; sound.play(); ++this.playing[id]; if (this.playing[id] >= this.ns) this.playing[id] = 0; }, "_handleLoad": function (currentImg, id) { if (currentImg) { this._clean(currentImg); this.res[id] = currentImg; } this.loadedCount++; if (this.handleProgress) this.handleProgress(this.loadedCount, this.resCount); this.checkComplete(); }, "_getTypeByExtension": function(extension) { switch (extension) { case "jpeg": case "jpg": case "gif": case "png": case "webp": case "bmp": return "img"; case "ogg": case "mp3": case "wav": return "audio"; case "js": return "js"; } }, "_clean": function(tag) { tag.onload = null; tag.onstalled = null; tag.onprogress = null; tag.onerror = null; }});//end-------------------AlloyPaper.Loader---------------------end//begin-------------------AlloyPaper.Matrix2D---------------------beginAlloyPaper.Matrix2D = Class.extend({ "statics": { "DEG_TO_RAD": 0.017453292519943295 }, "ctor": function(a, b, c, d, tx, ty) { this.a = a == null ? 1 : a; this.b = b || 0; this.c = c || 0; this.d = d == null ? 1 : d; this.tx = tx || 0; this.ty = ty || 0; return this; }, "identity": function() { this.a = this.d = 1; this.b = this.c = this.tx = this.ty = 0; return this; }, "appendTransform": function(x, y, scaleX, scaleY, rotation, skewX, skewY, regX, regY) { if (rotation % 360) { var r = rotation * AlloyPaper.Matrix2D.DEG_TO_RAD; var cos = Math.cos(r); var sin = Math.sin(r); } else { cos = 1; sin = 0; } if (skewX || skewY) { skewX *= AlloyPaper.Matrix2D.DEG_TO_RAD; skewY *= AlloyPaper.Matrix2D.DEG_TO_RAD; this.append(Math.cos(skewY), Math.sin(skewY), -Math.sin(skewX), Math.cos(skewX), x, y); this.append(cos * scaleX, sin * scaleX, -sin * scaleY, cos * scaleY, 0, 0); } else { this.append(cos * scaleX, sin * scaleX, -sin * scaleY, cos * scaleY, x, y); } if (regX || regY) { this.tx -= regX * this.a + regY * this.c; this.ty -= regX * this.b + regY * this.d; } return this; }, "append": function(a, b, c, d, tx, ty) { var a1 = this.a; var b1 = this.b; var c1 = this.c; var d1 = this.d; this.a = a * a1 + b * c1; this.b = a * b1 + b * d1; this.c = c * a1 + d * c1; this.d = c * b1 + d * d1; this.tx = tx * a1 + ty * c1 + this.tx; this.ty = tx * b1 + ty * d1 + this.ty; return this; }, "initialize": function(a, b, c, d, tx, ty) { this.a = a; this.b = b; this.c = c; this.d = d; this.tx = tx; this.ty = ty; return this; }, "setValues": function(a, b, c, d, tx, ty) { this.a = a == null ? 1 : a; this.b = b || 0; this.c = c || 0; this.d = d == null ? 1 : d; this.tx = tx || 0; this.ty = ty || 0; return this; }, "copy": function(matrix) { return this.setValues(matrix.a, matrix.b, matrix.c, matrix.d, matrix.tx, matrix.ty); }});//end-------------------AlloyPaper.Matrix2D---------------------end(function () { var observe = function (target, arr, callback) { var _observe = function (target, arr, callback) { if (!target.$observer) target.$observer = this; var $observer = target.$observer; var eventPropArr = []; if (observe.isArray(target)) { $observer.mock(target); } for (var prop in target) { if (target.hasOwnProperty(prop)) { if (callback) { if (observe.isArray(arr) && observe.isInArray(arr, prop)) { eventPropArr.push(prop); $observer.watch(target, prop); } else if (observe.isString(arr) && prop == arr) { eventPropArr.push(prop); $observer.watch(target, prop); } } else { eventPropArr.push(prop); $observer.watch(target, prop); } } } $observer.target = target; if (!$observer.propertyChangedHandler) $observer.propertyChangedHandler = []; var propChanged = callback ? callback : arr; $observer.propertyChangedHandler.push({ all: !callback, propChanged: propChanged, eventPropArr: eventPropArr }); }; _observe.prototype = { "onPropertyChanged": function (prop, value, oldValue, target, path) { if (value !== oldValue && this.propertyChangedHandler) { var rootName = observe._getRootName(prop, path); for (var i = 0, len = this.propertyChangedHandler.length; i < len; i++) { var handler = this.propertyChangedHandler[i]; if (handler.all || observe.isInArray(handler.eventPropArr, rootName) || rootName.indexOf("Array-") === 0) { handler.propChanged.call(this.target, prop, value, oldValue, path); } } } if (prop.indexOf("Array-") !== 0 && typeof value === "object") { this.watch(target, prop, target.$observeProps.$observerPath); } }, "mock": function (target) { var self = this; observe.methods.forEach(function (item) { target[item] = function () { var old = Array.prototype.slice.call(this, 0); var result = Array.prototype[item].apply(this, Array.prototype.slice.call(arguments)); if (new RegExp("\\b" + item + "\\b").test(observe.triggerStr)) { for (var cprop in this) { if (this.hasOwnProperty(cprop) && !observe.isFunction(this[cprop])) { self.watch(this, cprop, this.$observeProps.$observerPath); } } //todo self.onPropertyChanged("Array-" + item, this, old, this, this.$observeProps.$observerPath); } return result; }; }); }, "watch": function (target, prop, path) { if (prop === "$observeProps" || prop === "$observer") return; if (observe.isFunction(target[prop])) return; if (!target.$observeProps) target.$observeProps = {}; if (path !== undefined) { target.$observeProps.$observerPath = path; } else { target.$observeProps.$observerPath = "#"; } var self = this; var currentValue = target.$observeProps[prop] = target[prop]; Object.defineProperty(target, prop, { get: function () { return this.$observeProps[prop]; }, set: function (value) { var old = this.$observeProps[prop]; this.$observeProps[prop] = value; self.onPropertyChanged(prop, value, old, this, target.$observeProps.$observerPath); } }); if (typeof currentValue == "object") { if (observe.isArray(currentValue)) { this.mock(currentValue); } for (var cprop in currentValue) { if (currentValue.hasOwnProperty(cprop)) { this.watch(currentValue, cprop, target.$observeProps.$observerPath + "-" + prop); } } } } }; return new _observe(target, arr, callback) }; observe.methods = ["concat", "every", "filter", "forEach", "indexOf", "join", "lastIndexOf", "map", "pop", "push", "reduce", "reduceRight", "reverse", "shift", "slice", "some", "sort", "splice", "unshift", "toLocaleString", "toString", "size"]; observe.triggerStr = ["concat", "pop", "push", "reverse", "shift", "sort", "splice", "unshift", "size"].join(","); observe.isArray = function (obj) { return Object.prototype.toString.call(obj) === '[object Array]'; }; observe.isString = function (obj) { return typeof obj === "string"; }; observe.isInArray = function (arr, item) { for (var i = arr.length; --i > -1;) { if (item === arr[i]) return true; } return false; }; observe.isFunction = function (obj) { return Object.prototype.toString.call(obj) == '[object Function]'; }; observe.twoWay = function (objA, aProp, objB, bProp) { if (typeof objA[aProp] === "object" && typeof objB[bProp] === "object") { observe(objA, aProp, function (name, value) { objB[bProp] = this[aProp]; }) observe(objB, bProp, function (name, value) { objA[aProp] = this[bProp]; }) } else { observe(objA, aProp, function (name, value) { objB[bProp] = value; }) observe(objB, bProp, function (name, value) { objA[aProp] = value; }) } } observe._getRootName = function (prop, path) { if (path === "#") { return prop; } return path.split("-")[1]; } observe.add = function (obj, prop, value) { obj[prop] = value; var $observer = obj.$observer; $observer.watch(obj, prop); } Array.prototype.size = function (length) { this.length = length; } AlloyPaper.Observe = observe;})();//begin-------------------AlloyPaper.RAF---------------------beginAlloyPaper.RAF = Class.extend({ "statics": { "ctor": function() { var requestAnimFrame = function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback, element) { window.setTimeout(callback, 1e3 / 60); }; }(); var requestInterval = function(fn, delay) { if (!window.requestAnimationFrame && !window.webkitRequestAnimationFrame && !(window.mozRequestAnimationFrame && window.mozCancelRequestAnimationFrame) && !window.oRequestAnimationFrame && !window.msRequestAnimationFrame) return window.setInterval(fn, delay); var start = new Date().getTime(), handle = {}; function loop() { var current = new Date().getTime(), delta = current - start; if (delta >= delay) { fn.call(); start = new Date().getTime(); } handle.value = requestAnimFrame(loop); } handle.value = requestAnimFrame(loop); return handle; }; var clearRequestInterval = function(handle) { if (handle) { setTimeout(function() { window.cancelAnimationFrame ? window.cancelAnimationFrame(handle.value) : window.webkitCancelAnimationFrame ? window.webkitCancelAnimationFrame(handle.value) : window.webkitCancelRequestAnimationFrame ? window.webkitCancelRequestAnimationFrame(handle.value) : window.mozCancelRequestAnimationFrame ? window.mozCancelRequestAnimationFrame(handle.value) : window.oCancelRequestAnimationFrame ? window.oCancelRequestAnimationFrame(handle.value) : window.msCancelRequestAnimationFrame ? window.msCancelRequestAnimationFrame(handle.value) : clearInterval(handle); }, 0); } }; this.requestInterval = requestInterval; this.clearRequestInterval = clearRequestInterval; } }});//end-------------------AlloyPaper.RAF---------------------end//begin-------------------AlloyPaper.To---------------------beginAlloyPaper.To = Class.extend({ "statics": { "ctor": function () { this.bounceOut = AlloyPaper.TWEEN.Easing.Bounce.Out, this.linear = AlloyPaper.TWEEN.Easing.Linear.None, this.quadraticIn = AlloyPaper.TWEEN.Easing.Quadratic.In, this.quadraticOut = AlloyPaper.TWEEN.Easing.Quadratic.Out, this.quadraticInOut = AlloyPaper.TWEEN.Easing.Quadratic.InOut, this.cubicIn = AlloyPaper.TWEEN.Easing.Cubic.In, this.cubicOut = AlloyPaper.TWEEN.Easing.Cubic.Out, this.cubicInOut = AlloyPaper.TWEEN.Easing.Cubic.InOut, this.quarticIn = AlloyPaper.TWEEN.Easing.Quartic.In, this.quarticOut = AlloyPaper.TWEEN.Easing.Quartic.Out, this.quarticInOut = AlloyPaper.TWEEN.Easing.Quartic.InOut, this.quinticIn = AlloyPaper.TWEEN.Easing.Quintic.In, this.quinticOut = AlloyPaper.TWEEN.Easing.Quintic.Out, this.quinticInOut = AlloyPaper.TWEEN.Easing.Quintic.InOut, this.sinusoidalIn = AlloyPaper.TWEEN.Easing.Sinusoidal.In, this.sinusoidalOut = AlloyPaper.TWEEN.Easing.Sinusoidal.Out, this.sinusoidalInOut = AlloyPaper.TWEEN.Easing.Sinusoidal.InOut, this.exponentialIn = AlloyPaper.TWEEN.Easing.Exponential.In, this.exponentialOut = AlloyPaper.TWEEN.Easing.Exponential.Out, this.exponentialInOut = AlloyPaper.TWEEN.Easing.Exponential.InOut, this.circularIn = AlloyPaper.TWEEN.Easing.Circular.In, this.circularOut = AlloyPaper.TWEEN.Easing.Circular.Out, this.circularInOut = AlloyPaper.TWEEN.Easing.Circular.InOut, this.elasticIn = AlloyPaper.TWEEN.Easing.Elastic.In, this.elasticOut = AlloyPaper.TWEEN.Easing.Elastic.Out, this.elasticInOut = AlloyPaper.TWEEN.Easing.Elastic.InOut, this.backIn = AlloyPaper.TWEEN.Easing.Back.In, this.backOut = AlloyPaper.TWEEN.Easing.Back.Out, this.backInOut = AlloyPaper.TWEEN.Easing.Back.InOut, this.bounceIn = AlloyPaper.TWEEN.Easing.Bounce.In, this.bounceOut = AlloyPaper.TWEEN.Easing.Bounce.Out, this.bounceInOut = AlloyPaper.TWEEN.Easing.Bounce.InOut, this.interpolationLinear = AlloyPaper.TWEEN.Interpolation.Linear, this.interpolationBezier = AlloyPaper.TWEEN.Interpolation.Bezier, this.interpolationCatmullRom = AlloyPaper.TWEEN.Interpolation.CatmullRom; }, "get": function (element) { var to = new this(element); var stage = this.getStage(element); stage && stage.toList.push(to); return to; }, "getStage": function (element) { if (!element.parent) return; if (element.parent instanceof AlloyPaper.Stage) { return element.parent; } else { return this.getStage(element.parent); } } }, "ctor": function(element) { this.element = element; this.cmds = []; this.index = 0; this.tweens = []; this._pause = false; this.loop = setInterval(function() { AlloyPaper.TWEEN.update(); }, 15); this.cycleCount = 0; }, "to": function() { this.cmds.push(["to"]); return this; }, "set": function(prop, value, time, ease) { this.cmds[this.cmds.length - 1].push([prop, [value, time, ease]]); return this; }, "x": function() { this.cmds[this.cmds.length - 1].push(["x", arguments]); return this; }, "y": function() { this.cmds[this.cmds.length - 1].push(["y", arguments]); return this; }, "z": function() { this.cmds[this.cmds.length - 1].push(["z", arguments]); return this; }, "rotation": function() { this.cmds[this.cmds.length - 1].push(["rotation", arguments]); return this; }, "scaleX": function() { this.cmds[this.cmds.length - 1].push(["scaleX", arguments]); return this; }, "scaleY": function() { this.cmds[this.cmds.length - 1].push(["scaleY", arguments]); return this; }, "skewX": function() { this.cmds[this.cmds.length - 1].push(["skewX", arguments]); return this; }, "skewY": function() { this.cmds[this.cmds.length - 1].push(["skewY", arguments]); return this; }, "originX": function() { this.cmds[this.cmds.length - 1].push(["originX", arguments]); return this; }, "originY": function() { this.cmds[this.cmds.length - 1].push(["originY", arguments]); return this; }, "alpha": function() { this.cmds[this.cmds.length - 1].push(["alpha", arguments]); return this; }, "begin": function(fn) { this.cmds[this.cmds.length - 1].begin = fn; return this; }, "progress": function(fn) { this.cmds[this.cmds.length - 1].progress = fn; return this; }, "end": function(fn) { this.cmds[this.cmds.length - 1].end = fn; return this; }, "wait": function() { this.cmds.push(["wait", arguments]); return this; }, "then": function() { this.cmds.push(["then", arguments]); return this; }, "cycle": function() { this.cmds.push(["cycle", arguments]); return this; }, "rubber": function() { this.cmds = this.cmds.concat([["to", ["scaleX", { "0": 1.25, "1": 300}], ["scaleY", { "0": .75, "1": 300}]], ["to", ["scaleX", { "0": .75, "1": 100}], ["scaleY", { "0": 1.25, "1": 100}]], ["to", ["scaleX", { "0": 1.15, "1": 100}], ["scaleY", { "0": .85, "1": 100}]], ["to", ["scaleX", { "0": .95, "1": 150}], ["scaleY", { "0": 1.05, "1": 150}]], ["to", ["scaleX", { "0": 1.05, "1": 100}], ["scaleY", { "0": .95, "1": 100}]], ["to", ["scaleX", { "0": 1, "1": 250}], ["scaleY", { "0": 1, "1": 250}]]]); return this; }, "bounceIn": function() { this.cmds = this.cmds.concat([["to", ["scaleX", { "0": 0, "1": 0}], ["scaleY", { "0": 0, "1": 0}]], ["to", ["scaleX", { "0": 1.35, "1": 200}], ["scaleY", { "0": 1.35, "1": 200}]], ["to", ["scaleX", { "0": .9, "1": 100}], ["scaleY", { "0": .9, "1": 100}]], ["to", ["scaleX", { "0": 1.1, "1": 100}], ["scaleY", { "0": 1.1, "1": 100}]], ["to", ["scaleX", { "0": .95, "1": 100}], ["scaleY", { "0": .95, "1": 100}]], ["to", ["scaleX", { "0": 1, "1": 100}], ["scaleY", { "0": 1, "1": 100}]]]); return this; }, "flipInX": function() { this.cmds = this.cmds.concat([["to", ["rotateX", { "0": -90, "1": 0}]], ["to", ["rotateX", { "0": 20, "1": 300}]], ["to", ["rotateX", { "0": -20, "1": 300}]], ["to", ["rotateX", { "0": 10, "1": 300}]], ["to", ["rotateX", { "0": -5, "1": 300}]], ["to", ["rotateX", { "0": 0, "1": 300}]]]); return this; }, "zoomOut": function() { this.cmds = this.cmds.concat([["to", ["scaleX", { "0": 0, "1": 400}], ["scaleY", { "0": 0, "1": 400}]]]); return this; }, "start": function() { if (this._pause) return; var len = this.cmds.length; if (this.index < len) { this.exec(this.cmds[this.index], this.index == len - 1); } else { clearInterval(this.loop); } return this; }, "pause": function() { this._pause = true; for (var i = 0, len = this.tweens.length; i < len; i++) { this.tweens[i].pause(); } if (this.currentTask == "wait") { this.timeout -= new Date() - this.currentTaskBegin; this.currentTaskBegin = new Date(); } }, "toggle": function() { if (this._pause) { this.play(); } else { this.pause(); } }, "play": function() { this._pause = false; for (var i = 0, len = this.tweens.length; i < len; i++) { this.tweens[i].play(); } var self = this; if (this.currentTask == "wait") { setTimeout(function() { if (self._pause) return; self.index++; self.start(); if (self.index == self.cmds.length && self.complete) self.complete(); }, this.timeout); } }, "stop": function () { for (var i = 0, len = this.tweens.length; i < len; i++) { this.tweens[i].pause(); AlloyPaper.TWEEN.remove(this.tweens[i]); } this.cmds.length = 0; }, "exec": function(cmd, last) { var len = cmd.length, self = this; this.currentTask = cmd[0]; switch (this.currentTask) { case "to": self.stepCompleteCount = 0; for (var i = 1; i < len; i++) { var task = cmd[i]; var ease = task[1][2]; var target = {}; var prop = task[0]; target[prop] = task[1][0]; var t = new AlloyPaper.TWEEN.Tween(this.element).to(target, task[1][1]).onStart(function() { if (cmd.start) cmd.start(); }).onUpdate(function() { if (cmd.progress) cmd.progress.call(self.element); self.element[prop] = this[prop]; }).easing(ease ? ease : AlloyPaper.To.linear).onComplete(function() { self.stepCompleteCount++; if (self.stepCompleteCount == len - 1) { if (cmd.end) cmd.end.call(self.element); if (last && self.complete) self.complete(); self.index++; self.start(); } }).start(); this.tweens.push(t); } break; case "wait": this.currentTaskBegin = new Date(); this.timeout = cmd[1][0]; setTimeout(function() { if (self._pause) return; self.index++; self.start(); if (cmd.end) cmd.end.call(self.element); if (last && self.complete) self.complete(); }, cmd[1][0]); break; case "then": var arg = cmd[1][0]; arg.index = 0; arg.complete = function() { self.index++; self.start(); if (last && self.complete) self.complete(); }; arg.start(); break; case "cycle": var count = cmd[1][1]; if (count && self.cycleCount == count) { self.index++; self.start(); if (last && self.complete) self.complete(); } else { self.cycleCount++; self.index = cmd[1][0]; self.start(); } break; } }});//end-------------------AlloyPaper.To---------------------end//begin-------------------AlloyPaper.UID---------------------beginAlloyPaper.UID = Class.extend({ "statics": { "_nextID": 0, "_nextCacheID": 1, "get": function() { return this._nextID++; }, "getCacheID": function() { return this._nextCacheID++; } }});//end-------------------AlloyPaper.UID---------------------end//begin-------------------AlloyPaper.Util---------------------beginAlloyPaper.Util = Class.extend({ "statics": { "random": function(min, max) { return min + Math.floor(Math.random() * (max - min + 1)); } }});//end-------------------AlloyPaper.Util---------------------end//begin-------------------AlloyPaper.Vector2---------------------beginAlloyPaper.Vector2 = Class.extend({ "ctor": function(x, y) { this.x = x; this.y = y; }, "copy": function() { return new AlloyPaper.Vector2(this.x, this.y); }, "length": function() { return Math.sqrt(this.x * this.x + this.y * this.y); }, "sqrLength": function() { return this.x * this.x + this.y * this.y; }, "normalize": function() { var inv = 1 / this.length(); return new AlloyPaper.Vector2(this.x * inv, this.y * inv); }, "negate": function() { return new AlloyPaper.Vector2(-this.x, -this.y); }, "add": function(v) { this.x += v.x; this.y += v.y; }, "subtract": function(v) { return new AlloyPaper.Vector2(this.x - v.x, this.y - v.y); }, "multiply": function(f) { return new AlloyPaper.Vector2(this.x * f, this.y * f); }, "divide": function(f) { var invf = 1 / f; return new AlloyPaper.Vector2(this.x * invf, this.y * invf); }, "dot": function(v) { return this.x * v.x + this.y * v.y; }});//end-------------------AlloyPaper.Vector2---------------------end//begin-------------------AlloyPaper.Renderer---------------------beginAlloyPaper.Renderer = Class.extend({ "ctor": function (stage, openWebGL) { this.stage = stage; this.objs = []; this.width = this.stage.width; this.height = this.stage.height; this.mainCanvas = this.stage.canvas; var canvasSupport = !! window.CanvasRenderingContext2D, webglSupport = function() { try { var canvas = document.createElement("canvas"); return !!(window.WebGLRenderingContext && (canvas.getContext("webgl") || canvas.getContext("experimental-webgl"))); } catch (e) { return false; } }(); if (webglSupport && openWebGL) { this.renderingEngine = new AlloyPaper.WebGLRenderer(this.stage.canvas); } else { if (canvasSupport) { this.renderingEngine = new AlloyPaper.CanvasRenderer(this.stage.canvas); } else { throw "your browser does not support canvas and webgl "; } } this.mainCtx = this.renderingEngine.ctx; }, "update": function() { var objs = this.objs, ctx = this.mainCtx, engine = this.renderingEngine; objs.length = 0; this.computeMatrix(); engine.clear(); var l = objs.length; for (var m = 0; m < l; m++) { engine.renderObj(ctx, objs[m]); } }, "computeMatrix": function() { for (var i = 0, len = this.stage.children.length; i < len; i++) { this._computeMatrix(this.stage.children[i]); } }, "initComplex": function(o) { o.complexCompositeOperation = this._getCompositeOperation(o); o.complexAlpha = this._getAlpha(o, 1); }, "_computeMatrix": function(o, mtx) { if (!o.isVisible()) { return; } if (mtx) { o._matrix.initialize(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx, mtx.ty); } else { o._matrix.initialize(1, 0, 0, 1, 0, 0); } if (o instanceof AlloyPaper.Shape) { o._matrix.appendTransform(o.x, o.y, 1, 1, o.rotation, o.skewX, o.skewY, o.regX, o.regY); } else { o._matrix.appendTransform(o.x, o.y, o.scaleX, o.scaleY, o.rotation, o.skewX, o.skewY, o.regX, o.regY); } if (o instanceof AlloyPaper.Container) { var list = o.children, len = list.length, i = 0; for (; i < len; i++) { this._computeMatrix(list[i], o._matrix); } } else { if (o instanceof AlloyPaper.Graphics || o instanceof AlloyPaper.Text) { this.objs.push(o); this.initComplex(o); } else { o.initAABB(); if (this.isInStage(o)) { this.objs.push(o); this.initComplex(o); } } } }, "_getCompositeOperation": function(o) { if (o.compositeOperation) return o.compositeOperation; if (o.parent) return this._getCompositeOperation(o.parent); }, "_getAlpha": function(o, alpha) { var result = o.alpha * alpha; if (o.parent) { return this._getAlpha(o.parent, result); } return result; }, "isInStage": function(o) { return this.collisionBetweenAABB(o.AABB, this.stage.AABB); }, "collisionBetweenAABB": function(AABB1, AABB2) { var maxX = AABB1[0] + AABB1[2]; if (maxX < AABB2[0]) return false; var minX = AABB1[0]; if (minX > AABB2[0] + AABB2[2]) return false; var maxY = AABB1[1] + AABB1[3]; if (maxY < AABB2[1]) return false; var minY = AABB1[1]; if (minY > AABB2[1] + AABB2[3]) return false; return true; }});//end-------------------AlloyPaper.Renderer---------------------end//begin-------------------AlloyPaper.CanvasRenderer---------------------beginAlloyPaper.CanvasRenderer = Class.extend({ "ctor": function(canvas) { if (canvas) { this.canvas = canvas; this.ctx = this.canvas.getContext("2d"); this.height = this.canvas.height; this.width = this.canvas.width; } }, "hitAABB": function(ctx, o, evt, type) { var list = o.children.slice(0), l = list.length; for (var i = l - 1; i >= 0; i--) { var child = list[i]; if (!this.isbindingEvent(child)) continue; var target = this._hitAABB(ctx, child, evt, type); if (target) return target; } }, "_hitAABB": function(ctx, o, evt, type) { if (!o.isVisible()) { return; } if (o instanceof AlloyPaper.Container) { var list = o.children.slice(0), l = list.length; for (var i = l - 1; i >= 0; i--) { var child = list[i]; var target = this._hitAABB(ctx, child, evt, type); if (target) return target; } } else { if (o.AABB && this.checkPointInAABB(evt.stageX, evt.stageY, o.AABB)) { this._bubbleEvent(o, type, evt); return o; } } }, "hitRender": function(ctx, o, evt, type) { var mtx = o._hitMatrix; var list = o.children.slice(0), l = list.length; for (var i = l - 1; i >= 0; i--) { var child = list[i]; mtx.initialize(1, 0, 0, 1, 0, 0); mtx.appendTransform(o.x - evt.stageX, o.y - evt.stageY, o.scaleX, o.scaleY, o.rotation, o.skewX, o.skewY, o.regX, o.regY); if (!this.isbindingEvent(child)) continue; ctx.save(); var target = this._hitRender(ctx, child, mtx, evt, type); ctx.restore(); if (target) return target; } }, "_hitRender": function(ctx, o, mtx, evt, type) { ctx.clearRect(0, 0, 2, 2); if (!o.isVisible()) { return; } if (mtx) { o._hitMatrix.initialize(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx, mtx.ty); } else { o._hitMatrix.initialize(1, 0, 0, 1, 0, 0); } mtx = o._hitMatrix; if (o instanceof AlloyPaper.Shape) { mtx.appendTransform(o.x, o.y, 1, 1, o.rotation, o.skewX, o.skewY, o.regX, o.regY); } else { mtx.appendTransform(o.x, o.y, o.scaleX, o.scaleY, o.rotation, o.skewX, o.skewY, o.regX, o.regY); } var mmyCanvas = o.cacheCanvas || o.txtCanvas || o.shapeCanvas; if (mmyCanvas) { ctx.globalAlpha = o.complexAlpha; ctx.globalCompositeOperation = o.complexCompositeOperation; ctx.setTransform(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx, mtx.ty); ctx.drawImage(mmyCanvas, 0, 0); } else if (o instanceof AlloyPaper.Container) { var list = o.children.slice(0), l = list.length; for (var i = l - 1; i >= 0; i--) { ctx.save(); var target = this._hitRender(ctx, list[i], mtx, evt, type); if (target) return target; ctx.restore(); } } else if (o instanceof AlloyPaper.Bitmap || o instanceof AlloyPaper.Sprite) { ctx.globalAlpha = o.complexAlpha; ctx.globalCompositeOperation = o.complexCompositeOperation; var rect = o.rect; ctx.setTransform(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx, mtx.ty); ctx.drawImage(o.img, rect[0], rect[1], rect[2], rect[3], 0, 0, rect[2], rect[3]); } else if (o instanceof AlloyPaper.Graphics) { ctx.setTransform(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx, mtx.ty); o.draw(ctx); } if (ctx.getImageData(0, 0, 1, 1).data[3] > 1 && !(o instanceof AlloyPaper.Container)) { this._bubbleEvent(o, type, evt); return o; } }, "_bubbleEvent": function(o, type, event) { var result = o.execEvent(type, event); if (result !== false) { if (o.parent && o.parent.events && o.parent.events[type] && o.parent.events[type].length > 0 && o.parent.baseInstanceof !== "Stage") { this._bubbleEvent(o.parent, type, event); } } }, "isbindingEvent": function(obj) { if (Object.keys(obj.events).length !== 0) return true; if (obj instanceof AlloyPaper.Container) { for (var i = 0, len = obj.children.length; i < len; i++) { var child = obj.children[i]; if (child instanceof AlloyPaper.Container) { return this.isbindingEvent(child); } else { if (Object.keys(child.events).length !== 0) return true; } } } return false; }, "clear": function() { this.ctx.clearRect(0, 0, this.width, this.height); }, "renderObj": function(ctx, o) { var mtx = o._matrix; ctx.save(); ctx.globalAlpha = o.complexAlpha; ctx.globalCompositeOperation = o.complexCompositeOperation; o.shadow && this._applyShadow(ctx, o.shadow); var mmyCanvas = o.cacheCanvas || o.txtCanvas || o.shapeCanvas; if (mmyCanvas) { ctx.setTransform(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx, mtx.ty); ctx.drawImage(mmyCanvas, 0, 0); } else if (o instanceof AlloyPaper.Bitmap || o instanceof AlloyPaper.Sprite) { if (o._clipFn) { ctx.beginPath(); o._clipFn.call(ctx); ctx.closePath(); ctx.clip(); } var rect = o.rect; ctx.setTransform(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx, mtx.ty); ctx.drawImage(o.img, rect[0], rect[1], rect[2], rect[3], 0, 0, rect[2], rect[3]); } else if (o instanceof AlloyPaper.Graphics || o instanceof AlloyPaper.Text) { ctx.setTransform(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx, mtx.ty); o.draw(ctx); } ctx.restore(); }, "_applyShadow" : function(ctx, shadow) { ctx.shadowColor = shadow.color || "transparent"; ctx.shadowOffsetX = shadow.offsetX||0; ctx.shadowOffsetY = shadow.offsetY||0; ctx.shadowBlur = shadow.blur||0; }, "clearBackUpCanvasCache": function() {}, "checkPointInAABB": function(x, y, AABB) { var minX = AABB[0]; if (x < minX) return false; var minY = AABB[1]; if (y < minY) return false; var maxX = minX + AABB[2]; if (x > maxX) return false; var maxY = minY + AABB[3]; if (y > maxY) return false; return true; }});//end-------------------AlloyPaper.CanvasRenderer---------------------endAlloyPaper.WebGLRenderer = Class.extend({ "ctor": function(canvas) { this.surface = canvas; this.snapToPixel = true; this.canvasRenderer = new AlloyPaper.CanvasRenderer(); this.textureCache = {}; this.textureCanvasCache = {}; this.initSurface(this.surface); }, "initSurface": function(surface) { var options = { depth: false, alpha: true, preserveDrawingBuffer: true, antialias: false, premultipliedAlpha: true }; var ctx = undefined; try { ctx = surface.ctx = surface.getContext("webgl", options) || surface.getContext("experimental-webgl", options); ctx.viewportWidth = surface.width; ctx.viewportHeight = surface.height; } catch (e) {} if (!ctx) { alert("Could not initialise WebGL. Make sure you've updated your browser, or try a different one like Google Chrome."); } var textureShader = ctx.createShader(ctx.FRAGMENT_SHADER); ctx.shaderSource(textureShader, "" + "precision mediump float;\n" + "varying vec3 vTextureCoord;\n" + "varying float vAlpha;\n" + "uniform float uAlpha;\n" + "uniform sampler2D uSampler0;\n" + "void main(void) { \n" + "vec4 color = texture2D(uSampler0, vTextureCoord.st); \n" + "gl_FragColor = vec4(color.rgb, color.a * vAlpha);\n" + "}"); ctx.compileShader(textureShader); if (!ctx.getShaderParameter(textureShader, ctx.COMPILE_STATUS)) { alert(ctx.getShaderInfoLog(textureShader)); } var vertexShader = ctx.createShader(ctx.VERTEX_SHADER); ctx.shaderSource(vertexShader, "" + "attribute vec2 aVertexPosition;\n" + "attribute vec3 aTextureCoord;\n" + "attribute float aAlpha;\n" + "uniform bool uSnapToPixel;\n" + "const mat4 pMatrix = mat4(" + 2 / ctx.viewportWidth + ",0,0,0, 0," + -2 / ctx.viewportHeight + ",0,0, 0,0,-2, 0, -1,1,-1,1); \n" + "varying vec3 vTextureCoord;\n" + "varying float vAlpha;\n" + "void main(void) { \n" + "vTextureCoord = aTextureCoord; \n" + "vAlpha = aAlpha; \n" + "gl_Position = pMatrix * vec4(aVertexPosition.x,aVertexPosition.y,0.0, 1.0);\n" + "}"); ctx.compileShader(vertexShader); if (!ctx.getShaderParameter(vertexShader, ctx.COMPILE_STATUS)) { alert(ctx.getShaderInfoLog(vertexShader)); } var program = surface.shader = ctx.createProgram(); ctx.attachShader(program, vertexShader); ctx.attachShader(program, textureShader); ctx.linkProgram(program); if (!ctx.getProgramParameter(program, ctx.LINK_STATUS)) { alert("Could not initialise shaders"); } ctx.enableVertexAttribArray(program.vertexPositionAttribute = ctx.getAttribLocation(program, "aVertexPosition")); ctx.enableVertexAttribArray(program.uvCoordAttribute = ctx.getAttribLocation(program, "aTextureCoord")); ctx.enableVertexAttribArray(program.colorAttribute = ctx.getAttribLocation(program, "aAlpha")); program.alphaUniform = ctx.getUniformLocation(program, "uAlpha"); program.snapToUniform = ctx.getUniformLocation(program, "uSnapToPixel"); ctx.useProgram(program); this._vertexDataCount = 5; this._degToRad = Math.PI / 180; if (window.Float32Array) { this.vertices = new window.Float32Array(this._vertexDataCount * 4); } else { this.vertices = new Array(this._vertexDataCount * 4); } this.arrayBuffer = ctx.createBuffer(); this.indexBuffer = ctx.createBuffer(); ctx.bindBuffer(ctx.ARRAY_BUFFER, this.arrayBuffer); ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, this.indexBuffer); var byteCount = this._vertexDataCount * 4; ctx.vertexAttribPointer(program.vertexPositionAttribute, 2, ctx.FLOAT, 0, byteCount, 0); ctx.vertexAttribPointer(program.uvCoordAttribute, 2, ctx.FLOAT, 0, byteCount, 2 * 4); ctx.vertexAttribPointer(program.colorAttribute, 1, ctx.FLOAT, 0, byteCount, 4 * 4); if (window.Uint16Array) { this.indices = new window.Uint16Array(6); } else { this.indices = new Array(6); } for (var i = 0, l = this.indices.length; i < l; i += 6) { var j = i * 4 / 6; this.indices.set([j, j + 1, j + 2, j, j + 2, j + 3], i); } ctx.bufferData(ctx.ARRAY_BUFFER, this.vertices, ctx.STREAM_DRAW); ctx.bufferData(ctx.ELEMENT_ARRAY_BUFFER, this.indices, ctx.STATIC_DRAW); ctx.viewport(0, 0, ctx.viewportWidth, ctx.viewportHeight); ctx.colorMask(true, true, true, true); ctx.blendFuncSeparate(ctx.SRC_ALPHA, ctx.ONE_MINUS_SRC_ALPHA, ctx.SRC_ALPHA, ctx.ONE); ctx.enable(ctx.BLEND); ctx.disable(ctx.DEPTH_TEST); surface.init = true; this.ctx = ctx; }, "_initTexture": function(src, ctx) { if (!this.textureCache[src.src]) { src.glTexture = ctx.createTexture(); src.glTexture.image = src; ctx.activeTexture(ctx.TEXTURE0); ctx.bindTexture(ctx.TEXTURE_2D, src.glTexture); ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGBA, ctx.RGBA, ctx.UNSIGNED_BYTE, src.glTexture.image); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.LINEAR); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE); this.textureCache[src.src] = src.glTexture; ctx.uniform1i(ctx.getUniformLocation(ctx.canvas.shader, "uSampler0"), 0); } else { src.glTexture = this.textureCache[src.src]; ctx.activeTexture(ctx.TEXTURE0); ctx.bindTexture(ctx.TEXTURE_2D, src.glTexture); } }, "_initCache": function(o, src, ctx) { if (!this.textureCanvasCache[o.cacheID]) { this.textureCanvasCache[this._preCacheId] = null; src.glTexture = ctx.createTexture(); src.glTexture.image = src; ctx.activeTexture(ctx.TEXTURE0); ctx.bindTexture(ctx.TEXTURE_2D, src.glTexture); ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGBA, ctx.RGBA, ctx.UNSIGNED_BYTE, src.glTexture.image); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.LINEAR); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE); ctx.uniform1i(ctx.getUniformLocation(ctx.canvas.shader, "uSampler0"), 0); this.textureCanvasCache[o.cacheID] = src.glTexture; } else { src.glTexture = this.textureCanvasCache[o.cacheID]; ctx.activeTexture(ctx.TEXTURE0); ctx.bindTexture(ctx.TEXTURE_2D, src.glTexture); } }, "updateCache": function(ctx, o, w, h) { ctx.clearRect(0, 0, w + 1, h + 1); this.renderCache(ctx, o); }, "renderCache": function(ctx, o) { if (!o.isVisible()) { return; } if (o instanceof AlloyPaper.Container || o instanceof AlloyPaper.Stage) { var list = o.children.slice(0); for (var i = 0, l = list.length; i < l; i++) { ctx.save(); this.canvasRenderer.render(ctx, list[i]); ctx.restore(); } } else if (o instanceof AlloyPaper.Bitmap || o instanceof AlloyPaper.Sprite) { var rect = o.rect; ctx.drawImage(o.img, rect[0], rect[1], rect[2], rect[3], 0, 0, rect[2], rect[3]); } else if (o.txtCanvas) { ctx.drawImage(o.txtCanvas, 0, 0); } else if (o.shapeCanvas) { ctx.drawImage(o.shapeCanvas, 0, 0); } }, "clear": function() { this.ctx.clear(this.ctx.COLOR_BUFFER_BIT); }, "renderObj": function(ctx, o) { var mtx = o._matrix, leftSide = 0, topSide = 0, rightSide = 0, bottomSide = 0; var uFrame = 0, vFrame = 0, u = 1, v = 1, img = 0; if (o.complexCompositeOperation === "lighter") { ctx.blendFunc(ctx.SRC_ALPHA, ctx.ONE); } else { ctx.blendFunc(ctx.SRC_ALPHA, ctx.ONE_MINUS_SRC_ALPHA); } var mmyCanvas = o.cacheCanvas || o.txtCanvas || o.shapeCanvas; if (mmyCanvas) { this._initCache(o, mmyCanvas, ctx); rightSide = leftSide + mmyCanvas.width; bottomSide = topSide + mmyCanvas.height; } else if (o instanceof AlloyPaper.Bitmap || o instanceof AlloyPaper.Sprite) { var rect = o.rect; img = o.img; this._initTexture(img, ctx); rightSide = leftSide + rect[2]; bottomSide = topSide + rect[3]; u = rect[2] / img.width; v = rect[3] / img.height; uFrame = rect[0] / img.width; vFrame = rect[1] / img.height; } var a = mtx.a, b = mtx.b, c = mtx.c, d = mtx.d, tx = mtx.tx, ty = mtx.ty, lma = leftSide * a, lmb = leftSide * b, tmc = topSide * c, tmd = topSide * d, rma = rightSide * a, rmb = rightSide * b, bmc = bottomSide * c, bmd = bottomSide * d; var alpha = o.complexAlpha; this.vertices.set([lma + tmc + tx, lmb + tmd + ty, uFrame, vFrame, alpha, lma + bmc + tx, lmb + bmd + ty, uFrame, vFrame + v, alpha, rma + bmc + tx, rmb + bmd + ty, uFrame + u, vFrame + v, alpha, rma + tmc + tx, rmb + tmd + ty, uFrame + u, vFrame, alpha], 0); ctx.bufferSubData(ctx.ARRAY_BUFFER, 0, this.vertices); ctx.drawElements(ctx.TRIANGLES, 6, ctx.UNSIGNED_SHORT, 0); }, "clearBackUpCanvasCache": function() { this.textureCanvasCache[1] = null; }});//begin-------------------AlloyPaper.DisplayObject---------------------beginAlloyPaper.DisplayObject = Class.extend({ "ctor": function() { this.alpha = this.scaleX = this.scaleY = this.scale = 1; this.x = this.y = this.rotation = this.originX = this.originY = this.skewX = this.skewY = this.width = this.height = this.regX = this.regY = 0; this.textureReady = true; this.visible = true; this._matrix = new AlloyPaper.Matrix2D(); this._hitMatrix = new AlloyPaper.Matrix2D(); this.events = {}; this.id = AlloyPaper.UID.get(); this.cacheID = 0; this.baseInstanceof = "DisplayObject"; this.tickFPS = 60; var self = this; this._watch(this, "originX", function(prop, value) { if (typeof value === "string") { self.regX = parseInt(value); } else { self.regX = self.width * value; } }); this._watch(this, "originY", function(prop, value) { if (typeof value === "string") { self.regY = parseInt(value); } else { self.regY = self.height * value; } }); this._watch(this, "filter", function(prop, value) { self.setFilter.apply(self, value); }); this._watch(this, "scale", function(prop, value) { this.scaleX = this.scaleY = this.scale; }); this.cursor = "default"; this.onHover(function () { //this._setCursor(this, this.cursor); }, function () { this._setCursor(this, AlloyPaper.DefaultCursor); }); }, "_watch": function(target, prop, onPropertyChanged) { if (typeof prop === "string") { target["__" + prop] = this[prop]; Object.defineProperty(target, prop, { get: function() { return this["__" + prop]; }, set: function(value) { this["__" + prop] = value; onPropertyChanged.apply(target, [prop, value]); } }); } else { for (var i = 0, len = prop.length; i < len; i++) { var propName = prop[i]; target["__" + propName] = this[propName]; (function(propName) { Object.defineProperty(target, propName, { get: function() { return this["__" + propName]; }, set: function(value) { this["__" + propName] = value; onPropertyChanged.apply(target, [propName, value]); } }); })(propName); } } }, "isVisible": function() { return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0 && this.textureReady); }, "on": function(type, fn) { this.events[type] || (this.events[type] = []); this.events[type].push(fn); }, "off": function (type, fn) { var fns=this.events[type]; if (fns) { var i = 0, len = fns.length; for (; i < len; i++) { if (fns[i] === fn) { fns.splice(i, 1); break; } } } }, "execEvent": function (type, event) { if (this.events) { var fns = this.events[type], result = true; if (fns) { for (var i = 0, len = fns.length; i < len; i++) { result = fns[i].call(this, event); } } return result; } }, "_setCursor": function (obj, type) { if (obj) { if (obj.parent instanceof AlloyPaper.Stage) { obj.parent.setCursor(type); } else { this._setCursor(obj.parent, type); } } }, "clone": function() { var o = new AlloyPaper.DisplayObject(); this.cloneProps(o); return o; }, "cloneProps": function(o) { o.visible = this.visible; o.alpha = this.alpha; o.originX = this.originX; o.originY = this.originY; o.rotation = this.rotation; o.scaleX = this.scaleX; o.scaleY = this.scaleY; o.skewX = this.skewX; o.skewY = this.skewY; o.x = this.x; o.y = this.y; o.regX = this.regX; o.regY = this.regY; }, "cache": function() { if (!this.cacheCanvas) { this.cacheCanvas = document.createElement("canvas"); var bound = this.getBound(); this.cacheCanvas.width = bound.width; this.cacheCanvas.height = bound.height; this.cacheCtx = this.cacheCanvas.getContext("2d"); } this.cacheID = AlloyPaper.UID.getCacheID(); this.updateCache(this.cacheCtx, this, bound.width, bound.width); }, "uncache": function() { this.cacheCanvas = null; this.cacheCtx = null; this.cacheID = null; }, "setFilter": function(r, g, b, a) { if (this.width === 0 || this.height === 0) return; this.uncache(); this.cache(); var imageData = this.cacheCtx.getImageData(0, 0, this.cacheCanvas.width, this.cacheCanvas.height); var pix = imageData.data; for (var i = 0, n = pix.length; i < n; i += 4) { if (pix[i + 3] > 0) { pix[i] *= r; pix[i + 1] *= g; pix[i + 2] *= b; pix[i + 3] *= a; } } this.cacheCtx.putImageData(imageData, 0, 0); }, "getBound": function() { return { width: this.width, height: this.height }; }, "toCenter": function() { this.originX = .5; this.originY = .5; this.x = this.parent.width / 2; this.y = this.parent.height / 2; }, "destroy": function() { this.cacheCanvas = null; this.cacheCtx = null; this.cacheID = null; this._matrix = null; this.events = null; if (this.parent) { this.parent.remove(this); } }, "initAABB": function() { var x, y, width = this.width, height = this.height, mtx = this._matrix; var x_a = width * mtx.a, x_b = width * mtx.b; var y_c = height * mtx.c, y_d = height * mtx.d; var tx = mtx.tx, ty = mtx.ty; var minX = tx, maxX = tx, minY = ty, maxY = ty; if ((x = x_a + tx) < minX) { minX = x; } else if (x > maxX) { maxX = x; } if ((x = x_a + y_c + tx) < minX) { minX = x; } else if (x > maxX) { maxX = x; } if ((x = y_c + tx) < minX) { minX = x; } else if (x > maxX) { maxX = x; } if ((y = x_b + ty) < minY) { minY = y; } else if (y > maxY) { maxY = y; } if ((y = x_b + y_d + ty) < minY) { minY = y; } else if (y > maxY) { maxY = y; } if ((y = y_d + ty) < minY) { minY = y; } else if (y > maxY) { maxY = y; } this.AABB = [minX, minY, maxX - minX, maxY - minY]; this.rectPoints = [{ x: tx, y: ty},{ x: x_a + tx, y: x_b + ty},{ x: x_a + y_c + tx, y: x_b + y_d + ty},{ x: y_c + tx, y: y_d + ty}]; }, "updateCache": function(ctx, o, w, h) { ctx.clearRect(0, 0, w + 1, h + 1); this.renderCache(ctx, o); }, "renderCache": function(ctx, o) { if (!o.isVisible()) { return; } if (o instanceof AlloyPaper.Container || o instanceof AlloyPaper.Stage) { var list = o.children.slice(0); for (var i = 0, l = list.length; i < l; i++) { ctx.save(); this.render(ctx, list[i]); ctx.restore(); } } else if (o instanceof AlloyPaper.Bitmap || o instanceof AlloyPaper.Sprite) { var rect = o.rect; ctx.drawImage(o.img, rect[0], rect[1], rect[2], rect[3], 0, 0, rect[2], rect[3]); } else if (o.txtCanvas) { ctx.drawImage(o.txtCanvas, 0, 0); } else if (o.shapeCanvas) { ctx.drawImage(o.shapeCanvas, 0, 0); } }, "onClick": function(fn) { this.on("click", fn); }, "onMouseDown": function(fn) { this.on("pressdown", fn); }, "onMouseMove": function(fn) { this.on("mousemove", fn); }, "onMouseUp": function(fn) { this.on("pressup", fn); }, "onMouseOver": function(fn) { this.on("mouseover", fn); }, "onMouseOut": function(fn) { this.on("mouseout", fn); }, "onHover": function(over, out) { this.on("mouseover", over); this.on("mouseout", out); }, "onPressDown": function(fn) { this.on("pressdown", fn); }, "onPressMove": function(fn) { this.on("pressmove", fn); }, "onPressUp": function(fn) { this.on("pressup", fn); }, "onMouseWheel": function(fn) { this.on("mousewheel", fn); }, "onTouchStart": function(fn) { this.on("pressdown", fn); }, "onTouchMove": function(fn) { this.on("pressmove", fn); }, "onTouchEnd": function(fn) { this.on("pressup", fn); }, "onTouchCancel": function () { this.on("touchcancel", fn); }, "onDbClick": function(fn) { this.on("dblclick", fn); }, "addEventListener": function (type, handler) { this.on(this._normalizeEventType(type), handler); }, "removeEventListener": function (type, handler) { this.off(this._normalizeEventType(type), handler); }, "_normalizeEventType": function (type) { var newType = { "touchstart": "pressdown", "touchmove": "pressmove", "touchend": "pressup" }[type]; if (newType) return newType; return type; }});//end-------------------AlloyPaper.DisplayObject---------------------endAlloyPaper.Bitmap = AlloyPaper.DisplayObject.extend({ "ctor": function(img) { this._super(); Object.defineProperty(this, "rect", { get: function () { return this["__rect"]; }, set: function (value) { this["__rect"] = value; this.width = value[2]; this.height = value[3]; this.regX = value[2] * this.originX; this.regY = value[3] * this.originY; } }); if (arguments.length === 0) return; if (typeof img == "string") { this._initWithSrc(img); this.imgSrc = img; } else { this._init(img); this.imgSrc = img.src; } }, "_initWithSrc": function(img) { var cacheImg = AlloyPaper.Cache[img]; if (cacheImg) { this._init(cacheImg); } else { var self = this; this.textureReady = false; this.img = document.createElement("img"); this.img.crossOrigin = "Anonymous"; this.img.onload = function () { if (!self.rect) self.rect = [0, 0, self.img.width, self.img.height]; AlloyPaper.Cache[img] = self.img; self.textureReady = true; self.imageLoadHandle && self.imageLoadHandle(); if (self.filter) self.filter = self.filter; }; this.img.src = img; } }, "_init": function(img) { if (!img) return; this.img = img; this.img.crossOrigin = "Anonymous"; this.width = img.width; this.height = img.height; this.rect = [0, 0, img.width, img.height]; }, "useImage": function(img) { if (typeof img == "string") { this._initWithSrc(img); } else { this._init(img); this.imageLoadHandle && this.imageLoadHandle(); } }, "onImageLoad": function(fn) { this.imageLoadHandle = fn; }, "clone": function () { if (this.textureReady) { var o = new AlloyPaper.Bitmap(this.img); o.rect = this.rect.slice(0); this.cloneProps(o); return o; } else { var o = new AlloyPaper.Bitmap(this.imgSrc); this.rect&&(o.rect = this.rect.slice(0)); this.cloneProps(o); return o; } }, "clip": function (fn) { this._clipFn = fn; }, "flipX": function() {}, "flipY": function() {}});//begin-------------------AlloyPaper.Container---------------------beginAlloyPaper.Container = AlloyPaper.DisplayObject.extend({ "ctor": function() { this._super(); this.children = []; this.baseInstanceof = "Container"; }, "add": function(obj) { var len = arguments.length; if (len > 1) { for (var i = 0; i < len; i++) { var item = arguments[i]; if (item) { this.children.push(item); item.parent = this; } } } else { if (obj) { this.children.push(obj); obj.parent = this; } } }, "remove": function(obj) { var len = arguments.length, childLen = this.children.length; if (len > 1) { for (var j = 0; j < len; j++) { var currentObj = arguments[j]; for (var k = childLen; --k >= 0;) { if (currentObj&&this.children[k].id == currentObj.id) { currentObj.parent = null; this.children.splice(k, 1); break; } } } } else { for (var i = childLen; --i >= 0;) { if (obj&&this.children[i].id == obj.id) { obj.parent = null; this.children.splice(i, 1); break; } } } }, "clone": function() { var o = new AlloyPaper.Container(); this.cloneProps(o); var arr = o.children = []; for (var i = this.children.length - 1; i > -1; i--) { var clone = this.children[i].clone(); arr.unshift(clone); } return o; }, "removeAll": function() { var kids = this.children; while (kids.length) { kids.pop().parent = null; } }, "destroy": function() { this._super(); var kids = this.children; while (kids.length) { var kid = kids.pop(); kid.destroy(); kid = null; } }, "swapChildrenAt": function(index1, index2) { var kids = this.children; var o1 = kids[index1]; var o2 = kids[index2]; if (!o1 || !o2) { return; } kids[index1] = o2; kids[index2] = o1; }, "swapChildren": function(child1, child2) { var kids = this.children; var index1, index2; for (var i = 0, l = kids.length; i < l; i++) { if (kids[i] == child1) { index1 = i; } if (kids[i] == child2) { index2 = i; } if (index1 != null && index2 != null) { break; } } if (i == l) { return; } kids[index1] = child2; kids[index2] = child1; }, "swapToTop": function(child) { this.swapChildren(child, this.children[this.children.length - 1]); }});//end-------------------AlloyPaper.Container---------------------end//begin-------------------AlloyPaper.Graphics---------------------beginAlloyPaper.Graphics = AlloyPaper.DisplayObject.extend({ "ctor": function() { this._super(); this.cmds = []; this.assMethod = ["fillStyle", "strokeStyle", "lineWidth"]; }, "draw": function(ctx) { for (var i = 0, len = this.cmds.length; i < len; i++) { var cmd = this.cmds[i]; if (this.assMethod.join("-").match(new RegExp("\\b" + cmd[0] + "\\b", "g"))) { ctx[cmd[0]] = cmd[1][0]; } else { ctx[cmd[0]].apply(ctx, Array.prototype.slice.call(cmd[1])); } } }, "clearRect": function(x, y, width, height) { this.cmds.push(["clearRect", arguments]); return this; }, "clear": function() { this.cmds.length = 0; return this; }, "strokeRect": function() { this.cmds.push(["strokeRect", arguments]); return this; }, "fillRect": function() { this.cmds.push(["fillRect", arguments]); return this; }, "beginPath": function() { this.cmds.push(["beginPath", arguments]); return this; }, "arc": function() { this.cmds.push(["arc", arguments]); return this; }, "closePath": function() { this.cmds.push(["closePath", arguments]); return this; }, "fillStyle": function() { this.cmds.push(["fillStyle", arguments]); return this; }, "fill": function() { this.cmds.push(["fill", arguments]); return this; }, "strokeStyle": function() { this.cmds.push(["strokeStyle", arguments]); return this; }, "lineWidth": function() { this.cmds.push(["lineWidth", arguments]); return this; }, "stroke": function() { this.cmds.push(["stroke", arguments]); return this; }, "moveTo": function() { this.cmds.push(["moveTo", arguments]); return this; }, "lineTo": function() { this.cmds.push(["lineTo", arguments]); return this; }, "bezierCurveTo": function() { this.cmds.push(["bezierCurveTo", arguments]); return this; }, "clone": function() {}});//end-------------------AlloyPaper.Graphics---------------------end//begin-------------------AlloyPaper.Label---------------------beginAlloyPaper.Label = AlloyPaper.DisplayObject.extend({ "ctor": function(option) { this._super(); this.value = option.value; this.fontSize = option.fontSize; this.fontFamily = option.fontFamily; this.color = option.color; this.textAlign = "center"; this.textBaseline = "top"; this.fontWeight = option.fontWeight || ""; this.maxWidth = option.maxWidth || 2e3; this.square = option.square || false; this.txtCanvas = document.createElement("canvas"); this.txtCtx = this.txtCanvas.getContext("2d"); this.setDrawOption(); this.shadow = option.shadow; this._watch(this, ["value", "fontSize", "color", "fontFamily"], function() { this.setDrawOption(); }); }, "setDrawOption": function() { var drawOption = this.getDrawOption({ txt: this.value, maxWidth: this.maxWidth, square: this.square, size: this.fontSize, alignment: this.textAlign, color: this.color || "black", fontFamily: this.fontFamily, fontWeight: this.fontWeight, shadow: this.shadow }); this.cacheID = AlloyPaper.UID.getCacheID(); this.width = drawOption.calculatedWidth; this.height = drawOption.calculatedHeight; }, "getDrawOption": function(option) { var canvas = this.txtCanvas; var ctx = this.txtCtx; var canvasX, canvasY; var textX, textY; var text = []; var textToWrite = option.txt; var maxWidth = option.maxWidth; var squareTexture = option.square; var textHeight = option.size; var textAlignment = option.alignment; var textColour = option.color; var fontFamily = option.fontFamily; var fontWeight = option.fontWeight; ctx.font = textHeight + "px " + fontFamily; if (maxWidth && this.measureText(ctx, textToWrite) > maxWidth) { maxWidth = this.createMultilineText(ctx, textToWrite, maxWidth, text); canvasX = this.getPowerOfTwo(maxWidth); } else { text.push(textToWrite); canvasX = this.getPowerOfTwo(ctx.measureText(textToWrite).width); } canvasY = this.getPowerOfTwo(textHeight * (text.length + 1)); if (squareTexture) { canvasX > canvasY ? canvasY = canvasX : canvasX = canvasY; } option.calculatedWidth = canvasX; option.calculatedHeight = canvasY; canvas.width = canvasX; canvas.height = canvasY; switch (textAlignment) { case "left": textX = 0; break; case "center": textX = canvasX / 2; break; case "right": textX = canvasX; break; } textY = canvasY / 2; ctx.fillStyle = textColour; ctx.textAlign = textAlignment; ctx.textBaseline = "middle"; ctx.font = fontWeight + " " + textHeight + "px " + fontFamily; if (option.shadow) { ctx.shadowColor = option.shadow.color || "transparent"; ctx.shadowOffsetX = option.shadow.offsetX || 0; ctx.shadowOffsetY = option.shadow.offsetY || 0; ctx.shadowBlur = option.shadow.blur || 0; } var offset = (canvasY - textHeight * (text.length + 1)) * .5; option.cmd = []; for (var i = 0; i < text.length; i++) { if (text.length > 1) { textY = (i + 1) * textHeight + offset; } option.cmd.push({ text: text[i], x: textX, y: textY }); ctx.fillText(text[i], textX, textY); } return option; }, "getPowerOfTwo": function(value, pow) { var temp_pow = pow || 1; while (temp_pow < value) { temp_pow *= 2; } return temp_pow; }, "measureText": function(ctx, textToMeasure) { return ctx.measureText(textToMeasure).width; }, "createMultilineText": function(ctx, textToWrite, maxWidth, text) { textToWrite = textToWrite.replace("\n", " "); var currentText = textToWrite; var futureText; var subWidth = 0; var maxLineWidth; var wordArray = textToWrite.split(" "); var wordsInCurrent, wordArrayLength; wordsInCurrent = wordArrayLength = wordArray.length; while (this.measureText(ctx, currentText) > maxWidth && wordsInCurrent > 1) { wordsInCurrent--; currentText = futureText = ""; for (var i = 0; i < wordArrayLength; i++) { if (i < wordsInCurrent) { currentText += wordArray[i]; if (i + 1 < wordsInCurrent) { currentText += " "; } } else { futureText += wordArray[i]; if (i + 1 < wordArrayLength) { futureText += " "; } } } } text.push(currentText); maxLineWidth = this.measureText(ctx, currentText); if (futureText) { subWidth = this.createMultilineText(ctx, futureText, maxWidth, text); if (subWidth > maxLineWidth) { maxLineWidth = subWidth; } } return maxLineWidth; }, "draw": function(ctx) { ctx.fillStyle = this.color; ctx.font = this.font; ctx.textAlign = this.textAlign || "left"; ctx.textBaseline = this.textBaseline || "top"; ctx.fillText(this.text, 0, 0); }});//end-------------------AlloyPaper.Label---------------------end//begin-------------------AlloyPaper.Particle---------------------beginAlloyPaper.Particle = AlloyPaper.Bitmap.extend({ "ctor": function(option) { this._super(option.texture); this.originX = .5; this.originY = .5; this.position = option.position; this.x = this.position.x; this.y = this.position.y; this.rotation = option.rotation || 0; this.velocity = option.velocity; this.acceleration = option.acceleration || new AlloyPaper.Vector2(0, 0); this.rotatingSpeed = option.rotatingSpeed || 0; this.rotatingAcceleration = option.rotatingAcceleration || 0; this.hideSpeed = option.hideSpeed || .01; this.zoomSpeed = option.hideSpeed || .01; this.isAlive = true; this.img = option.texture; this.img.src = ""; }, "tick": function() { this.velocity.add(this.acceleration); this.position.add(this.velocity.multiply(.1)); this.rotatingSpeed += this.rotatingAcceleration; this.rotation += this.rotatingSpeed; this.alpha -= this.hideSpeed; this.x = this.position.x; this.y = this.position.y; }});//end-------------------AlloyPaper.Particle---------------------end//begin-------------------AlloyPaper.ParticleSystem---------------------beginAlloyPaper.ParticleSystem = AlloyPaper.Container.extend({ "ctor": function(option) { this._super(); this.speed = option.speed; this.angle = option.angle; this.angleRange = option.angleRange; this.emitArea = option.emitArea; this.gravity = option.gravity || { x: 0, y: 0 }; this.filter = option.filter; this.compositeOperation = "lighter"; this.emitCount = option.emitCount; this.maxCount = option.maxCount || 1e3; this.emitX = option.emitX; this.emitY = option.emitY; if (typeof option.texture === "string") { if (AlloyPaper.Cache[option.texture]) { this.texture = AlloyPaper.Cache[option.texture]; this.generateFilterTexture(this.texture); } else { this.bitmap = new AlloyPaper.Bitmap(); this.bitmap._parent = this; this.bitmap.onImageLoad(function() { this._parent.texture = this.img; this._parent.generateFilterTexture(this.img); delete this._parent; }); this.bitmap.useImage(option.texture); } } else { this.texture = option.texture; this.generateFilterTexture(option.texture); } this.totalCount = option.totalCount; this.emittedCount = 0; this.tickFPS = 60; this.hideSpeed = option.hideSpeed || .01; }, "generateFilterTexture": function(texture) { var bitmap = new AlloyPaper.Bitmap(texture); bitmap.filter = this.filter; this.filterTexture = bitmap.cacheCanvas; }, "changeFilter": function (filter) { var bitmap = new AlloyPaper.Bitmap(this.texture); bitmap.filter = filter; this.filterTexture = bitmap.cacheCanvas; }, "emit": function() { var angle = (this.angle + AlloyPaper.Util.random(-this.angleRange / 2, this.angleRange / 2)) * Math.PI / 180; var halfX = this.emitArea[0] / 2, harfY = this.emitArea[1] / 2; var particle = new AlloyPaper.Particle({ position: new AlloyPaper.Vector2(this.emitX + AlloyPaper.Util.random(-halfX, halfX), this.emitY + AlloyPaper.Util.random(-harfY, harfY)), velocity: new AlloyPaper.Vector2(this.speed * Math.cos(angle), this.speed * Math.sin(angle)), texture: this.filterTexture, acceleration: this.gravity, hideSpeed: this.hideSpeed}); this.add(particle); this.emittedCount++; }, "tick": function() { if (this.filterTexture) { var len = this.children.length; if (this.totalCount && this.emittedCount > this.totalCount) { if (len === 0) this.destroy(); } else { if (len < this.maxCount) { for (var k = 0; k < this.emitCount; k++) { this.emit(); } } } for (var i = 0; i < len; i++) { var item = this.children[i]; if (item.isVisible()) { item.tick(); } else { this.remove(item); i--; len--; } } } }});//end-------------------AlloyPaper.ParticleSystem---------------------end//begin----------------- AlloyPaper.ParticleExplosion -------------------beginAlloyPaper.ParticleExplosion = AlloyPaper.Container.extend({ ctor: function (ps, callback) { this._super(); this.ps = ps; this.add(ps); this.callback = callback; this.tickFPS = 0; setTimeout(function () { this.ps.maxCount = 0; this.tickFPS = 60; }.bind(this), 1000); }, tick: function () { if (this.ps.children.length === 0) { this.tickFPS = 0; this.parent.remove(this); this.callback(); } }});//end-----------------AlloyPaper.ParticleExplosion-------------------end//begin-------------------AlloyPaper.Shape---------------------beginAlloyPaper.Shape = AlloyPaper.DisplayObject.extend({ "ctor": function(width, height, debug) { this._super(); this.cmds = []; this.assMethod = ["fillStyle", "strokeStyle", "lineWidth"]; this.width = width; this.height = height; this._width = width; this._height = height; this.shapeCanvas = document.createElement("canvas"); this.shapeCanvas.width = this.width; this.shapeCanvas.height = this.height; this.shapeCtx = this.shapeCanvas.getContext("2d"); if (debug) { this.fillStyle("red"); this.fillRect(0, 0, width, height); } this._watch(this, "scaleX", function(prop, value) { this.width = this._width * value; this.height = this._height * this.scaleY; this.shapeCanvas.width = this.width; this.shapeCanvas.height = this.height; this.shapeCtx.scale(value, this.scaleY); this.end(); }); this._watch(this, "scaleY", function(prop, value) { this.width = this._width * this.scaleX; this.height = this._height * value; this.shapeCanvas.width = this.width; this.shapeCanvas.height = this.height; this.shapeCtx.scale(this.scaleX, value); this.end(); }); }, "end": function() { this._preCacheId = this.cacheID; this.cacheID = AlloyPaper.UID.getCacheID(); var ctx = this.shapeCtx; for (var i = 0, len = this.cmds.length; i < len; i++) { var cmd = this.cmds[i]; if (this.assMethod.join("-").match(new RegExp("\\b" + cmd[0] + "\\b", "g"))) { ctx[cmd[0]] = cmd[1][0]; } else { ctx[cmd[0]].apply(ctx, Array.prototype.slice.call(cmd[1])); } } }, "clearRect": function(x, y, width, height) { this.cacheID = AlloyPaper.UID.getCacheID(); this.shapeCtx.clearRect(x, y, width, height); }, "clear": function() { this.cacheID = AlloyPaper.UID.getCacheID(); this.cmds.length = 0; this.shapeCtx.clearRect(0, 0, this.width, this.height); }, "strokeRect": function() { this.cmds.push(["strokeRect", arguments]); return this; }, "fillRect": function() { this.cmds.push(["fillRect", arguments]); return this; }, "beginPath": function() { this.cmds.push(["beginPath", arguments]); return this; }, "arc": function() { this.cmds.push(["arc", arguments]); return this; }, "closePath": function() { this.cmds.push(["closePath", arguments]); return this; }, "fillStyle": function() { this.cmds.push(["fillStyle", arguments]); return this; }, "fill": function() { this.cmds.push(["fill", arguments]); return this; }, "strokeStyle": function() { this.cmds.push(["strokeStyle", arguments]); return this; }, "lineWidth": function() { this.cmds.push(["lineWidth", arguments]); return this; }, "stroke": function() { this.cmds.push(["stroke", arguments]); return this; }, "moveTo": function() { this.cmds.push(["moveTo", arguments]); return this; }, "lineTo": function() { this.cmds.push(["lineTo", arguments]); return this; }, "bezierCurveTo": function() { this.cmds.push(["bezierCurveTo", arguments]); return this; }, "clone": function() {}});//end-------------------AlloyPaper.Shape---------------------end//begin-------------------AlloyPaper.Sprite---------------------beginAlloyPaper.Sprite = AlloyPaper.DisplayObject.extend({ "ctor": function(option) { this._super(); this.option = option; this.x = option.x || 0; this.y = option.y || 0; this.currentFrameIndex = 0; this.animationFrameIndex = 0; this.currentAnimation = option.currentAnimation || null; this.rect = [0, 0, 10, 10]; this.visible = false; this.bitmaps = []; this._loadedCount = 0; var len = this.option.imgs.length; for (var i = 0; i < len; i++) { var urlOrImg = this.option.imgs[i]; if (typeof urlOrImg === "string") { if (AlloyPaper.Cache[urlOrImg]) { this.bitmaps.push(new AlloyPaper.Bitmap(AlloyPaper.Cache[urlOrImg])); this._loadedCount++; } else { (function(){ var bmp = new AlloyPaper.Bitmap(); bmp._sprite = this; bmp.onImageLoad(function() { bmp._sprite._loadedCount++; if (bmp._sprite._loadedCount === len) { bmp._sprite.visible = true; delete bmp._sprite; } }); bmp.useImage(this.option.imgs[i]); this.bitmaps.push(bmp); })(); } } else { this._loadedCount++; this.bitmaps.push(new AlloyPaper.Bitmap(urlOrImg)); } } if (this._loadedCount === len) { this.visible = true; } this.img = this.bitmaps[0].img; this.interval = 1e3 / option.framerate; this.loop = null; this.paused = false; this.animationEnd = option.animationEnd || null; if (this.currentAnimation) { this.gotoAndPlay(this.currentAnimation); } this.tickAnimationEnd = option.tickAnimationEnd || null; }, "play": function() { this.paused = false; }, "pause": function () { this.paused = true; }, "reset": function() { this.currentFrameIndex = 0; this.animationFrameIndex = 0; }, "gotoAndPlay": function(animation, times) { this.paused = false; this.reset(); clearInterval(this.loop); this.currentAnimation = animation; var self = this; var playTimes = 0; this.loop = setInterval(function() { if (!self.paused) { var opt = self.option; var frames = opt.animations[self.currentAnimation].frames, len = frames.length; self.animationFrameIndex++; if (self.animationFrameIndex > len - 1) { playTimes++; self.animationFrameIndex = 0; if (self.tickAnimationEnd) { self.tickAnimationEnd(); } if (times && playTimes == times) { if (self.animationEnd) self.animationEnd(); self.paused = true; clearInterval(self.loop); self.parent.remove(self); } } self.rect = opt.frames[frames[self.animationFrameIndex]]; self.width = self.rect[2]; self.height = self.rect[3]; var rect = self.rect, rectLen = rect.length; rectLen > 4 && (self.regX = rect[2] * rect[4]); rectLen > 5 && (self.regY = rect[3] * rect[5]); rectLen > 6 && (self.img = self.bitmaps[rect[6]].img); } }, this.interval); }, "gotoAndStop": function(animation) { this.reset(); clearInterval(this.loop); var self = this; self.currentAnimation = animation; var opt = self.option; var frames = opt.animations[self.currentAnimation].frames; self.rect = opt.frames[frames[self.animationFrameIndex]]; self.width = self.rect[2]; self.height = self.rect[3]; var rect = self.rect, rectLen = rect.length; rectLen > 4 && (self.regX = rect[2] * rect[4]); rectLen > 5 && (self.regY = rect[3] * rect[5]); rectLen > 6 && (self.img = self.bitmaps[rect[6]].img); }});//end-------------------AlloyPaper.Sprite---------------------endAlloyPaper.Stage = AlloyPaper.Container.extend({ "ctor": function(canvas, openWebGL) { this._super(); this.canvas = typeof canvas == "string" ? document.querySelector(canvas) : canvas; this.width = this.canvas.width; this.height = this.canvas.height; this.AABB = [0, 0, this.width, this.height]; this.hitAABB = true; this.hitRenderer = new AlloyPaper.CanvasRenderer(); this.hitCanvas = document.createElement("canvas"); this.hitCanvas.width = 1; this.hitCanvas.height = 1; this.stageRenderer = new AlloyPaper.Renderer(this, openWebGL); this.hitCtx = this.hitCanvas.getContext("2d"); this._scaleX = this._scaleY = null; this.offset = this._getXY(this.canvas); this.overObj = null; this._paused = false; this.fps = 63; this.interval = Math.floor(1e3 / this.fps); this.toList = []; this.tickFns = []; this.beginTick = null; this.endTick = null; var self = this; self.loop = setInterval(function() { if (self._paused) return; self.beginTick && self.beginTick(); self._tick(self); self.endTick && self.endTick(); }, self.interval); Object.defineProperty(this, "useRequestAnimFrame", { set: function(value) { this._useRequestAnimFrame = value; if (value) { clearInterval(self.loop); self.loop = AlloyPaper.RAF.requestInterval(function() { self._tick(self); }, self.interval); } else { AlloyPaper.RAF.clearRequestInterval(self.loop); self.loop = setInterval(function() { self._tick(self); }, self.interval); } }, get: function() { return this._useRequestAnimFrame; } }); this._watch(this, "fps", function(prop, value) { this.interval = Math.floor(1e3 / value); var self = this; if (this.useRequestAnimFrame) { clearInterval(this.loop); try { AlloyPaper.RAF.clearRequestInterval(this.loop); } catch (e) {} this.loop = AlloyPaper.RAF.requestInterval(function() { self._tick(self); }, this.interval); } else { AlloyPaper.RAF.clearRequestInterval(this.loop); try { clearInterval(this.loop); } catch (e) {} this.loop = setInterval(function() { self._tick(self); }, this.interval); } }); this._initDebug(); this._pressmoveObjs = null; this.baseInstanceof = "Stage"; this.overObj = null; this._moveInterval = 16; this._preMoveTime = new Date(); this._currentMoveTime = new Date(); Object.defineProperty(this, "moveFPS", { set: function(value) { this._moveFPS = value; this._moveInterval = 1e3 / value; }, get: function() { return this._moveFPS; } }); this.canvas.addEventListener("mousemove", this._handleMouseMove.bind(this), false); this.canvas.addEventListener("click", this._handleClick.bind(this), false); this.canvas.addEventListener("mousedown", this._handleMouseDown.bind(this), false); this.canvas.addEventListener("mouseup", this._handleMouseUp.bind(this), false); this.canvas.addEventListener("dblclick", this._handleDblClick.bind(this), false); this.addEvent(this.canvas, "mousewheel", this._handleMouseWheel.bind(this)); this.canvas.addEventListener("touchmove", this._handleMouseMove.bind(this), false); this.canvas.addEventListener("touchstart", this._handleMouseDown.bind(this), false); this.canvas.addEventListener("touchend", this._handleMouseUp.bind(this), false); this.canvas.addEventListener("touchcancel", this._handleTouchCancel.bind(this), false); document.addEventListener("DOMContentLoaded", this.adjustLayout.bind(this), false); window.addEventListener("load", this.adjustLayout.bind(this), false); window.addEventListener("resize", this.adjustLayout.bind(this), false); this.autoUpdate = true; this.scaleType = "normal"; this.setCursor(AlloyPaper.DefaultCursor); }, "adjustLayout": function() { this.offset = this._getXY(this.canvas); this.style=this._getStyle(); if (this._scaleX) { this.scaleToScreen(this._scaleX, this._scaleY); } }, "pause": function () { this._paused = true; this._pauseSprite(this); this._pauseTween(); }, "play": function () { this._paused = false; this._playSprite(this); this._playTween(); }, "_pauseSprite": function (obj) { for (var i = 0, len = obj.children.length; i < len; i++) { var child = obj.children[i]; if (child instanceof AlloyPaper.Container) { this._pauseSprite(child); } else if (child instanceof AlloyPaper.Sprite) { child.pause(); } } }, "_pauseTween": function () { for (var i = 0, len = this.toList.length; i < len; i++) { this.toList[i].pause(); } }, "_playSprite": function (obj) { for (var i = 0, len = obj.children.length; i < len; i++) { var child = obj.children[i]; if (child instanceof AlloyPaper.Container) { this._playSprite(child); } else if (child instanceof AlloyPaper.Sprite) { child.play(); } } }, "_playTween": function () { for (var i = 0, len = this.toList.length; i < len; i++) { this.toList[i].play(); } }, "toggle": function () { if (this._paused) { this.play(); } else { this.pause(); } }, "openDebug": function() {}, "closeDebug": function() {}, "_initDebug": function() { this.debugDiv = document.createElement("div"); this.debugDiv.style.cssText = "display:none;position:absolute;z-index:2000;left:0;bottom:0;background-color:yellow;font-size:16px;"; document.body.appendChild(this.debugDiv); Object.defineProperty(this, "debug", { set: function(value) { this._debug = value; if (this._debug) { this.debugDiv.style.display = "block"; } else { this.debugDiv.style.display = "none"; } }, get: function() { return this._debug; } }); }, "_handleMouseWheel": function(event) { this._correctionEvent(event, event.type); var callbacks = this.events["mousewheel"]; if (callbacks) { for (var i = 0, len = callbacks.length; i < len; i++) { var callback = callbacks[i]; callback(event); } } if (this.overObj) { this.hitRenderer._bubbleEvent(this.overObj, "mousewheel", event); } }, "update": function() { this.stageRenderer.update(); }, "_correctionEvent": function (evt, type) { this.adjustLayout(); if (evt.touches||evt.changedTouches) { var firstTouch = evt.touches[0] || evt.changedTouches[0]; if (firstTouch) { evt.stageX = firstTouch.pageX; evt.stageY = firstTouch.pageY; } } else { evt.stageX = evt.pageX; evt.stageY = evt.pageY; } //if (this.scaleType !== "normal") { var p = this._correction(evt.stageX, evt.stageY); evt.stageX = Math.round(p.x); evt.stageY = Math.round(p.y); //} var callbacks = this.events[type]; if (callbacks) { for (var i = 0, len = callbacks.length; i < len; i++) { var callback = callbacks[i]; callback(evt); } } }, "_handleClick": function(evt) { this._correctionEvent(evt, evt.type); this._getObjectUnderPoint(evt, evt.type); }, "_handleMouseMove": function(evt) { this._currentMoveTime = new Date(); if (this._currentMoveTime - this._preMoveTime > this._moveInterval / 2) { this._correctionEvent(evt, evt.type); if (this._pressmoveObjs) { var pressmoveHandle = this._pressmoveObjs.events["pressmove"]; pressmoveHandle && this._pressmoveObjs.execEvent("pressmove", evt); } var child = this._getObjectUnderPoint(evt, "mousemove"); if (child) { if (this.overObj) { if (child.id != this.overObj.id) { this.hitRenderer._bubbleEvent(this.overObj, "mouseout", evt); this.hitRenderer._bubbleEvent(child, "mouseover", evt); this.overObj = child; } else { this.hitRenderer._bubbleEvent(child, "mousemove", evt); } this._setCursorByOverObject(child); } else { this.overObj = child; this.hitRenderer._bubbleEvent(child, "mouseover", evt); } } else { if (this.overObj) { this.hitRenderer._bubbleEvent(this.overObj, "mouseout", evt); this.overObj = null; } } this._preMoveTime = this._currentMoveTime; } }, "_getPressmoveTarget": function(o) { if (o.events["pressmove"]) { this._pressmoveObjs = o; } if (o.parent) this._getPressmoveTarget(o.parent); }, "_handleMouseDown": function(evt) { this._correctionEvent(evt, "pressdown"); var child = this._getObjectUnderPoint(evt, "pressdown"); if (child) { this._getPressmoveTarget(child); } }, "_handleMouseUp": function(evt) { this._pressmoveObjs = null; this._correctionEvent(evt, "pressup"); this._getObjectUnderPoint(evt, "pressup"); }, "_handleTouchCancel": function (evt) { this._pressmoveObjs = null; this._correctionEvent(evt, "touchcancel"); this._getObjectUnderPoint(evt, "touchcancel"); }, "_handleDblClick": function(evt) { this._correctionEvent(evt, evt.type); this._getObjectUnderPoint(evt, evt.type); }, "_getObjectUnderPoint": function(evt, type) { if (this.hitAABB) { return this.hitRenderer.hitAABB(this.hitCtx, this, evt, type); } else { return this.hitRenderer.hitRender(this.hitCtx, this, evt, type); } }, "_getXY": function(el) { var _t = 0, _l = 0; if (document.documentElement.getBoundingClientRect && el.getBoundingClientRect) { var box = el.getBoundingClientRect(); _l = box.left; _t = box.top; } else { while (el.offsetParent) { _t += el.offsetTop; _l += el.offsetLeft; el = el.offsetParent; } return [_l, _t]; } return [_l + Math.max(document.documentElement.scrollLeft, document.body.scrollLeft), _t + Math.max(document.documentElement.scrollTop, document.body.scrollTop)]; }, "_tick": function(container) { if (container && container.tick && container.tickFPS > 0) { this._initInterval(container); if (!container.hasOwnProperty("_tickInterval")) { container.tick(); } else { container._tickIntervalCurrent = new Date(); if (!container._tickIntervalLast) { container._tickIntervalLast = new Date(); container._tickIntervalPrev = new Date(); } var itv = (container._tickIntervalCurrent - container._tickIntervalLast) +( container._tickIntervalCurrent - container._tickIntervalPrev); if (itv > container._tickInterval) { container.tick(); container._tickIntervalLast = container._tickIntervalCurrent; } container._tickIntervalPrev= new Date(); } } var children = container.children, len = children.length; for (var i = 0; i < len; i++) { var child = children[i]; if (child) { if (child.tick && child.tickFPS > 0) { this._initInterval(child); if (!child.hasOwnProperty("_tickInterval")) { child.tick(); } else { child._tickIntervalCurrent = new Date(); if (!child._tickIntervalLast){ child._tickIntervalLast = new Date(); child._tickIntervalPrev = new Date(); } var itv =( child._tickIntervalCurrent - child._tickIntervalLast)+(child._tickIntervalCurrent-child._tickIntervalPrev); if (itv > child._tickInterval) { child.tick(); child._tickIntervalLast = child._tickIntervalCurrent; } child._tickIntervalPrev= new Date(); } } if (child.baseInstanceof == "Container") { this._tick(child); } } } }, "_initInterval": function(obj) { if (obj.hasOwnProperty("tickFPS")) { obj._tickInterval = 1e3 / obj.tickFPS; } }, "tick": function () { for (var i = 0, len = this.tickFns.length; i < len; i++) { var fn = this.tickFns[i]; if (!fn.hasOwnProperty("_ARE_PrevDate")) { fn(); continue; } fn._ARE_CurrentDate = new Date(); var interval = (fn._ARE_CurrentDate - fn._ARE_PrevDate) + (fn._ARE_CurrentDate - fn._ARE_LastDate); if (interval > fn._ARE_Interval) { fn(); fn._ARE_PrevDate = fn._ARE_CurrentDate; } fn._ARE_LastDate = fn._ARE_CurrentDate; } if(this.autoUpdate)this.update(); if (this.debug) { this.getFPS(); this.debugDiv.innerHTML = "fps : " + this.fpsValue + " <br/>object count : " + this.getTotalCount() + " <br/>rendering mode : " + this.getRenderingMode() + " <br/>inner object count : " + this.stageRenderer.objs.length; } }, "onTick": function(fn,interval) { this.tickFns.push(fn); if (interval !== undefined) { fn._ARE_PrevDate = new Date(); fn._ARE_CurrentDate = new Date(); fn._ARE_LastDate = new Date(); fn._ARE_Interval = interval; } }, "setFPS": function(fps) { this.interval = Math.floor(1e3 / fps); }, "onKeyboard": function(keyCombo, onDownCallback, onUpCallback) { AlloyPaper.Keyboard.on(keyCombo, onDownCallback, onUpCallback); }, "getActiveKeys": function() { return AlloyPaper.Keyboard.getActiveKeys(); }, "scaleToScreen": function (scaleX, scaleY) { this.scaleType = "screen"; if (scaleX === 1 && scaleY === 1) { document.body.style.overflow = "hidden"; document.documentElement.style.overflow = "hidden"; } document.body.style.margin = 0; document.documentElement.style.margin = 0; document.body.style.border = 0; document.documentElement.style.border = 0; document.body.style.padding = 0; document.documentElement.style.padding = 0; document.body.style.width = "100%"; document.documentElement.style.width = "100%"; document.body.style.height = "100%"; document.documentElement.style.height = "100%"; this._scaleX = scaleX; this._scaleY = scaleY; var canvas = this.canvas; canvas.style.position = "absolute"; canvas.style.width = scaleX * 100 + "%"; canvas.style.height = scaleY * 100 + "%"; canvas.style.left = 100 * (1 - scaleX) / 2 + "%"; canvas.style.top = 100 * (1 - scaleY) / 2 + "%"; canvas.style.border = "0px solid #ccc"; this.offset = this._getXY(this.canvas); this.style=this._getStyle(); }, "scaleToBox": function (w, h) { this.scaleType = "box"; if (w === window.innerWidth && h === window.innerHeight) { document.body.style.overflow = "hidden"; document.documentElement.style.overflow = "hidden"; } var canvas = this.canvas; canvas.style.position = "absolute"; canvas.style.width = w + "px"; canvas.style.height = h + "px"; canvas.style.left = (window.innerWidth - w) / 2 + "px"; canvas.style.top = (window.innerHeight - h) / 2 + "px"; canvas.style.border = "0px solid #ccc"; this.offset = this._getXY(this.canvas); this.style=this._getStyle(); }, "correctingXY": function (x, y) { if (this.scaleType === "box") { return { x: x * this.width / parseInt( this.canvas.style.width), y: y * this.height / parseInt(this.canvas.style.height) }; } else { return { x: x * this.width / (window.innerWidth * this._scaleX), y: y * this.height / (window.innerHeight * this._scaleY) }; } }, "getTotalCount": function() { var count = 0; var self = this; function getCount(child) { if (child.baseInstanceof == "Container" || child.baseInstanceof == "Stage") { for (var i = 0, len = child.children.length; i < len; i++) { var subChild = child.children[i]; if (subChild instanceof AlloyPaper.Container) { getCount(subChild); } else { count++; } } } else { count++; } } getCount(this); return count; }, "getRenderingMode": function() { if (this.stageRenderer.renderingEngine instanceof AlloyPaper.CanvasRenderer) { return "Canvas"; } return "WebGL"; }, "getFPS": function() { var fps = AlloyPaper.FPS.get(); this.fpsValue = fps.value; }, "addEvent": function(el, type, fn, capture) { if (type === "mousewheel" && document.mozHidden !== undefined) { type = "DOMMouseScroll"; } el.addEventListener(type, function(event) { var type = event.type; if (type == "DOMMouseScroll" || type == "mousewheel") { event.delta = event.wheelDelta ? event.wheelDelta / 120 : -(event.detail || 0) / 3; } fn.call(this, event); }, capture || false); }, "setCursor": function(type) { this.canvas.style.cursor = type; }, "_setCursorByOverObject": function (obj) { if (obj.cursor !== "default") { this.setCursor(obj.cursor); } else { if (obj.parent) { this._setCursorByOverObject(obj.parent); } } }, "destroy": function () { this._super(); this.canvas.parentNode.removeChild(this.canvas); if (this.useRequestAnimFrame) { AlloyPaper.RAF.clearRequestInterval(this.loop); } else { clearInterval(this.loop); } }, "_getStyle":function() { var style = window.getComputedStyle(this.canvas, null); return { boxSizing: style.boxSizing, borderTopWidth: parseInt(style.borderTopWidth), borderLeftWidth: parseInt(style.borderLeftWidth), width:parseInt(style.width), height:parseInt(style.height) }; }, "_correction":function(pageX,pageY){ var x=pageX-this.offset[0]-this.style.borderLeftWidth, y=pageY-this.offset[1]-this.style.borderTopWidth, canvasWidth=this.style.width, canvasHeight=this.style.height; if(this.style.boxSizing==="border-box"){ canvasWidth-=this.style.borderLeftWidth; canvasHeight-=this.style.borderTopWidth; } return {x: this.width*x/canvasWidth,y:this.height*y/canvasHeight}; }});//begin-------------------AlloyPaper.Text---------------------beginAlloyPaper.Text = AlloyPaper.DisplayObject.extend({ "ctor": function(value, font, color) { this._super(); this.value = value; this.font = font; this.color = color; this.textAlign = "left"; this.textBaseline = "top"; }, "draw": function(ctx) { ctx.fillStyle = this.color; ctx.font = this.font; ctx.textAlign = this.textAlign || "left"; ctx.textBaseline = this.textBaseline || "top"; ctx.fillText(this.value, 0, 0); }, "clone": function() { var t = new AlloyPaper.Text(this.text, this.font, this.color); this.cloneProps(t); return t; }, "getWidth": function () { var measureCtx = document.createElement("canvas").getContext("2d"); measureCtx.font = this.font; var width = measureCtx.measureText(this.value).width; measureCtx = null; return width; }});//end-------------------AlloyPaper.Text---------------------endreturn AlloyPaper;}));
- web手势库AlloyFinger运用( 控制CANVAS中图片移动、缩放、旋转)
- 超小Web手势库AlloyFinger原理
- Unity 移动端简单手势控制(移动,旋转,缩放)
- CANVAS移动、缩放、旋转画入的图片
- Canvas的应用,图片的移动、旋转、缩放
- canvas控制图片缩放
- 图片 旋转,缩放,移动
- canvas实现图片旋转缩放
- android中手势操作图片的平移、缩放、旋转
- android中手势操作图片的平移、缩放、旋转
- android中手势操作图片的平移、缩放、旋转
- Android matrix 控制图片的旋转、缩放、移动
- Android matrix 控制图片的旋转、缩放、移动
- Android matrix 控制图片的旋转、缩放、移动
- Android matrix 控制图片的旋转、缩放、移动
- Android matrix 控制图片的旋转、缩放、移动
- Android之matrix类控制图片的旋转、缩放、移动
- Android matrix 控制图片的旋转、缩放、移动
- Go 语言简介(上)— 语法
- QML动画与过度
- Android进程的五个等级
- Linux终端缩短路径名
- CocoaPods详解之----制作篇
- web手势库AlloyFinger运用( 控制CANVAS中图片移动、缩放、旋转)
- CUDA学习(四)初探
- 26个字母和数字符号ASCII码对照表
- Android如何在activity中控制屏幕点亮与关闭
- 浅谈C/C++ 开发Excel插件之操作excel
- 1078 - Integer Divisibility
- 关于小米手机及一些使用相册去选取图片的手机的一些问题
- php checkbox 取值详细说明
- 预压缩处理图片 options.inJustDecodeBounds = true