;(function(){
/**
* @class Flash渲染器。将可视对象以flash方式渲染出来。
* @augments Renderer
* @param {Object} properties 创建对象的属性参数。可包含此类所有可写属性。
* @module hilo/flash/FlashRenderer
* @requires hilo/core/Class
* @requires hilo/core/Hilo
* @requires hilo/renderer/Renderer
*/
var FlashRenderer = (function(){
var _stageStateList = ["x", "y", "scaleX", "scaleY", "rotation", "visible", "alpha"];
var _stateList = _stageStateList.concat(["pivotX", "pivotY", "width", "height", "depth"]);
var _textStateList = _stateList.concat(["text", "color", "textAlign", "outline", "lineSpacing", "font"]);
var n = 0;
var state = {
View: _stateList,
Stage: _stageStateList,
Graphics: _stateList,
Text: _textStateList
};
function createFid(target){
return target.id + (n++);
}
return Hilo.Class.create(/** @lends FlashRenderer.prototype */{
Extends: Hilo.Renderer,
constructor: function(properties){
FlashRenderer.superclass.constructor.call(this, properties);
this.stage._ADD_TO_FLASH = true;
this.stage.fid = createFid(this.stage);
this.stage.flashType = "Stage";
this.commands = properties.commands || [];
this.commands.push("create", this.stage.fid, "Stage");
this.commands.push("stageAddChild", this.stage.fid);
},
/**
* @private
* @see Renderer#startDraw
*/
startDraw: function(target){
if(target == this.stage){
return true;
}
target._lastState = target._lastState || {};
//create
if(!target._ADD_TO_FLASH){
target._ADD_TO_FLASH = true;
target.fid = createFid(target);
if(target._drawTextLine){
target.flashType = "Text";
}
else if(target.beginLinearGradientFill){
target.flashType = "Graphics";
}
else if(target == this.stage){
target.flashType = "Stage";
}
else{
target.flashType = "View";
}
this.commands.push("create", target.fid, target.flashType);
}
return true;
},
/**
* @private
* @see Renderer#draw
*/
draw: function(target){
if(target == this.stage){
return;
}
target._lastState = target._lastState || {};
var lastParent = target._lastState.parent;
var parent = target.parent;
if(parent){
if(!lastParent || parent.fid != lastParent.fid){
this.commands.push("addChild", parent.fid, target.fid, target.depth);
}
}
target._lastState.parent = target.parent;
switch(target.flashType){
case "Graphics":
if(target.isDirty && target.flashGraphicsCommands && target.flashGraphicsCommands.length > 0){
this.commands.push("graphicsDraw", target.fid, target.flashGraphicsCommands.join(";"));
target.isDirty = false;
}
break;
case "Text":
break;
}
},
/**
* @private
* @see Renderer#transform
*/
transform: function(target){
var stateList = state[target.flashType];
var lastState = target._lastState = target._lastState||{};
if(stateList){
for(var i = 0,l = stateList.length;i < l;i ++){
var prop = stateList[i];
var lastValue = lastState[prop];
var value = target[prop];
lastState[prop] = value;
if(lastValue != value){
this.commands.push("setProp", target.fid, prop, value);
}
}
//画图
if(target.drawable && target.drawable.image){
var image = target.drawable.image;
var rect = target.drawable.rect;
var lastRect = lastState.rect||[];
var lastImage = lastState.image||{};
if(rect && rect.join(",")!= lastRect.join(",")){
this.commands.push("setProp", target.fid, "rect", rect.join(","));
}
if(image && (image.src != lastImage.src)) {
this.commands.push("setImage", target.fid, image.src);
}
lastState.rect = rect;
lastState.image = image;
}
}
},
/**
* @private
* @see Renderer#remove
*/
remove: function(target){
var parent = target.parent;
if(parent){
this.commands.push("removeChild", target.parent.fid, target.fid);
if(target._lastState){
target._lastState.parent = null;
}
}
}
});
})();
/**
* @class FlashAdaptor
* @module hilo/flash/FlashAdaptor
* @requires hilo/core/Hilo
* @requires hilo/view/Text
* @requires hilo/view/Graphics
* @requires hilo/media/WebAudio
* @requires hilo/media/WebSound
* @requires hilo/view/Stage
* @requires hilo/flash/FlashRenderer
*/
var FlashAdaptor = (function(){
var scripts = document.scripts;
var selfScript = scripts[scripts.length - 1];
var scriptDir = selfScript.src.substring(0, selfScript.src.lastIndexOf('/') + 1);
var defaultSwf = scriptDir + 'hilo.swf';
var defaultOption = {
url: defaultSwf,
id: "hiloFlash",
width: "100%",
height: "100%",
color: "#ffffff",
fps: 60
};
var imageCallBacks = {};
var isFlashReady = false;
var flashCommands = [];
var Adaptor = {
/**
* 初始化flash
* @public
* @method init
* @param {Object} option 参数option定义
* option.url flash网址
* option.fps flash fps, 默认60
* option.forceFlash 强制falsh模式
* option.id flash id,默认 hiloFlash
*/
init:function(option){
option = option || {};
var that = this;
if(!Hilo.browser.supportCanvas || option.forceFlash || location.search.indexOf("forceFlash") > -1){
Hilo.isFlash = true;
this._addFlashCallback();
this._flashShim(option);
}
else{
Hilo.View.prototype.release = function(){
this.removeFromParent();
};
}
},
setFps:function(fps){
if(this._fps != fps){
this._fps = fps;
flashCommands.push("setFps", fps);
}
},
_flashShim:function(option){
var that = this;
option = Hilo.copy(defaultOption, option||{});
Array.prototype.indexOf = Array.prototype.indexOf||function(a){
for(var i = 0, l = this.length;i > l;i ++){
if(this[i] === a){
return i;
}
}
return -1;
};
Hilo.Stage.prototype._initRenderer = function(properties){
var canvas = this.canvas;
if(typeof canvas === 'string') canvas = Hilo.getElement(canvas);
var container = properties.container;
if(typeof container === 'string') container = Hilo.getElement(container);
if(!container) container = document.body;
if(canvas && canvas.parentNode){
container = container||canvas.parentNode;
canvas.parentNode.removeChild(canvas);
}
this.canvas = container;
var width = this.width, height = this.height,
viewport = this.updateViewport();
if(!properties.width) width = (viewport && viewport.width) || 320;
if(!properties.height) height = (viewport && viewport.height) || 480;
that._insertSwf(Hilo.copy(option, {
container:container,
width:width * (this.scaleX||1),
height:height * (this.scaleY||1)
}));
var props = {canvas:container, stage:this, commands:flashCommands};
this.renderer = new FlashRenderer(props);
};
Hilo.Stage.prototype.addTo = function(domElement){
var swf = this._swf;
if(swf && swf.parentNode !== domElement){
domElement.appendChild(swf);
}
return this;
};
var enableDOMEvent = Hilo.Stage.prototype.enableDOMEvent;
Hilo.Stage.prototype.enableDOMEvent = function(type, enabled){
var canvas = this.canvas;
if(!canvas.addEventListener){
canvas.addEventListener = function(type, handler){
canvas.attachEvent('on' + type, handler);
};
canvas.removeEventListener = function(type, handler){
canvas.detachEvent('on' + type, handler);
};
}
return enableDOMEvent.call(this, type, enabled);
};
var onDOMEvent = Hilo.Stage.prototype._onDOMEvent;
Hilo.Stage.prototype._onDOMEvent = function(e){
onDOMEvent.call(this, e || fixEvent());
};
Hilo.View.prototype.release = function(){
this.removeFromParent();
if(this.fid){
flashCommands.push("release", this.fid);
}
};
Hilo.Text.prototype.render = function(renderer){
renderer.draw(this);
};
Hilo.Graphics.prototype.render = function(renderer){
renderer.draw(this);
};
var graphicsFuncs = [
"lineStyle", "beginFill", "endFill",
"beginBitmapFill", "beginPath", "closePath", "moveTo", "lineTo", "quadraticCurveTo", "bezierCurveTo",
"drawRect", "drawRoundRectComplex", "drawRoundRect", "drawCircle", "drawEllipse", "cache", "uncache", "clear"
];
//flashGraphicsCommands command由";"分割 参数由","分割 参数中数组由":"分割
for(var i = 0;i < graphicsFuncs.length;i ++){
var funcName = graphicsFuncs[i];
Hilo.Graphics.prototype[funcName] = function(funcName){
return function(){
var args = Array.prototype.slice.call(arguments);
var arr = [funcName].concat(args).join(",");
this.flashGraphicsCommands = this.flashGraphicsCommands||[];
this.flashGraphicsCommands.push(arr);
this.isDirty = true;
return this;
}
}(funcName);
}
Hilo.Graphics.prototype.beginRadialGradientFill = function(x0, y0, r0, x1, y1, r1, colors, ratios){
var cmd = ["beginRadialGradientFill", x0, y0, r0, x1, y1, r1, colors.join(":"), ratios.join(":")].join(",");
this.flashGraphicsCommands = this.flashGraphicsCommands||[];
this.flashGraphicsCommands.push(cmd);
this.isDirty = true;
return this;
};
Hilo.Graphics.prototype.beginLinearGradientFill = function(x0, y0, x1, y1, colors, ratios){
var cmd = ["beginLinearGradientFill", x0, y0, x1, y1, colors.join(":"), ratios.join(":")].join(",");
this.flashGraphicsCommands = this.flashGraphicsCommands||[];
this.flashGraphicsCommands.push(cmd);
this.isDirty = true;
return this;
};
Hilo.Graphics.prototype.drawSVGPath = function(pathData){
var me = this, addAction = me._addAction,
path = pathData.split(/,| (?=[a-zA-Z])/);
me.beginPath();
for(var i = 0, len = path.length; i < len; i++){
var str = path[i], cmd = str.charAt(0).toUpperCase(), p = str.substring(1).split(/,| /);
if(p[0].length == 0) p.shift();
switch(cmd){
case 'M':
me.moveTo(p[0], p[1]);
break;
case 'L':
me.lineTo(p[0], p[1]);
break;
case 'C':
me.bezierCurveTo(p[0], p[1], p[2], p[3], p[4], p[5]);
break;
case 'Z':
me.closePath();
break;
}
}
return me;
};
Hilo.WebSound.removeAudio = function(source){
var src = typeof source === 'string' ? source : source.src;
var audio = this._audios[src];
if(audio){
audio.stop();
audio.off();
audio.release();
this._audios[src] = null;
delete this._audios[src];
}
};
Hilo.WebAudio.isSupported = true;
Hilo.WebAudio.enabled = true;
Hilo.WebAudio.enable = function(){};
Hilo.WebAudio.prototype._init = function(){
this.fid = Hilo.getUid("audio");
flashCommands.push("audio", "create", this.fid, this.src);
if(this.autoPlay){
this.play();
}
};
Hilo.WebAudio.prototype.load = function(){
flashCommands.push("audio", "load", this.fid);
return this;
};
Hilo.WebAudio.prototype.play = function(){
flashCommands.push("audio", "play", this.fid, this.loop?1:0);
return this;
};
Hilo.WebAudio.prototype.pause = function(){
flashCommands.push("audio", "pause", this.fid);
return this;
};
Hilo.WebAudio.prototype.resume = function(){
flashCommands.push("audio", "resume", this.fid);
return this;
};
Hilo.WebAudio.prototype.stop = function(){
flashCommands.push("audio", "stop", this.fid);
return this;
};
Hilo.WebAudio.prototype.setVolume = function(volume){
flashCommands.push("audio", "setVolume", this.fid, volume);
return this;
};
Hilo.WebAudio.prototype.setMute = function(muted){
flashCommands.push("audio", "setMute", this.fid, muted?1:0);
return this;
};
Hilo.WebAudio.prototype.release = function(){
flashCommands.push("audio", "release", this.fid);
return this;
};
},
_insertSwf:function(option){
var that = this;
var swf;
var src = option.url;
var id = option.id;
var color = option.color||null;
var fps = option.fps;
var container = option.container;
var width = option.width;
var height = option.height;
this.setFps(fps);
if(window.attachEvent){
var hasHTML = container.innerHTML;
container.innerHTML =
'' + hasHTML;
var swf = container.getElementsByTagName("object")[0];
swf["movie"] = src;
}
else{
swf = document.createElement("embed");
swf.setAttribute("src",src);
swf.setAttribute("type","application/x-shockwave-flash");
swf.setAttribute("allowScriptAccess","always");
swf.setAttribute("allowFullScreen","true");
swf.setAttribute("bgcolor",color);
swf.setAttribute("pluginspage","http://www.adobe.com/go/getflashplayer_cn");
swf.setAttribute("wmode", "transparent");
swf.setAttribute("FlashVars", "debug=0");
container.appendChild(swf);
}
swf.name = id;
swf.width = width;
swf.height = height;
swf.id = id;
this._swf = swf;
setInterval(function(){
that.tick();
}, 1000/fps)
return swf;
},
tick:function(){
if(isFlashReady && flashCommands.length > 0){
this._swf.CallFunction(
''
+ flashCommands.join("√") + ''
);
// console.log("executeCommand", flashCommands.join(","));
flashCommands.length = 0;
}
},
_addFlashCallback:function(){
/*
* 加载flash图片
* @method loadFlashImage
*/
Hilo.loadFlashImage = function(src, successHandler, errorHandler){
imageCallBacks[src] = imageCallBacks[src]||[];
imageCallBacks[src].push([successHandler, errorHandler||successHandler]);
flashCommands.push("loadImage", src);
};
/*
*flash 可以调接口时回调函数
*/
Hilo.unlock = function(){
isFlashReady = true;
};
/*
* falsh图片加载完回调函数
* @argument src:图片地址
* @argument errorCode: 0:图片加载成功, 1:图片加载失败
* @argument width:图片宽
* argument height:图片高
*/
Hilo.imageCallBack = function(src, errorCode, width, height){
// console.log("imageCallBack", src, errorCode);
var arr = imageCallBacks[src];
if(arr && arr.length > 0){
for(var i = 0, l = arr.length;i < l;i ++){
arr[i][errorCode]({
target:{
src:src,
width:width,
height:height,
isFlash:true
},
errorCode:errorCode
});
}
arr.length = 0;
}
}
}
};
function fixEvent(){
var event = window.event;
var e = {
rawEvent:event,
type:event.type,
target:event.srcElememt,
preventDefault:function(){
event.returnValue = false;
},
stopPropagation:function(){
event.cancelBubble = true;
}
};
if(event.type.indexOf("mouse") != -1){
e.clientX = event.clientX;
e.clientY = event.clientY;
if(event.type == "mouseover")
e.relatedTarget = event.fromElement;
else if(event.type == "mouseout")
e.relatedTarget = event.toElement;
}
else if(event.type.indexOf("key") != -1){
e.charCode = e.keyCode = event.keyCode;
}
return e;
}
if(selfScript.getAttribute('data-auto') === 'true') Adaptor.init();
return Hilo.FlashAdaptor = Adaptor;
})();
})();