;(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; })(); })();