From c327c80a46d56ea8fed9c54b994ca24b4acf294b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Thu, 9 May 2013 18:06:48 +0300 Subject: [PATCH 01/31] Canvas only rendering WIP Broken: - DOM renderer: replace scene with transitions - Canvas: Scaling the director. --- lime/src/director.js | 62 ++++++++++++++++++++---------- lime/src/events/eventdispatcher.js | 4 +- lime/src/scene.js | 3 +- 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/lime/src/director.js b/lime/src/director.js index 798b54d5..7a635ef1 100644 --- a/lime/src/director.js +++ b/lime/src/director.js @@ -16,6 +16,7 @@ goog.require('lime'); goog.require('lime.Node'); goog.require('lime.events.EventDispatcher'); goog.require('lime.helper.PauseScene'); +goog.require('lime.Renderer.CANVAS'); goog.require('lime.scheduleManager'); goog.require('lime.transitions.Transition'); @@ -31,6 +32,8 @@ goog.require('lime.transitions.Transition'); lime.Director = function(parentElement, opt_width, opt_height) { lime.Node.call(this); + this.container = parentElement; + // Unlike other nodes Director is always in the DOM as // it requires parentNode in the constructor this.inTree_ = true; @@ -54,10 +57,17 @@ lime.Director = function(parentElement, opt_width, opt_height) { this.coverStack_ = []; this.domClassName = goog.getCssName('lime-director'); - this.createDomElement(); - parentElement.appendChild(this.domElement); + if (parentElement.tagName === 'CANVAS') { + this.setRenderer(lime.Renderer.CANVAS); + this.domElement = this.container; + } + this.updateDomElement(); + + if (this.domElement && this.domElement !== this.container) { + parentElement.appendChild(this.domElement); + } if (goog.userAgent.WEBKIT && goog.userAgent.MOBILE) { //todo: Not pretty solution. Cover layers may not be needed at all. @@ -90,8 +100,8 @@ lime.Director = function(parentElement, opt_width, opt_height) { meta.content = content; document.getElementsByTagName('head').item(0).appendChild(meta); - - + + //todo: look for a less hacky solution if(goog.userAgent.MOBILE && !goog.global['navigator'].standalone){ var that = this; @@ -112,7 +122,6 @@ lime.Director = function(parentElement, opt_width, opt_height) { this.setDisplayFPS(goog.DEBUG); this.setPaused(false); - var vsm = new goog.dom.ViewportSizeMonitor(); goog.events.listen(vsm, goog.events.EventType.RESIZE, this.invalidateSize_, false, this); @@ -135,7 +144,7 @@ lime.Director = function(parentElement, opt_width, opt_height) { this.invalidateSize_(); - + if(goog.DEBUG){ goog.events.listen(goog.global,'keyup',this.keyUpHandler_,false,this); } @@ -143,6 +152,11 @@ lime.Director = function(parentElement, opt_width, opt_height) { }; goog.inherits(lime.Director, lime.Node); +/* +lime.Director.prototype.needsDomElement = function() { + return this.container.tagName !== 'CANVAS' +}; +*/ /** * Milliseconds between recalculating FPS value @@ -221,6 +235,8 @@ lime.Director.prototype.setDisplayFPS = function(value) { this.frames_ = 0; this.accumDt_ = 0; + if (!this.domElement) return; + this.fpsElement_ = goog.dom.createDom('div'); goog.dom.classes.add(this.fpsElement_, goog.getCssName('lime-fps')); this.domElement.parentNode.appendChild(this.fpsElement_); @@ -300,20 +316,24 @@ lime.Director.prototype.replaceScene = function(scene, opt_transition, this.sceneStack_.length = 0; this.sceneStack_.push(scene); - scene.domElement.style['display']='none'; - this.domElement.appendChild(scene.domElement); + if (scene.domElement) { + scene.domElement.style['display']='none'; + // this.domElement.appendChild(scene.domElement); + } + this.appendChild(scene); + scene.parent_ = this; scene.wasAddedToTree(); var transition = new transitionclass(outgoing, scene); - + goog.events.listenOnce(transition,'end',function() { var i = removelist.length; while (--i >= 0) { goog.dom.removeNode(removelist[i]); } removelist.length = 0; - + },false,this); if (goog.isDef(opt_duration)) { @@ -326,11 +346,11 @@ lime.Director.prototype.replaceScene = function(scene, opt_transition, }; /** @inheritDoc */ -lime.Director.prototype.updateLayout = function() { +/*lime.Director.prototype.updateLayout = function() { // debugger; this.dirty_ &= ~lime.Dirty.LAYOUT; }; - +*/ /** * Push scene to the top of scene stack * @param {lime.Scene} scene New scene. @@ -371,11 +391,11 @@ lime.Director.prototype.pushScene = function(scene, opt_transition, opt_duration * @return Transition object if opt_transition is defined */ lime.Director.prototype.popScene = function(opt_transition, opt_duration) { - var transition, + var transition, outgoing = this.getCurrentScene(); - + if (goog.isNull(outgoing)) return; - + var popOutgoing = function() { outgoing.wasRemovedFromTree(); outgoing.parent_ = null; @@ -386,7 +406,7 @@ lime.Director.prototype.popScene = function(opt_transition, opt_duration) { // Transitions require an existing incoming scene if (goog.isDef(opt_transition) && (this.sceneStack_.length > 1)) { transition = new opt_transition(outgoing, this.sceneStack_[this.sceneStack_.length - 2]); - + if (goog.isDef(opt_duration)) { transition.setDuration(opt_duration); } @@ -488,7 +508,7 @@ lime.Director.prototype.localToScreen = function(c) { * @inheritDoc */ lime.Director.prototype.update = function() { - lime.Node.prototype.update.call(this); + lime.Node.prototype.update.apply(this, arguments); var i = this.coverStack_.length; while (--i >= 0) { @@ -503,9 +523,9 @@ lime.Director.prototype.update = function() { */ lime.Director.prototype.invalidateSize_ = function() { - var stageSize = goog.style.getSize(this.domElement.parentNode); + var stageSize = goog.style.getSize(this.container); - if (this.domElement.parentNode == document.body) { + if (this.container == document.body) { window.scrollTo(0, 0); if (goog.isNumber(window.innerHeight)) { stageSize.height = window.innerHeight; @@ -525,7 +545,7 @@ lime.Director.prototype.invalidateSize_ = function() { } this.updateDomOffset_(); - + // overflow hidden is for hiding away unused edges of document // height addition is because scroll(0,0) doesn't work any more if the // document has no edge @tonis todo:look for less hacky solution(iframe?). @@ -574,7 +594,7 @@ lime.Director.prototype.makeMobileWebAppCapable = function() { * @private */ lime.Director.prototype.updateDomOffset_ = function() { - this.domOffset = goog.style.getPageOffset(this.domElement.parentNode); + this.domOffset = goog.style.getPageOffset(this.container); }; /** diff --git a/lime/src/events/eventdispatcher.js b/lime/src/events/eventdispatcher.js index 455223c4..a83bc691 100644 --- a/lime/src/events/eventdispatcher.js +++ b/lime/src/events/eventdispatcher.js @@ -27,7 +27,7 @@ lime.events.EventDispatcher.prototype.register = function(node, eventType) { //dom tree changes otherwise goog.events.listen(eventType.substring(0, 5) == 'touch' && node!=this.director ? document : (eventType.substring(0, 3) == 'key' ? - window : this.director.domElement.parentNode), eventType, + window : this.director.container), eventType, this, false, this); } else { @@ -47,7 +47,7 @@ lime.events.EventDispatcher.prototype.release = function(node, eventType) { if (goog.isDef(this.handlers[eventType])) { goog.array.remove(this.handlers[eventType], node); if (!this.handlers[eventType].length) { - goog.events.unlisten(this.director.domElement.parentNode, + goog.events.unlisten(this.director.container, eventType, this, false, this); delete this.handlers[eventType]; } diff --git a/lime/src/scene.js b/lime/src/scene.js index 2ee7dcee..30afe54f 100644 --- a/lime/src/scene.js +++ b/lime/src/scene.js @@ -15,7 +15,8 @@ lime.Scene = function() { this.setAnchorPoint(0, 0); this.domClassName = goog.getCssName('lime-scene'); - this.createDomElement(); + + //this.updateDomElement(); }; goog.inherits(lime.Scene, lime.Node); From 1c6b4411056d41928ac0677b9882f6f7c2f4addc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Fri, 10 May 2013 11:32:21 +0300 Subject: [PATCH 02/31] Allow tests to run in canvas-only --- lime/demos/tests/anim1.js | 6 +-- lime/demos/tests/anim2.js | 4 +- lime/demos/tests/anim3.js | 4 +- lime/demos/tests/anim4.js | 4 +- lime/demos/tests/audio.js | 4 +- lime/demos/tests/autoresize.js | 4 +- lime/demos/tests/box2d.js | 4 +- lime/demos/tests/box2d_2.js | 4 +- lime/demos/tests/button1.js | 4 +- lime/demos/tests/button2.js | 4 +- lime/demos/tests/canvas.js | 4 +- lime/demos/tests/canvas2.js | 4 +- lime/demos/tests/canvascontext.js | 4 +- lime/demos/tests/drag1.js | 4 +- lime/demos/tests/events1.js | 4 +- lime/demos/tests/events2.js | 4 +- lime/demos/tests/events3.js | 4 +- lime/demos/tests/events4.js | 4 +- lime/demos/tests/events5.js | 4 +- lime/demos/tests/frame1.js | 4 +- lime/demos/tests/frame2.js | 4 +- lime/demos/tests/frame3.js | 4 +- lime/demos/tests/frame4.js | 4 +- lime/demos/tests/keyframe.js | 4 +- lime/demos/tests/keyframe2.js | 4 +- lime/demos/tests/labels1.js | 4 +- lime/demos/tests/labels2.js | 4 +- lime/demos/tests/mask.js | 4 +- lime/demos/tests/mask2.js | 4 +- lime/demos/tests/opacity.js | 4 +- lime/demos/tests/poly1.js | 4 +- lime/demos/tests/run_canvasonly.htm | 65 +++++++++++++++++++++++++++++ lime/demos/tests/scroll.js | 4 +- lime/demos/tests/shapes1.js | 4 +- lime/demos/tests/shapes2.js | 4 +- lime/demos/tests/shapes3.js | 4 +- lime/demos/tests/stroke.js | 26 ++++++------ lime/demos/tests/tiled1.js | 10 ++--- lime/demos/tests/tiled2.js | 12 +++--- lime/demos/tests/tiled3.js | 12 +++--- lime/demos/tests/transitions1.js | 8 ++-- 41 files changed, 170 insertions(+), 105 deletions(-) create mode 100644 lime/demos/tests/run_canvasonly.htm diff --git a/lime/demos/tests/anim1.js b/lime/demos/tests/anim1.js index 8b1b4995..31a2b5eb 100644 --- a/lime/demos/tests/anim1.js +++ b/lime/demos/tests/anim1.js @@ -24,10 +24,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); @@ -44,7 +44,7 @@ test.start = function() { new lime.animation.MoveBy(200, 0).setDuration(1.5), new lime.animation.ScaleBy(2), new lime.animation.ColorTo(0,200,0) - + ), new lime.animation.Spawn( new lime.animation.MoveBy(-200, 0).setDuration(1.5), new lime.animation.ScaleBy(.5), diff --git a/lime/demos/tests/anim2.js b/lime/demos/tests/anim2.js index 82e7e0cc..07504e28 100644 --- a/lime/demos/tests/anim2.js +++ b/lime/demos/tests/anim2.js @@ -22,10 +22,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/anim3.js b/lime/demos/tests/anim3.js index ec544968..e65e8aeb 100644 --- a/lime/demos/tests/anim3.js +++ b/lime/demos/tests/anim3.js @@ -21,10 +21,10 @@ test.WIDTH = 800; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/anim4.js b/lime/demos/tests/anim4.js index 3f927921..2b7fad7d 100644 --- a/lime/demos/tests/anim4.js +++ b/lime/demos/tests/anim4.js @@ -19,10 +19,10 @@ test.WIDTH = 800; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body,1024, 768); + test.director = new lime.Director(parent || document.body,1024, 768); test.director.makeMobileWebAppCapable(); var scene = new lime.Scene(); diff --git a/lime/demos/tests/audio.js b/lime/demos/tests/audio.js index ad7b9f8c..266165ca 100644 --- a/lime/demos/tests/audio.js +++ b/lime/demos/tests/audio.js @@ -23,10 +23,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); diff --git a/lime/demos/tests/autoresize.js b/lime/demos/tests/autoresize.js index c34d5a42..3c6889f0 100644 --- a/lime/demos/tests/autoresize.js +++ b/lime/demos/tests/autoresize.js @@ -22,10 +22,10 @@ test.WIDTH = 800; test.HEIGHT = 600; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/box2d.js b/lime/demos/tests/box2d.js index 09c56e8b..8ab9a0fa 100644 --- a/lime/demos/tests/box2d.js +++ b/lime/demos/tests/box2d.js @@ -23,7 +23,7 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { /* @@ -33,7 +33,7 @@ test.start = function() { */ //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene(); diff --git a/lime/demos/tests/box2d_2.js b/lime/demos/tests/box2d_2.js index cd075901..6cda663a 100644 --- a/lime/demos/tests/box2d_2.js +++ b/lime/demos/tests/box2d_2.js @@ -23,7 +23,7 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { /* @@ -33,7 +33,7 @@ test.start = function() { */ //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene(); diff --git a/lime/demos/tests/button1.js b/lime/demos/tests/button1.js index 12aca40f..f12b1fd9 100644 --- a/lime/demos/tests/button1.js +++ b/lime/demos/tests/button1.js @@ -17,10 +17,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); diff --git a/lime/demos/tests/button2.js b/lime/demos/tests/button2.js index badefd93..88958e52 100644 --- a/lime/demos/tests/button2.js +++ b/lime/demos/tests/button2.js @@ -19,10 +19,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); diff --git a/lime/demos/tests/canvas.js b/lime/demos/tests/canvas.js index a47f4b34..01a9688d 100644 --- a/lime/demos/tests/canvas.js +++ b/lime/demos/tests/canvas.js @@ -15,10 +15,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/canvas2.js b/lime/demos/tests/canvas2.js index 06e6443a..86f37a73 100644 --- a/lime/demos/tests/canvas2.js +++ b/lime/demos/tests/canvas2.js @@ -21,9 +21,9 @@ test.WIDTH = 500; test.HEIGHT = 350; -test.start = function() { +test.start = function(parent) { - var director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + var director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); director.makeMobileWebAppCapable(); var scene = new lime.Scene; diff --git a/lime/demos/tests/canvascontext.js b/lime/demos/tests/canvascontext.js index e9380cd3..5fb87e3a 100644 --- a/lime/demos/tests/canvascontext.js +++ b/lime/demos/tests/canvascontext.js @@ -19,10 +19,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/drag1.js b/lime/demos/tests/drag1.js index 1a65fabf..c377b4c9 100644 --- a/lime/demos/tests/drag1.js +++ b/lime/demos/tests/drag1.js @@ -18,10 +18,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); diff --git a/lime/demos/tests/events1.js b/lime/demos/tests/events1.js index bee2885e..2539025c 100644 --- a/lime/demos/tests/events1.js +++ b/lime/demos/tests/events1.js @@ -19,10 +19,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); diff --git a/lime/demos/tests/events2.js b/lime/demos/tests/events2.js index f241a026..eaaa7531 100644 --- a/lime/demos/tests/events2.js +++ b/lime/demos/tests/events2.js @@ -16,10 +16,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); diff --git a/lime/demos/tests/events3.js b/lime/demos/tests/events3.js index f5c38ec3..8d34610c 100644 --- a/lime/demos/tests/events3.js +++ b/lime/demos/tests/events3.js @@ -18,10 +18,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); diff --git a/lime/demos/tests/events4.js b/lime/demos/tests/events4.js index 2c7d7794..23dadd0a 100644 --- a/lime/demos/tests/events4.js +++ b/lime/demos/tests/events4.js @@ -17,10 +17,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); diff --git a/lime/demos/tests/events5.js b/lime/demos/tests/events5.js index f2fd10f7..456291b7 100644 --- a/lime/demos/tests/events5.js +++ b/lime/demos/tests/events5.js @@ -17,10 +17,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); diff --git a/lime/demos/tests/frame1.js b/lime/demos/tests/frame1.js index 3216e23d..c231d30b 100644 --- a/lime/demos/tests/frame1.js +++ b/lime/demos/tests/frame1.js @@ -15,10 +15,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/frame2.js b/lime/demos/tests/frame2.js index 249de478..538b117a 100644 --- a/lime/demos/tests/frame2.js +++ b/lime/demos/tests/frame2.js @@ -14,10 +14,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/frame3.js b/lime/demos/tests/frame3.js index 8ebfa296..e23ae1fe 100644 --- a/lime/demos/tests/frame3.js +++ b/lime/demos/tests/frame3.js @@ -16,10 +16,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/frame4.js b/lime/demos/tests/frame4.js index a3dd1d0d..46f50c0a 100644 --- a/lime/demos/tests/frame4.js +++ b/lime/demos/tests/frame4.js @@ -17,10 +17,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/keyframe.js b/lime/demos/tests/keyframe.js index 58878f2e..52ebe903 100644 --- a/lime/demos/tests/keyframe.js +++ b/lime/demos/tests/keyframe.js @@ -13,10 +13,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/keyframe2.js b/lime/demos/tests/keyframe2.js index 897cc63e..d2f9aac8 100644 --- a/lime/demos/tests/keyframe2.js +++ b/lime/demos/tests/keyframe2.js @@ -19,10 +19,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/labels1.js b/lime/demos/tests/labels1.js index aee4b719..ed57e7b7 100644 --- a/lime/demos/tests/labels1.js +++ b/lime/demos/tests/labels1.js @@ -13,10 +13,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/labels2.js b/lime/demos/tests/labels2.js index 1034a7c0..d4868315 100644 --- a/lime/demos/tests/labels2.js +++ b/lime/demos/tests/labels2.js @@ -15,10 +15,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/mask.js b/lime/demos/tests/mask.js index 88ebc9c5..03bb266b 100644 --- a/lime/demos/tests/mask.js +++ b/lime/demos/tests/mask.js @@ -15,10 +15,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/mask2.js b/lime/demos/tests/mask2.js index f4246963..2c09193c 100644 --- a/lime/demos/tests/mask2.js +++ b/lime/demos/tests/mask2.js @@ -15,10 +15,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/opacity.js b/lime/demos/tests/opacity.js index 4fd010da..f5d804c2 100644 --- a/lime/demos/tests/opacity.js +++ b/lime/demos/tests/opacity.js @@ -17,10 +17,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/poly1.js b/lime/demos/tests/poly1.js index 8d2a883d..b47358e7 100644 --- a/lime/demos/tests/poly1.js +++ b/lime/demos/tests/poly1.js @@ -15,10 +15,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/run_canvasonly.htm b/lime/demos/tests/run_canvasonly.htm new file mode 100644 index 00000000..8a2cb7d4 --- /dev/null +++ b/lime/demos/tests/run_canvasonly.htm @@ -0,0 +1,65 @@ + + + + +Run demos + + + + + + + + + + + + + + diff --git a/lime/demos/tests/scroll.js b/lime/demos/tests/scroll.js index 8afcf1de..891eea73 100644 --- a/lime/demos/tests/scroll.js +++ b/lime/demos/tests/scroll.js @@ -15,10 +15,10 @@ test.WIDTH = 800; test.HEIGHT = 600; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/shapes1.js b/lime/demos/tests/shapes1.js index 35631e11..bc399bb0 100644 --- a/lime/demos/tests/shapes1.js +++ b/lime/demos/tests/shapes1.js @@ -13,10 +13,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/shapes2.js b/lime/demos/tests/shapes2.js index d2405fee..77f995e4 100644 --- a/lime/demos/tests/shapes2.js +++ b/lime/demos/tests/shapes2.js @@ -14,10 +14,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/shapes3.js b/lime/demos/tests/shapes3.js index 79512faf..01b8f92e 100644 --- a/lime/demos/tests/shapes3.js +++ b/lime/demos/tests/shapes3.js @@ -15,10 +15,10 @@ test.WIDTH = 600; test.HEIGHT = 400; -test.start = function() { +test.start = function(parent) { //director - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; diff --git a/lime/demos/tests/stroke.js b/lime/demos/tests/stroke.js index b5f83e16..0fd7195b 100644 --- a/lime/demos/tests/stroke.js +++ b/lime/demos/tests/stroke.js @@ -15,45 +15,45 @@ test.WIDTH = 500; test.HEIGHT = 350; -test.start = function() { +test.start = function(parent) { - var director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + var director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); director.makeMobileWebAppCapable(); var scene = new lime.Scene; - + var layer = new lime.Layer().setPosition(70,170); scene.appendChild(layer); - + var sprite = new lime.Sprite().setSize(90,90).setFill('#c00'); layer.appendChild(sprite); - + var circle = new lime.Circle().setSize(90,90).setFill('assets/html5_badge.png').setPosition(80,0); layer.appendChild(circle); - + var rrect = new lime.RoundedRect().setSize(70,90).setRadius(15).setRotation(-20).setFill( new lime.fill.LinearGradient().setDirection(0,0,1,1). addColorStop(0,0,0,100,.9).addColorStop(1,0,0,100,0) ).setPosition(160,0); layer.appendChild(rrect); - + var tri = new lime.Polygon().setPoints(0,-70 ,40,0, -40,0).setFill( new lime.fill.LinearGradient().setDirection(0,0,0,1). addColorStop(0.4,200,0,0).addColorStop(1,0,200,0) ).setPosition(220,20); layer.appendChild(tri); - + var sprite2 = new lime.Label().setText('Hi').setFontColor('#fff').setFontSize(32). setPadding(15,10).setRotation(10).setFill('#0a0').setPosition(280,0); layer.appendChild(sprite2); - + var circle2 = new lime.Circle().setSize(100,70).setRotation(5).setPosition(350,0); layer.appendChild(circle2); - + var index = 0; lime.scheduleManager.scheduleWithDelay(function(){ var child = layer.getChildAt(index); - + child.setStroke( Math.floor(Math.random()*6)*2+4, Math.floor(Math.random()*255), @@ -61,11 +61,11 @@ test.start = function() { Math.floor(Math.random()*255), Math.random()*.5+.5 ); - + index++; if(index>=layer.getNumberOfChildren()) index=0; },this,500); - + // set active scene director.replaceScene(scene); }; diff --git a/lime/demos/tests/tiled1.js b/lime/demos/tests/tiled1.js index bece3dd5..49fd87d0 100644 --- a/lime/demos/tests/tiled1.js +++ b/lime/demos/tests/tiled1.js @@ -13,17 +13,17 @@ goog.require('lime.parser.TMX'); test.WIDTH = 800; test.HEIGHT = 600; -test.start = function(){ +test.start = function(parent){ - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; - + layer = new lime.Layer().setRenderer(lime.Renderer.CANVAS); //canvas renderer is recommended for tiled maps. much faster in most cases gamescene.appendChild(layer); - + var tmx = new lime.parser.TMX('assets/desert.tmx'); for(var j = 0; j < tmx.layers.length; j++) { @@ -37,5 +37,5 @@ test.start = function(){ } // set active scene test.director.replaceScene(gamescene); - + } \ No newline at end of file diff --git a/lime/demos/tests/tiled2.js b/lime/demos/tests/tiled2.js index b8b238d2..2b42d2d2 100644 --- a/lime/demos/tests/tiled2.js +++ b/lime/demos/tests/tiled2.js @@ -13,13 +13,13 @@ goog.require('lime.parser.TMX'); test.WIDTH = 800; test.HEIGHT = 600; -test.start = function(){ +test.start = function(parent){ - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; - + var tmx = new lime.parser.TMX('assets/sewers.tmx'); //canvas renderer is recommended for tiled maps. much faster in most cases layer = new lime.Layer().setRenderer(lime.Renderer.CANVAS); @@ -34,12 +34,12 @@ test.start = function(){ layer.appendChild(sprite); } } - + goog.events.listen(layer, ['mousedown', 'touchstart'], function(e) { e.startDrag(); }); - + // set active scene test.director.replaceScene(gamescene); - + } \ No newline at end of file diff --git a/lime/demos/tests/tiled3.js b/lime/demos/tests/tiled3.js index 98502c87..17ce796f 100644 --- a/lime/demos/tests/tiled3.js +++ b/lime/demos/tests/tiled3.js @@ -13,13 +13,13 @@ goog.require('lime.parser.TMX'); test.WIDTH = 800; test.HEIGHT = 600; -test.start = function(){ +test.start = function(parent){ - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var gamescene = new lime.Scene; - + var tmx = new lime.parser.TMX('assets/isometric_grass_and_water.tmx'); layer = new lime.Layer().setRenderer(lime.Renderer.CANVAS).setPosition(400,0); //canvas renderer is recommended for tiled maps. much faster in most cases @@ -34,12 +34,12 @@ test.start = function(){ layer.appendChild(sprite); } } - + goog.events.listen(layer, ['mousedown', 'touchstart'], function(e) { e.startDrag(); }); - + // set active scene test.director.replaceScene(gamescene); - + } \ No newline at end of file diff --git a/lime/demos/tests/transitions1.js b/lime/demos/tests/transitions1.js index e6e20937..bfaf6df2 100644 --- a/lime/demos/tests/transitions1.js +++ b/lime/demos/tests/transitions1.js @@ -14,9 +14,9 @@ goog.require('lime.transitions.SlideIn'); test.WIDTH = 800; test.HEIGHT = 600; -test.start = function() { +test.start = function(parent) { - test.director = new lime.Director(document.body, test.WIDTH, test.HEIGHT); + test.director = new lime.Director(parent || document.body, test.WIDTH, test.HEIGHT); test.director.makeMobileWebAppCapable(); var scene1 = test.createScene('#666'); @@ -42,11 +42,11 @@ test.start = function() { scene2.appendChild(button1); scene2.appendChild(button2); - + goog.events.listenOnce(button1, 'click', function() { test.director.popScene(); }, false, this); - + goog.events.listenOnce(button2, 'click', function() { test.director.popScene(lime.transitions.SlideIn); }, false, this); From 087b3ba90cc292b3fc33dcc6545239b10f906be1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Fri, 10 May 2013 11:34:22 +0300 Subject: [PATCH 03/31] Scene replacement fixes --- lime/src/director.js | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/lime/src/director.js b/lime/src/director.js index 7a635ef1..585e4263 100644 --- a/lime/src/director.js +++ b/lime/src/director.js @@ -309,28 +309,28 @@ lime.Director.prototype.replaceScene = function(scene, opt_transition, var removelist = []; var i = this.sceneStack_.length; while (--i >= 0) { - this.sceneStack_[i].wasRemovedFromTree(); - removelist.push(this.sceneStack_[i].domElement); - this.sceneStack_[i].parent_ = null; + //this.sceneStack_[i].wasRemovedFromTree(); + removelist.push(this.sceneStack_[i]); + //this.sceneStack_[i].parent_ = null; } this.sceneStack_.length = 0; this.sceneStack_.push(scene); if (scene.domElement) { - scene.domElement.style['display']='none'; + // scene.domElement.style['display']='none'; // this.domElement.appendChild(scene.domElement); } - this.appendChild(scene); + this.appendChild(scene); - scene.parent_ = this; - scene.wasAddedToTree(); + //scene.parent_ = this; + //scene.wasAddedToTree(); var transition = new transitionclass(outgoing, scene); goog.events.listenOnce(transition,'end',function() { var i = removelist.length; while (--i >= 0) { - goog.dom.removeNode(removelist[i]); + this.removeChild(removelist[i]); } removelist.length = 0; @@ -373,9 +373,10 @@ lime.Director.prototype.pushScene = function(scene, opt_transition, opt_duration scene.domElement.style['display'] = 'none'; } this.sceneStack_.push(scene); - this.domElement.appendChild(scene.domElement); - scene.parent_ = this; - scene.wasAddedToTree(); + this.appendChild(scene); + //this.domElement.appendChild(scene.domElement); + //scene.parent_ = this; + //scene.wasAddedToTree(); if (transition) { transition.start(); @@ -397,9 +398,10 @@ lime.Director.prototype.popScene = function(opt_transition, opt_duration) { if (goog.isNull(outgoing)) return; var popOutgoing = function() { - outgoing.wasRemovedFromTree(); - outgoing.parent_ = null; - goog.dom.removeNode(outgoing.domElement); + //outgoing.wasRemovedFromTree(); + //outgoing.parent_ = null; + this.removeChild(outgoing); + //goog.dom.removeNode(outgoing.domElement); this.sceneStack_.pop(); outgoing = null; // GC }; From 901eafa7bb27138494b9e6e3285811b03b7695aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Fri, 10 May 2013 12:32:07 +0300 Subject: [PATCH 04/31] Fix Canvas scaling --- lime/src/director.js | 15 ++++++++++++++- lime/src/renderer/canvas.js | 27 +++++++++++++++++++-------- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/lime/src/director.js b/lime/src/director.js index 585e4263..80201e8b 100644 --- a/lime/src/director.js +++ b/lime/src/director.js @@ -128,9 +128,17 @@ lime.Director = function(parentElement, opt_width, opt_height) { goog.events.listen(goog.global, 'orientationchange', this.invalidateSize_, false, this); - lime.scheduleManager.schedule(this.step_, this); + if (this.container === this.domElement) + lime.scheduleManager.schedule(function() { + var size = goog.style.getSize(parentElement); + if (size.width !== parentSize.width || size.height !== parentSize.height) { + this.invalidateSize_(); + parentSize = size; + } + }, this); + this.eventDispatcher = new lime.events.EventDispatcher(this); @@ -505,6 +513,11 @@ lime.Director.prototype.localToScreen = function(c) { return coord; }; +lime.Director.prototype.measureContents = function() { + + return this.getFrame(); + +}; /** * @inheritDoc diff --git a/lime/src/renderer/canvas.js b/lime/src/renderer/canvas.js index 8086da8a..2c542f23 100644 --- a/lime/src/renderer/canvas.js +++ b/lime/src/renderer/canvas.js @@ -38,7 +38,7 @@ lime.Renderer.CANVAS.drawCanvas = function() { } else { if (this.staticCanvas != 1 && this.children_.length != 0) { - if(!(this instanceof lime.Scene)){ + if(!(this instanceof lime.Scene) && !(this instanceof lime.Director)){ bounds.expand(PADDING, PADDING, PADDING, PADDING); } } @@ -72,12 +72,15 @@ lime.Renderer.CANVAS.drawCanvas = function() { var bsize = bounds.size(); var pxsize = bsize.clone().ceil(); + + if (this.domElement.width != pxsize.width || this.domElement.height != pxsize.height) { - this.domElement.width = pxsize.width; - this.domElement.height = pxsize.height; + if (this.domElement !== this.container) { + this.domElement.width = pxsize.width; + this.domElement.height = pxsize.height; + } this.redraw_ = 1; - // console.log('redraw'); } @@ -119,16 +122,24 @@ lime.Renderer.CANVAS.drawCanvas = function() { if (goog.isDef(this.transitionsActive_[lime.Transition.ROTATION])) { rotation = -this.transitionsActive_[lime.Transition.ROTATION]; } - lime.style.setTransform(this.domElement, - new lime.style.Transform().setPrecision(.1).translate(pos.x, pos.y). - scale(realScale.x, realScale.y).rotate(rotation)); + if (this.domElement !== this.container) { + lime.style.setTransform(this.domElement, + new lime.style.Transform().setPrecision(.1).translate(pos.x, pos.y). + scale(realScale.x, realScale.y).rotate(rotation)); + } } + + if (this.redraw_) { var context = this.domElement.getContext('2d'); - context.clearRect(0, 0, pxsize.width, pxsize.height); + context.clearRect(0, 0, this.domElement.width, this.domElement.height); context.save(); + if (this.domElement === this.container) { + context.translate(pos.x, pos.y); + context.scale(realScale.x, realScale.y); + } context.translate(this.ax, this.ay); var size = this.getSize(), anchor = this.getAnchorPoint(); From 6bcedbe02e6021b6e2726c2a21904905f80ab429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Fri, 10 May 2013 12:42:22 +0300 Subject: [PATCH 05/31] Clip director in Canvas only mode --- lime/src/renderer/canvas.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lime/src/renderer/canvas.js b/lime/src/renderer/canvas.js index 2c542f23..815bdabd 100644 --- a/lime/src/renderer/canvas.js +++ b/lime/src/renderer/canvas.js @@ -139,6 +139,15 @@ lime.Renderer.CANVAS.drawCanvas = function() { if (this.domElement === this.container) { context.translate(pos.x, pos.y); context.scale(realScale.x, realScale.y); + context.save(); + context.beginPath(); + context.moveTo(0, 0); + context.lineTo(pxsize.width, 0); + context.lineTo(pxsize.width, pxsize.height); + context.lineTo(0, pxsize.height); + context.closePath(); + context.restore(); + context.clip(); } context.translate(this.ax, this.ay); From f572dc5477e011d57e0f5fbdc4511a37d9f07859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Fri, 10 May 2013 13:32:27 +0300 Subject: [PATCH 06/31] Remove DOM calls on canvas only platforms --- lime/src/director.js | 11 +++++++---- lime/src/helper/dom.js | 12 ++++++++++++ lime/src/lime.js | 6 ++++-- 3 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 lime/src/helper/dom.js diff --git a/lime/src/director.js b/lime/src/director.js index 80201e8b..37e204e8 100644 --- a/lime/src/director.js +++ b/lime/src/director.js @@ -14,6 +14,7 @@ goog.require('goog.math.Vec2'); goog.require('goog.style'); goog.require('lime'); goog.require('lime.Node'); +goog.require('lime.dom'); goog.require('lime.events.EventDispatcher'); goog.require('lime.helper.PauseScene'); goog.require('lime.Renderer.CANVAS'); @@ -58,7 +59,8 @@ lime.Director = function(parentElement, opt_width, opt_height) { this.domClassName = goog.getCssName('lime-director'); - if (parentElement.tagName === 'CANVAS') { + if (parentElement.getContext) { + this.container.tagName = 'CANVAS'; // Ejecta hack. this.setRenderer(lime.Renderer.CANVAS); this.domElement = this.container; } @@ -243,7 +245,7 @@ lime.Director.prototype.setDisplayFPS = function(value) { this.frames_ = 0; this.accumDt_ = 0; - if (!this.domElement) return; + if (!lime.dom.isDOMSupported()) return; this.fpsElement_ = goog.dom.createDom('div'); goog.dom.classes.add(this.fpsElement_, goog.getCssName('lime-fps')); @@ -324,10 +326,10 @@ lime.Director.prototype.replaceScene = function(scene, opt_transition, this.sceneStack_.length = 0; this.sceneStack_.push(scene); - if (scene.domElement) { + /*if (scene.domElement) { // scene.domElement.style['display']='none'; // this.domElement.appendChild(scene.domElement); - } + }*/ this.appendChild(scene); //scene.parent_ = this; @@ -577,6 +579,7 @@ lime.Director.prototype.invalidateSize_ = function() { * web application on iOS devices */ lime.Director.prototype.makeMobileWebAppCapable = function() { + if (!lime.dom.isDOMSupported()) return; var meta = document.createElement('meta'); meta.name = 'apple-mobile-web-app-capable'; diff --git a/lime/src/helper/dom.js b/lime/src/helper/dom.js new file mode 100644 index 00000000..6e90cbc6 --- /dev/null +++ b/lime/src/helper/dom.js @@ -0,0 +1,12 @@ +goog.provide('lime.dom'); +goog.require('goog.dom'); + +lime.dom.isDOMSupported = function() { + // This works for Ejecta. Probably not for others. Pull request! + return !!document.head.parentNode; +} + +var old = goog.dom.getOwnerDocument; +goog.dom.getOwnerDocument = function() { + return old.apply(goog.dom, arguments) || document; +} \ No newline at end of file diff --git a/lime/src/lime.js b/lime/src/lime.js index fd905f60..d4abe5fd 100644 --- a/lime/src/lime.js +++ b/lime/src/lime.js @@ -2,6 +2,7 @@ goog.provide('lime'); goog.require('goog.style'); goog.require('lime.css'); +goog.require('lime.dom'); goog.require('lime.userAgent'); (function() { @@ -107,6 +108,7 @@ lime.Transition = { OPACITY: 5 }; - -goog.style.installStyles(lime.css.css(null, null)); +if (lime.dom.isDOMSupported()) { + goog.style.installStyles(lime.css.css(null, null)); +} From 6b1a27f7e3dabaa9e7eed16b869b3f4a4cb843e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Fri, 10 May 2013 13:33:16 +0300 Subject: [PATCH 07/31] Temp remove some label functionality(Ejecta is picky) --- lime/src/shape/label.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lime/src/shape/label.js b/lime/src/shape/label.js index 67f86766..944a0037 100644 --- a/lime/src/shape/label.js +++ b/lime/src/shape/label.js @@ -75,7 +75,8 @@ lime.Label.prototype.measureText = function() { if (this.getMultiline()) { lh *= goog.string.trim(this.text_).split('\n').length } - mContext.font = this.getStyle() + ' ' + this.getFontWeight() + ' ' + this.getFontSize() + 'px ' + this.getFontFamily(); + + mContext.font = this.getFontSize() + 'px Helvetica' //+ ' ' + this.getFontWeight() + ' ' + this.getFontSize() + 'px ' + this.getFontFamily(); var metrics = mContext.measureText(this.text_); var w = goog.userAgent.WEBKIT ? metrics.width : metrics.width + 1; @@ -545,8 +546,10 @@ lime.Renderer.CANVAS.LABEL.draw = function(context) { var lh = this.getLineHeight(); context.fillStyle = this.getFontColor(); - context.font = this.getStyle() + ' '+ this.getFontWeight() + ' ' + this.getFontSize() + - 'px/' + lh + ' ' + this.getFontFamily(); + + context.font = this.getFontSize() + 'px Helvetica'/*this.getFontWeight() + ' ' + this.getFontSize() + + 'px/' + lh + ' ' + this.getFontFamily();*/ + context.textAlign = align; context.textBaseline = 'top'; From 29ce66dc8345af674c3118c8ce84e5317eda9697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Fri, 10 May 2013 16:20:53 +0300 Subject: [PATCH 08/31] Only update scenes that are active --- lime/src/node.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lime/src/node.js b/lime/src/node.js index 715a2a41..38a855a4 100644 --- a/lime/src/node.js +++ b/lime/src/node.js @@ -714,11 +714,15 @@ lime.Node.prototype.updateLayout = function() { * @param {number=} opt_pass Pass number. */ lime.Node.prototype.update = function(opt_pass) { - // if (!this.renderer) return; - var property, + // if (!this.renderer) return; + var property, value; var pass = opt_pass || 0; + if (!this.inTree_) { + return this.setDirty(0, pass); + } + var uid = goog.getUid(this); if (this.dirty_ & lime.Dirty.LAYOUT) { this.updateLayout(); From ad2362f753ef56ec7a387cdc7017f1035f11fdb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Fri, 10 May 2013 16:21:33 +0300 Subject: [PATCH 09/31] Image loading ix for Ejecta --- lime/src/fill/image.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lime/src/fill/image.js b/lime/src/fill/image.js index 2569cd6e..cd86668b 100644 --- a/lime/src/fill/image.js +++ b/lime/src/fill/image.js @@ -78,7 +78,6 @@ lime.fill.Image.prototype.initForSprite = function(sprite){ var size = sprite.getSize(),that = this; if(!size.width && !size.height){ if(!this.isLoaded()){ - goog.events.listen(this,goog.events.EventType.LOAD,function(){ var size = this.getSize(); if(!size.width && !size.height){ @@ -112,7 +111,7 @@ lime.fill.Image.prototype.addLoadHandler_ = function(){ * @private */ lime.fill.Image.prototype.imageLoadedHandler_ = function(e) { - this.dispatchEvent(e); + this.dispatchEvent({type:'load'}); }; /** From e825bd730b8c71df0529f3914e39c00651050749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Fri, 10 May 2013 16:32:56 +0300 Subject: [PATCH 10/31] Add way for adding background to the main canvas --- lime/src/renderer/canvas.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lime/src/renderer/canvas.js b/lime/src/renderer/canvas.js index 815bdabd..733e6b59 100644 --- a/lime/src/renderer/canvas.js +++ b/lime/src/renderer/canvas.js @@ -18,6 +18,8 @@ lime.Renderer.CANVAS = new lime.Renderer(); */ lime.Renderer.CANVAS.updateLayout = function() {}; +lime.Renderer.CANVAS.CLEAR_COLOR = null; + /** * Initalize canvas element and start the drawing process * @this {lime.Node} @@ -133,8 +135,14 @@ lime.Renderer.CANVAS.drawCanvas = function() { if (this.redraw_) { var context = this.domElement.getContext('2d'); + if (lime.Renderer.CANVAS.CLEAR_COLOR) { + context.fillStyle = lime.Renderer.CANVAS.CLEAR_COLOR; + context.fillRect(0, 0, this.domElement.width, this.domElement.height); + } + else { + context.clearRect(0, 0, this.domElement.width, this.domElement.height); + } - context.clearRect(0, 0, this.domElement.width, this.domElement.height); context.save(); if (this.domElement === this.container) { context.translate(pos.x, pos.y); From 36980c80de6bc3574e217a443c5043a70f9ce69c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Fri, 10 May 2013 17:27:57 +0300 Subject: [PATCH 11/31] Disable font installing on Canvas only mode --- lime/src/shape/label.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lime/src/shape/label.js b/lime/src/shape/label.js index 944a0037..50281029 100644 --- a/lime/src/shape/label.js +++ b/lime/src/shape/label.js @@ -2,7 +2,7 @@ goog.provide('lime.Label'); goog.provide('lime.Renderer.CANVAS.LABEL'); goog.provide('lime.Renderer.DOM.LABEL'); - +goog.require('lime.dom'); goog.require('lime.Renderer.CANVAS.SPRITE'); goog.require('lime.Renderer.DOM.SPRITE'); goog.require('lime.Sprite'); @@ -587,6 +587,7 @@ lime.Renderer.CANVAS.LABEL.draw = function(context) { * @param {string=} opt_format Font format. */ lime.Label.installFont = function(name, fileurl, opt_format) { + if (!lime.dom.isDOMSupported()) return; var format = opt_format || 'truetype'; goog.style.installStyles('@font-face{font-family: "' + name + '";src: url(' + fileurl + ') format("' + format + '");})'); From 773b9875d79b658232aa9b967faf493df63f15f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Fri, 10 May 2013 17:28:13 +0300 Subject: [PATCH 12/31] Ejecta compatibility to demo games --- Makefile | 15 +++++++++++++++ lime/demos/roundball/game.js | 3 +-- lime/demos/roundball/rb.js | 19 +++++++++++++------ lime/demos/zlizer/game.js | 25 ++++++++++++++----------- lime/demos/zlizer/zlizer.js | 11 ++++++----- 5 files changed, 49 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index 01b26fd7..185347f9 100644 --- a/Makefile +++ b/Makefile @@ -41,4 +41,19 @@ lime/demos/pong/compiled/pong.js: $(DEMO_GAMES_DEPS) lime/demos/pong/*.js .FORCE: +ejecta-roundball: $(EJECTA_ROUNDBALL)/App/index.js + +$(EJECTA_ROUNDBALL)/App/index.js: $(DEMO_GAMES_DEPS) lime/demos/roundball/*.js + $(LIMEPY) build rb -m -o $@ + echo "\nrb.start(document.getElementById('canvas'));" >> $@ + cd $(EJECTA_ROUNDBALL); \ + xcodebuild VALID_ARCHS=i386 -configuration Debug clean build -sdk iphonesimulator -scheme Ejecta + +ejecta-zlizer: $(EJECTA_ZLIZER)/App/index.js + +$(EJECTA_ZLIZER)/App/index.js: $(DEMO_GAMES_DEPS) lime/demos/zlizer/*.js + $(LIMEPY) build zlizer -m -o $@ + echo "\nzlizer.start(document.getElementById('canvas'));" >> $@ + cd $(EJECTA_ZLIZER); \ + xcodebuild VALID_ARCHS=i386 -configuration Debug clean build -sdk iphonesimulator -scheme Ejecta diff --git a/lime/demos/roundball/game.js b/lime/demos/roundball/game.js index 20a2e3f8..5c327cc9 100644 --- a/lime/demos/roundball/game.js +++ b/lime/demos/roundball/game.js @@ -9,7 +9,6 @@ goog.require('rb.Progress'); */ rb.Game = function(size) { lime.Scene.call(this); - this.points = 0; //empty layer for contents @@ -18,7 +17,7 @@ rb.Game = function(size) { //make board this.board = new rb.Board(size, size, this).setPosition(25, 174); - + if(rb.isBrokenChrome()) this.board.setRenderer(lime.Renderer.CANVAS); // static background bubbles for baord. try dfkit.Renderer.CANVAS for this one as it is quite static diff --git a/lime/demos/roundball/rb.js b/lime/demos/roundball/rb.js index d4558e0f..f823b8c2 100644 --- a/lime/demos/roundball/rb.js +++ b/lime/demos/roundball/rb.js @@ -12,24 +12,33 @@ goog.require('rb.Board'); goog.require('rb.Button'); goog.require('rb.Game'); goog.require('rb.Help'); +goog.require('lime.dom') //constant iPad size rb.WIDTH = 720; rb.HEIGHT = 1004; +// Ejecta has some issues on adding new textures on the fly. +var img = new Image(); +img.src = 'assets/selection.png'; +img = new Image(); +img.src = 'assets/shadow.png'; + + // entrypoint -rb.start = function() { +rb.start = function(parent) { + + lime.Renderer.CANVAS.CLEAR_COLOR = '#1c6aa1'; /* //enable for non-seeded random. useful for debugging var pseudoRandom = new goog.testing.PseudoRandom(109); pseudoRandom.install(); */ - - rb.director = new lime.Director(document.body, rb.WIDTH, rb.HEIGHT); + rb.director = new lime.Director(parent || document.body, rb.WIDTH, rb.HEIGHT); rb.director.makeMobileWebAppCapable(); - rb.loadMenu(); + rb.loadMenu(); }; @@ -46,10 +55,8 @@ rb.Mode = { rb.loadMenu = function() { var scene = new lime.Scene(), layer = new lime.Layer().setPosition(rb.WIDTH / 2, 0); - if(rb.isBrokenChrome()) layer.setRenderer(lime.Renderer.CANVAS); - var title = new lime.Sprite().setFill('assets/main_title.png').setPosition(0, 290); title.qualityRenderer = true; layer.appendChild(title); diff --git a/lime/demos/zlizer/game.js b/lime/demos/zlizer/game.js index 81deb82f..fbbd0849 100644 --- a/lime/demos/zlizer/game.js +++ b/lime/demos/zlizer/game.js @@ -70,11 +70,11 @@ zlizer.Game = function(level) { goog.events.listen(btn, 'click', function() {zlizer.loadMenuScene(lime.transitions.MoveInUp);}); this.startup(); - + //only needed to use pointInPath() function. no actual drawing. var canvas = goog.dom.createDom('canvas'); this.ctx = canvas.getContext('2d'); - + //lime logo zlizer.builtWithLime(this); }; @@ -112,12 +112,12 @@ zlizer.Game.prototype.start = function() { this.touches = []; this.layer.runAction(new lime.animation.FadeTo(1)); - + this.graphics = new lime.CanvasContext().setSize(zlizer.director.getSize().clone()).setAnchorPoint(0,0).setQuality(.5); this.appendChild(this.graphics); this.graphics.draw = goog.bind(this.drawTouches_,this); - + this.isdown = false; goog.events.listen(this, ['mousedown', 'touchstart', 'keydown'], @@ -129,7 +129,6 @@ zlizer.Game.prototype.start = function() { }; zlizer.Game.prototype.drawTouches_ = function(ctx) { - var now = goog.now(); if(!this.lastRun_) this.lastRun_ = now; var dt = now-this.lastRun_, @@ -140,19 +139,21 @@ zlizer.Game.prototype.drawTouches_ = function(ctx) { t, i, p, particles; this.lastRun_ = now; - + + + /* if(goog.userAgent.MOBILE) this.ctx.globalCompositeOperation = 'copy'; - else + else ctx.clearRect(0,0,zlizer.director.getSize().width,zlizer.director.getSize().height); - + */ // style for clear. clearRect is very slow on ios ctx.strokeStyle = 'rgba(0,0,0,0)'; ctx.lineCap = 'round'; ctx.lineWidth = 17; ctx.shadowBlur = 0; ctx.shadowColor = '#fff'; - + var t = this.touches.length; while (--t >= 0) { @@ -203,6 +204,8 @@ zlizer.Game.prototype.drawTouches_ = function(ctx) { } } + + }; zlizer.Game.prototype.downHandler_ = function(e) { @@ -218,7 +221,7 @@ zlizer.Game.prototype.downHandler_ = function(e) { e.swallow(['mousemove', 'touchmove'], goog.partial(this.moveHandler_, touch)); e.swallow(['mouseup', 'touchend', 'touchcancel', 'keyup'], goog.partial(this.upHandler_, touch)); - + }; zlizer.Game.prototype.moveHandler_ = function(touch,e) { if (!goog.isDef(touch.pos)) { @@ -235,7 +238,7 @@ zlizer.Game.prototype.moveHandler_ = function(touch,e) { if (dx > 0) if (dy > 0) touch.quaters[0] = 1; else touch.quaters[1] = 1; - else; + else if (dy > 0) touch.quaters[2] = 1; else touch.quaters[3] = 1; diff --git a/lime/demos/zlizer/zlizer.js b/lime/demos/zlizer/zlizer.js index 8bbbe11e..f481a833 100644 --- a/lime/demos/zlizer/zlizer.js +++ b/lime/demos/zlizer/zlizer.js @@ -22,9 +22,10 @@ zlizer.WIDTH = 768; zlizer.HEIGHT = 1004; // entrypoint -zlizer.start = function() { +zlizer.start = function(parent) { + lime.Renderer.CANVAS.CLEAR_COLOR = '#5ea71d'; - zlizer.director = new lime.Director(document.body, zlizer.WIDTH, zlizer.HEIGHT); + zlizer.director = new lime.Director(parent || document.body, zlizer.WIDTH, zlizer.HEIGHT); zlizer.director.makeMobileWebAppCapable(); lime.Label.defaultFont = 'Impact'; @@ -81,7 +82,7 @@ zlizer.loadMenuScene = function(opt_transition) { var btns_layer = new lime.Layer().setPosition(-250, 110); levels.appendChild(btns_layer); - + var r = 0; for (r = 0; r < 4; r++) { for (var c = 0; c < 5; c++) { @@ -95,12 +96,12 @@ zlizer.loadMenuScene = function(opt_transition) { } //Creates a button to go back to the main menu - var btn_main = new zlizer.Button('Back to Menu').setSize(400, 80).setPosition(250, r * 90); + var btn_main = new zlizer.Button('Back to Menu').setSize(400, 80).setPosition(250, r * 90); btns_layer.appendChild(btn_main); goog.events.listen(btn_main, lime.Button.Event.CLICK, function() { contents.runAction(new lime.animation.MoveTo(0, 280).enableOptimizations()); },false, num); - + }; From 70e58ef229d061bb11815620e514a4b28b2dedcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Sun, 12 May 2013 10:55:46 +0300 Subject: [PATCH 13/31] Copy assets to Ejecta targets --- Makefile | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 185347f9..a3a878f8 100644 --- a/Makefile +++ b/Makefile @@ -40,8 +40,10 @@ lime/demos/pong/compiled/pong.js: $(DEMO_GAMES_DEPS) lime/demos/pong/*.js sed -i "" -e "s/\(# Updated on: \).*/\1$$(date '+%Y-%m-%d %H:%M:%S')/" $@ .FORCE: + +ifdef EJECTA_ROUNDBALL -ejecta-roundball: $(EJECTA_ROUNDBALL)/App/index.js +ejecta-roundball: $(EJECTA_ROUNDBALL)/App/index.js | ejecta-roundball-assets $(EJECTA_ROUNDBALL)/App/index.js: $(DEMO_GAMES_DEPS) lime/demos/roundball/*.js $(LIMEPY) build rb -m -o $@ @@ -49,7 +51,17 @@ $(EJECTA_ROUNDBALL)/App/index.js: $(DEMO_GAMES_DEPS) lime/demos/roundball/*.js cd $(EJECTA_ROUNDBALL); \ xcodebuild VALID_ARCHS=i386 -configuration Debug clean build -sdk iphonesimulator -scheme Ejecta -ejecta-zlizer: $(EJECTA_ZLIZER)/App/index.js +ejecta-roundball-assets: $(patsubst lime/demos/roundball/%, $(EJECTA_ROUNDBALL)/App/%, $(shell find lime/demos/roundball/assets -type f)) + +$(EJECTA_ROUNDBALL)/App/assets/%: lime/demos/roundball/assets/% + mkdir -p $(EJECTA_ROUNDBALL)/App/assets + cp $< $@ + +endif + +ifdef EJECTA_ZLIZER + +ejecta-zlizer: $(EJECTA_ZLIZER)/App/index.js | ejecta-zlizer-assets $(EJECTA_ZLIZER)/App/index.js: $(DEMO_GAMES_DEPS) lime/demos/zlizer/*.js $(LIMEPY) build zlizer -m -o $@ @@ -57,3 +69,10 @@ $(EJECTA_ZLIZER)/App/index.js: $(DEMO_GAMES_DEPS) lime/demos/zlizer/*.js cd $(EJECTA_ZLIZER); \ xcodebuild VALID_ARCHS=i386 -configuration Debug clean build -sdk iphonesimulator -scheme Ejecta +ejecta-zlizer-assets: $(patsubst lime/demos/zlizer/%, $(EJECTA_ZLIZER)/App/%, $(shell find lime/demos/zlizer/assets -type f)) + +$(EJECTA_ZLIZER)/App/assets/%: lime/demos/zlizer/assets/% + mkdir -p $(EJECTA_ZLIZER)/App/assets + cp $< $@ + +endif From 3cc1c9ec70ec505f64dc374e4edb43ed72dd9d4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Sun, 12 May 2013 14:08:47 +0300 Subject: [PATCH 14/31] Basic CocoonJS support --- lime/src/helper/dom.js | 1 + lime/templates/cocoonjs/index.html | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 lime/templates/cocoonjs/index.html diff --git a/lime/src/helper/dom.js b/lime/src/helper/dom.js index 6e90cbc6..93b1a176 100644 --- a/lime/src/helper/dom.js +++ b/lime/src/helper/dom.js @@ -2,6 +2,7 @@ goog.provide('lime.dom'); goog.require('goog.dom'); lime.dom.isDOMSupported = function() { + if (goog.global['CocoonJS_ENV'] === true) return false; // This works for Ejecta. Probably not for others. Pull request! return !!document.head.parentNode; } diff --git a/lime/templates/cocoonjs/index.html b/lime/templates/cocoonjs/index.html new file mode 100644 index 00000000..5739b150 --- /dev/null +++ b/lime/templates/cocoonjs/index.html @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file From ad72a5e4d1cdbeb8ba3388394868f5ea02b5afe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Sun, 12 May 2013 14:09:10 +0300 Subject: [PATCH 15/31] Add CocoonJS targets for demo games --- Makefile | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a3a878f8..69fdcabe 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,9 @@ lime/demos/pong/compiled/pong.js: $(DEMO_GAMES_DEPS) lime/demos/pong/*.js .FORCE: +ROUNDBALL_ASSETS = $(shell find lime/demos/roundball/assets -type f) +ZLIZER_ASSETS = $(shell find lime/demos/zlizer/assets -type f) + ifdef EJECTA_ROUNDBALL ejecta-roundball: $(EJECTA_ROUNDBALL)/App/index.js | ejecta-roundball-assets @@ -51,7 +54,7 @@ $(EJECTA_ROUNDBALL)/App/index.js: $(DEMO_GAMES_DEPS) lime/demos/roundball/*.js cd $(EJECTA_ROUNDBALL); \ xcodebuild VALID_ARCHS=i386 -configuration Debug clean build -sdk iphonesimulator -scheme Ejecta -ejecta-roundball-assets: $(patsubst lime/demos/roundball/%, $(EJECTA_ROUNDBALL)/App/%, $(shell find lime/demos/roundball/assets -type f)) +ejecta-roundball-assets: $(patsubst lime/demos/roundball/%, $(EJECTA_ROUNDBALL)/App/%, $(ROUNDBALL_ASSETS)) $(EJECTA_ROUNDBALL)/App/assets/%: lime/demos/roundball/assets/% mkdir -p $(EJECTA_ROUNDBALL)/App/assets @@ -69,10 +72,46 @@ $(EJECTA_ZLIZER)/App/index.js: $(DEMO_GAMES_DEPS) lime/demos/zlizer/*.js cd $(EJECTA_ZLIZER); \ xcodebuild VALID_ARCHS=i386 -configuration Debug clean build -sdk iphonesimulator -scheme Ejecta -ejecta-zlizer-assets: $(patsubst lime/demos/zlizer/%, $(EJECTA_ZLIZER)/App/%, $(shell find lime/demos/zlizer/assets -type f)) +ejecta-zlizer-assets: $(patsubst lime/demos/zlizer/%, $(EJECTA_ZLIZER)/App/%, $(ZLIZER_ASSETRS)) $(EJECTA_ZLIZER)/App/assets/%: lime/demos/zlizer/assets/% mkdir -p $(EJECTA_ZLIZER)/App/assets cp $< $@ endif + +ifdef COCOON_ROUNDBALL + +TEMPDIR:=$(shell mktemp -u -d -t roundball-cocoonjs) + +cocoon-roundball: $(COCOON_ROUNDBALL) + +$(COCOON_ROUNDBALL): $(DEMO_GAMES_DEPS) lime/demos/roundball/*.js $(ROUNDBALL_ASSSETS) lime/templates/cocoonjs/index.html + mkdir $(TEMPDIR) + $(LIMEPY) build rb -m -o $(TEMPDIR)/index.js + cp lime/templates/cocoonjs/index.html $(TEMPDIR) + sed -i "" -e "s/{init}/rb.start(canvas);/" $(TEMPDIR)/index.html + cp -rf lime/demos/roundball/assets $(TEMPDIR) + cd $(TEMPDIR); zip -r roundball.zip . -x ".*" + cp -rf $(TEMPDIR)/roundball.zip $(COCOON_ROUNDBALL) + rm -r $(TEMPDIR) + +endif + +ifdef COCOON_ZLIZER + +TEMPDIR:=$(shell mktemp -u -d -t zlizer-cocoonjs) + +cocoon-zlizer: $(COCOON_ZLIZER) + +$(COCOON_ZLIZER): $(DEMO_GAMES_DEPS) lime/demos/zlizer/*.js $(ZLIZER_ASSSETS) lime/templates/cocoonjs/index.html + mkdir $(TEMPDIR) + $(LIMEPY) build zlizer -m -o $(TEMPDIR)/index.js + cp lime/templates/cocoonjs/index.html $(TEMPDIR) + sed -i "" -e "s/{init}/zlizer.start(canvas);/" $(TEMPDIR)/index.html + cp -rf lime/demos/zlizer/assets $(TEMPDIR) + cd $(TEMPDIR); zip -r zlizer.zip . -x ".*" + cp -rf $(TEMPDIR)/zlizer.zip $(COCOON_ZLIZER) + rm -r $(TEMPDIR) + +endif \ No newline at end of file From d1a8053b9c29291a842698342e8e6f87a814a276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Mon, 13 May 2013 11:03:47 +0300 Subject: [PATCH 16/31] Fix CocoonJS+Android issue on setting tagname --- lime/src/director.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lime/src/director.js b/lime/src/director.js index 37e204e8..0c7ea5d6 100644 --- a/lime/src/director.js +++ b/lime/src/director.js @@ -60,7 +60,9 @@ lime.Director = function(parentElement, opt_width, opt_height) { this.domClassName = goog.getCssName('lime-director'); if (parentElement.getContext) { - this.container.tagName = 'CANVAS'; // Ejecta hack. + if (!this.container.tagName) { + this.container.tagName = 'CANVAS'; // Ejecta hack. + } this.setRenderer(lime.Renderer.CANVAS); this.domElement = this.container; } From 1607045cf18c83e28a830e09e55ea58863047fa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Mon, 13 May 2013 11:33:44 +0300 Subject: [PATCH 17/31] Make CocoonJS canvas full screen by default --- lime/templates/cocoonjs/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lime/templates/cocoonjs/index.html b/lime/templates/cocoonjs/index.html index 5739b150..b110fc25 100644 --- a/lime/templates/cocoonjs/index.html +++ b/lime/templates/cocoonjs/index.html @@ -6,8 +6,8 @@ { // Create a canvas and draw something in it. var canvas = document.createElement("canvas"); - canvas.width = 640; - canvas.height = 1136; + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; document.body.appendChild(canvas); {init} }; From c9d9957253e85ef35b0b9bc36d069e9a6f6598eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Tue, 14 May 2013 10:44:24 +0300 Subject: [PATCH 18/31] Cache image pattern and gradient for reuse. This is over-simplified and needs fining before merge to master. See "todo" comments. --- lime/src/fill/image.js | 7 +++++-- lime/src/fill/lineargradient.js | 24 ++++++++++++++---------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/lime/src/fill/image.js b/lime/src/fill/image.js index cd86668b..7e38ef34 100644 --- a/lime/src/fill/image.js +++ b/lime/src/fill/image.js @@ -233,12 +233,15 @@ lime.fill.Image.prototype.setCanvasStyle = function(context,shape) { var so = this.getPixelSizeAndOffset(shape),s=so[0],offset=so[1]; /* todo: No idea if drawimage() with loops is faster or if the pattern object needs to be cached. Needs to be tested! */ - var ptrn = context.createPattern(img,'repeat'); + if (!this._pattern && img.complete) { + // todo: different context? memory leak? + this._pattern = context.createPattern(img,'repeat'); + } var aspx = s.width/img.width, aspy =s.height/img.height; context.save(); context.translate(frame.left+offset.x,frame.top+offset.y); context.scale(aspx,aspy); - context.fillStyle = ptrn; + context.fillStyle = this._pattern; context.fillRect(-offset.x/aspx,-offset.y/aspy,size.width/aspx, size.height/aspy); context.restore(); }catch(e){} diff --git a/lime/src/fill/lineargradient.js b/lime/src/fill/lineargradient.js index 279075da..6c771b18 100644 --- a/lime/src/fill/lineargradient.js +++ b/lime/src/fill/lineargradient.js @@ -139,15 +139,19 @@ lime.fill.LinearGradient.prototype.setCanvasStyle = function(context, shape) { width = frame.right - frame.left, height = frame.bottom - frame.top; - var grad = context.createLinearGradient( - frame.left + width * p[0], - frame.top + height * p[1], - frame.left + width * p[2], - frame.top + height * p[3] - ); - - for (var i = 0; i < this.colors_.length; i++) { - grad.addColorStop(this.colors_[i][0], this.colors_[i][1].str); + if (!this._grad) { + // todo: this does not work when gradient changes. need to also store the frame. + var grad = context.createLinearGradient( + frame.left + width * p[0], + frame.top + height * p[1], + frame.left + width * p[2], + frame.top + height * p[3] + ); + + for (var i = 0; i < this.colors_.length; i++) { + grad.addColorStop(this.colors_[i][0], this.colors_[i][1].str); + } + this._grad = grad; } - context.fillStyle = grad; + context.fillStyle = this._grad; }; From ee435978503376286b0957cc1252a6a28d1e4c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Tue, 14 May 2013 10:45:24 +0300 Subject: [PATCH 19/31] Fix frame fill for canvas only + formatting --- lime/src/fill/frame.js | 67 +++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/lime/src/fill/frame.js b/lime/src/fill/frame.js index 855e8208..78fafd1a 100644 --- a/lime/src/fill/frame.js +++ b/lime/src/fill/frame.js @@ -9,6 +9,7 @@ goog.require('goog.dom.classes'); goog.require('goog.dom'); goog.require('goog.math.Vec2'); goog.require('goog.math.Size'); +goog.require('lime.dom'); /** * Image fill. @@ -22,19 +23,19 @@ goog.require('goog.math.Size'); */ lime.fill.Frame = function(img, rect, opt_offset, opt_size, opt_rotated) { lime.fill.Image.call(this,img); - + if(goog.isNumber(rect)){ rect = new goog.math.Rect(arguments[1],arguments[2],arguments[3],arguments[4]); opt_offset = new goog.math.Vec2(0,0); opt_size = new goog.math.Size(rect.width,rect.height); opt_rotated = false; } - + this.rect_ = rect; this.coffset_ = opt_offset; this.csize_ = opt_size; this.rotated_ = opt_rotated; - + var r = this.rect_,key = [this.url_,r.width,r.height,r.left,r.top,this.coffset_.x,this.coffset_.y].join('_'); if(goog.isDef(this.dataCache_[key])){ this.data_ = this.dataCache_[key]; @@ -50,7 +51,7 @@ lime.fill.Frame = function(img, rect, opt_offset, opt_size, opt_rotated) { this.data_.initializer = this; this.data_.classname = this.getNextCssClass_(); this.dataCache_[key] = this.data_; - + if(this.USE_CSS_CANVAS){ this.ctx = document.getCSSCanvasContext('2d', this.data_.classname, this.csize_.width, this.csize_.height); } @@ -58,7 +59,7 @@ lime.fill.Frame = function(img, rect, opt_offset, opt_size, opt_rotated) { //todo: FF4 has support for element backgrounds. probably faster than this png url. this.ctx = this.makeCanvas(); } - + if(this.isLoaded()){ this.makeFrameData_(); } @@ -89,20 +90,20 @@ lime.fill.Frame.prototype.USE_CSS_CANVAS = goog.isFunction(document.getCSSCanvas * @inheritDoc */ lime.fill.Frame.prototype.initForSprite = function(sprite){ - + var size = sprite.getSize(); if(size.width==0 && size.height==0){ sprite.setSize(this.csize_.width,this.csize_.height); } - + lime.fill.Image.prototype.initForSprite.call(this,sprite); - + if(!this.isProcessed()){ goog.events.listen(this,'processed',function(){ sprite.setDirty(lime.Dirty.CONTENT); },false,this); } - + //switch to canvas if no support }; @@ -127,30 +128,31 @@ lime.fill.Frame.prototype.getNextCssClass_ = function(){ */ lime.fill.Frame.prototype.makeFrameData_ = function(){ this.writeToCanvas(this.ctx); - - if(!this.USE_CSS_CANVAS){ - - var contents = this.cvs.toDataURL("image/png"), - rule = '.'+this.data_.classname+'{background-image:url('+contents+') !important}'; - if(!styleSheet){ - goog.style.installStyles(rule); - styleSheet = document.styleSheets[document.styleSheets.length-1]; - } - else { - // why doesn't addCssRule work in IE9??? - if(goog.userAgent.IE) styleSheet.cssText+=rule; - else goog.cssom.addCssRule(styleSheet,rule); - } - - // laoding into image to avoid flickery onf firefox firat load - this.data_.img = goog.dom.createDom('img'); - this.data_.img.src = contents; + + if(!this.USE_CSS_CANVAS && lime.dom.isDOMSupported()){ + + var contents = this.cvs.toDataURL("image/png"), + rule = '.'+this.data_.classname+'{background-image:url('+contents+') !important}'; + if (!styleSheet) { + goog.style.installStyles(rule); + styleSheet = document.styleSheets[document.styleSheets.length-1]; + } + else { + // why doesn't addCssRule work in IE9??? + if(goog.userAgent.IE) styleSheet.cssText+=rule; + else goog.cssom.addCssRule(styleSheet,rule); + } + + // loading into image to avoid flickery on firefox first load + this.data_.img = goog.dom.createDom('img'); + this.data_.img.src = contents; } - + this.data_.processed = true; this.dispatchEvent(new goog.events.Event('processed')); - + this.getImageElement().complete = true; + }; })(); @@ -204,15 +206,14 @@ lime.fill.Frame.prototype.writeToCanvas = function(ctx){ ox = this.coffset_.x; oy = this.coffset_.y; } - ctx.drawImage(this.image_,l,t,w,h,ox,oy,w,h); }; /** @inheritDoc */ lime.fill.Frame.prototype.setDOMStyle = function(domEl,shape) { if(this.USE_CSS_CANVAS){ - domEl.style['background'] = '-webkit-canvas('+this.data_.classname+')'; - } + domEl.style['background'] = '-webkit-canvas('+this.data_.classname+')'; + } else if(this.data_.classname!=shape.cvs_background_class_){ goog.dom.classes.add(domEl,this.data_.classname); domEl.style['background'] = ''; @@ -220,7 +221,7 @@ lime.fill.Frame.prototype.setDOMStyle = function(domEl,shape) { goog.dom.classes.remove(domEl,shape.cvs_background_class_); shape.cvs_background_class_ = this.data_.classname; } - + this.setDOMBackgroundProp_(domEl,shape); }; From 5d74efbf5711c25fce8f8b0c33826a090805287c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Tue, 14 May 2013 11:34:41 +0300 Subject: [PATCH 20/31] Cache pattern for frame fill --- lime/src/fill/image.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lime/src/fill/image.js b/lime/src/fill/image.js index 7e38ef34..5f7ba151 100644 --- a/lime/src/fill/image.js +++ b/lime/src/fill/image.js @@ -233,15 +233,15 @@ lime.fill.Image.prototype.setCanvasStyle = function(context,shape) { var so = this.getPixelSizeAndOffset(shape),s=so[0],offset=so[1]; /* todo: No idea if drawimage() with loops is faster or if the pattern object needs to be cached. Needs to be tested! */ - if (!this._pattern && img.complete) { + if (!img._pattern && img.complete) { // todo: different context? memory leak? - this._pattern = context.createPattern(img,'repeat'); + img._pattern = context.createPattern(img,'repeat'); } var aspx = s.width/img.width, aspy =s.height/img.height; context.save(); context.translate(frame.left+offset.x,frame.top+offset.y); context.scale(aspx,aspy); - context.fillStyle = this._pattern; + context.fillStyle = img._pattern; context.fillRect(-offset.x/aspx,-offset.y/aspy,size.width/aspx, size.height/aspy); context.restore(); }catch(e){} From c8e8c247365e3180a2d98803115f5c3f5f37477e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Tue, 14 May 2013 15:29:49 +0300 Subject: [PATCH 21/31] Create frame canvas only when needed. --- lime/src/fill/frame.js | 11 ++++++----- lime/src/fill/image.js | 33 +++++++++++++++++++-------------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/lime/src/fill/frame.js b/lime/src/fill/frame.js index 78fafd1a..ff2bf5ad 100644 --- a/lime/src/fill/frame.js +++ b/lime/src/fill/frame.js @@ -57,9 +57,8 @@ lime.fill.Frame = function(img, rect, opt_offset, opt_size, opt_rotated) { } else { //todo: FF4 has support for element backgrounds. probably faster than this png url. - this.ctx = this.makeCanvas(); + //this.ctx = this.makeCanvas(); } - if(this.isLoaded()){ this.makeFrameData_(); } @@ -127,8 +126,9 @@ lime.fill.Frame.prototype.getNextCssClass_ = function(){ * @private */ lime.fill.Frame.prototype.makeFrameData_ = function(){ - this.writeToCanvas(this.ctx); - + if (this.ctx) { + this.writeToCanvas(this.ctx); + } if(!this.USE_CSS_CANVAS && lime.dom.isDOMSupported()){ var contents = this.cvs.toDataURL("image/png"), @@ -148,7 +148,6 @@ lime.fill.Frame.prototype.makeFrameData_ = function(){ this.data_.img.src = contents; } - this.data_.processed = true; this.dispatchEvent(new goog.events.Event('processed')); this.getImageElement().complete = true; @@ -169,6 +168,8 @@ lime.fill.Frame.prototype.getImageElement = function(){ if(!this.cvs){ var ctx = this.makeCanvas(); this.writeToCanvas(ctx); + this.ctx = ctx; + this.cvs._pattern = false; } this.frameImgCache_ = this.cvs; } diff --git a/lime/src/fill/image.js b/lime/src/fill/image.js index 5f7ba151..fbb3bd72 100644 --- a/lime/src/fill/image.js +++ b/lime/src/fill/image.js @@ -229,20 +229,25 @@ lime.fill.Image.prototype.setCanvasStyle = function(context,shape) { return; } try { - var img = this.getImageElement(); var so = this.getPixelSizeAndOffset(shape),s=so[0],offset=so[1]; - /* todo: No idea if drawimage() with loops is faster or if the - pattern object needs to be cached. Needs to be tested! */ - if (!img._pattern && img.complete) { - // todo: different context? memory leak? - img._pattern = context.createPattern(img,'repeat'); - } - var aspx = s.width/img.width, aspy =s.height/img.height; - context.save(); - context.translate(frame.left+offset.x,frame.top+offset.y); - context.scale(aspx,aspy); - context.fillStyle = img._pattern; - context.fillRect(-offset.x/aspx,-offset.y/aspy,size.width/aspx, size.height/aspy); - context.restore(); + // var pat = offset.x < 0 || offset.y < 0 || size.width > s.width - offset.x || size.height > s.height - offset.y; + // if (pat) { + var img = this.getImageElement(); + + /* todo: No idea if drawimage() with loops is faster or if the + pattern object needs to be cached. Needs to be tested! */ + if (!img._pattern && img.complete) { + // todo: different context? memory leak? + img._pattern = context.createPattern(img,'repeat'); + } + var aspx = s.width/img.width, aspy =s.height/img.height; + context.save(); + context.translate(frame.left+offset.x,frame.top+offset.y); + context.scale(aspx,aspy); + context.fillStyle = img._pattern || 'none'; + context.fillRect(-offset.x/aspx,-offset.y/aspy,size.width/aspx, size.height/aspy); + context.restore(); + // } + }catch(e){} }; From 8ea7c0b6c3cdbffb70784f43a338792436124805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Tue, 14 May 2013 22:44:52 +0300 Subject: [PATCH 22/31] Skip canvas creation when not needed --- lime/src/fill/image.js | 74 ++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/lime/src/fill/image.js b/lime/src/fill/image.js index fbb3bd72..c7035bb3 100644 --- a/lime/src/fill/image.js +++ b/lime/src/fill/image.js @@ -225,29 +225,53 @@ lime.fill.Image.prototype.setDOMStyle = function(domEl,shape) { lime.fill.Image.prototype.setCanvasStyle = function(context,shape) { var size = shape.getSize(),frame = shape.getFrame(); - if (!size.width || !size.height) { - return; - } - try { - var so = this.getPixelSizeAndOffset(shape),s=so[0],offset=so[1]; - // var pat = offset.x < 0 || offset.y < 0 || size.width > s.width - offset.x || size.height > s.height - offset.y; - // if (pat) { - var img = this.getImageElement(); - - /* todo: No idea if drawimage() with loops is faster or if the - pattern object needs to be cached. Needs to be tested! */ - if (!img._pattern && img.complete) { - // todo: different context? memory leak? - img._pattern = context.createPattern(img,'repeat'); - } - var aspx = s.width/img.width, aspy =s.height/img.height; - context.save(); - context.translate(frame.left+offset.x,frame.top+offset.y); - context.scale(aspx,aspy); - context.fillStyle = img._pattern || 'none'; - context.fillRect(-offset.x/aspx,-offset.y/aspy,size.width/aspx, size.height/aspy); - context.restore(); - // } - - }catch(e){} + + if (!size.width || !size.height) return; + + var so = this.getPixelSizeAndOffset(shape),s=so[0],offset=so[1]; + var pat = offset.x < 0 || offset.y < 0 || size.width > s.width - offset.x || size.height > s.height - offset.y; + if (pat || !this.writeToCanvas || this.rotated_) { + var img = this.getImageElement(); + + if (!img._pattern && img.complete) { + // todo: different context? memory leak? + img._pattern = context.createPattern(img,'repeat'); + } + var aspx = s.width/img.width, aspy =s.height/img.height; + context.save(); + context.translate(frame.left+offset.x,frame.top+offset.y); + context.scale(aspx,aspy); + context.fillStyle = img._pattern || 'none'; + context.fillRect(-offset.x/aspx,-offset.y/aspy,size.width/aspx, size.height/aspy); + context.restore(); + } + else { + img = this.image_; + if (!img._pattern && img.complete) { + // todo: different context? memory leak? + img._pattern = context.createPattern(img,'repeat'); + } + aspx = s.width/this.csize_.width, aspy =s.height/this.csize_.height; + context.save(); + context.translate(frame.left+offset.x,frame.top+offset.y); + context.scale(aspx,aspy); + + context.fillStyle = img._pattern || 'none'; + // todo: negative offsets? + var l = this.rect_.left; + var t = this.rect_.top; + + context.translate(this.coffset_.x - l, this.coffset_.y - t); + var rr = goog.math.Rect.intersection(this.rect_, + new goog.math.Rect( + l - offset.x/aspx - this.coffset_.x, + t - offset.y/aspy - this.coffset_.y, + size.width/aspx, + size.height/aspy + ) + ) + context.fillRect(rr.left, rr.top, rr.width, rr.height); + context.restore(); + } + }; From d341f285043f2447c49486cdf5b91c4c9f5e449c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Wed, 15 May 2013 12:24:12 +0300 Subject: [PATCH 23/31] Merge roundball assets to sprite sheet. (Ejecta performance test) --- lime/demos/roundball/assets/roundball.json | 76 ++++++++++++++++++ lime/demos/roundball/assets/roundball.json.js | 6 ++ lime/demos/roundball/assets/roundball.png | Bin 0 -> 48633 bytes lime/demos/roundball/game.js | 2 +- lime/demos/roundball/gem.js | 4 +- lime/demos/roundball/rb.js | 13 +-- 6 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 lime/demos/roundball/assets/roundball.json create mode 100644 lime/demos/roundball/assets/roundball.json.js create mode 100644 lime/demos/roundball/assets/roundball.png diff --git a/lime/demos/roundball/assets/roundball.json b/lime/demos/roundball/assets/roundball.json new file mode 100644 index 00000000..10b5fd31 --- /dev/null +++ b/lime/demos/roundball/assets/roundball.json @@ -0,0 +1,76 @@ +{"frames": { + +"ball_0.png": +{ + "frame": {"x":134,"y":134,"w":61,"h":61}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":61,"h":61}, + "sourceSize": {"w":61,"h":61} +}, +"ball_1.png": +{ + "frame": {"x":149,"y":68,"w":61,"h":61}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":61,"h":61}, + "sourceSize": {"w":61,"h":61} +}, +"ball_2.png": +{ + "frame": {"x":83,"y":68,"w":61,"h":61}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":61,"h":61}, + "sourceSize": {"w":61,"h":61} +}, +"ball_3.png": +{ + "frame": {"x":134,"y":2,"w":61,"h":61}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":61,"h":61}, + "sourceSize": {"w":61,"h":61} +}, +"ball_4.png": +{ + "frame": {"x":68,"y":166,"w":61,"h":61}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":61,"h":61}, + "sourceSize": {"w":61,"h":61} +}, +"ball_5.png": +{ + "frame": {"x":2,"y":166,"w":61,"h":61}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":61,"h":61}, + "sourceSize": {"w":61,"h":61} +}, +"selection.png": +{ + "frame": {"x":2,"y":85,"w":76,"h":76}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":76,"h":76}, + "sourceSize": {"w":76,"h":76} +}, +"shadow.png": +{ + "frame": {"x":2,"y":2,"w":76,"h":78}, + "rotated": false, + "trimmed": false, + "spriteSourceSize": {"x":0,"y":0,"w":76,"h":78}, + "sourceSize": {"w":76,"h":78} +}}, +"meta": { + "app": "http://www.texturepacker.com", + "version": "1.0", + "image": "roundball.png", + "format": "RGBA8888", + "size": {"w":256,"h":256}, + "scale": "1", + "smartupdate": "$TexturePacker:SmartUpdate:89901ac97cb2eae3221b3ed315bc5e53$" +} +} diff --git a/lime/demos/roundball/assets/roundball.json.js b/lime/demos/roundball/assets/roundball.json.js new file mode 100644 index 00000000..9f305367 --- /dev/null +++ b/lime/demos/roundball/assets/roundball.json.js @@ -0,0 +1,6 @@ +goog.provide('lime.ASSETS.roundball.json'); +goog.require('soy'); + +lime.ASSETS.roundball.json.data = function(opt_data) { +return JSON.parse("{\"frames\":{\"ball_3.png\":{\"trimmed\":false,\"frame\":{\"y\":2,\"x\":134,\"w\":61,\"h\":61},\"rotated\":false,\"sourceSize\":{\"h\":61,\"w\":61},\"spriteSourceSize\":{\"y\":0,\"x\":0,\"w\":61,\"h\":61}},\"ball_2.png\":{\"trimmed\":false,\"frame\":{\"y\":68,\"x\":83,\"w\":61,\"h\":61},\"rotated\":false,\"sourceSize\":{\"h\":61,\"w\":61},\"spriteSourceSize\":{\"y\":0,\"x\":0,\"w\":61,\"h\":61}},\"ball_1.png\":{\"trimmed\":false,\"frame\":{\"y\":68,\"x\":149,\"w\":61,\"h\":61},\"rotated\":false,\"sourceSize\":{\"h\":61,\"w\":61},\"spriteSourceSize\":{\"y\":0,\"x\":0,\"w\":61,\"h\":61}},\"ball_0.png\":{\"trimmed\":false,\"frame\":{\"y\":134,\"x\":134,\"w\":61,\"h\":61},\"rotated\":false,\"sourceSize\":{\"h\":61,\"w\":61},\"spriteSourceSize\":{\"y\":0,\"x\":0,\"w\":61,\"h\":61}},\"ball_5.png\":{\"trimmed\":false,\"frame\":{\"y\":166,\"x\":2,\"w\":61,\"h\":61},\"rotated\":false,\"sourceSize\":{\"h\":61,\"w\":61},\"spriteSourceSize\":{\"y\":0,\"x\":0,\"w\":61,\"h\":61}},\"ball_4.png\":{\"trimmed\":false,\"frame\":{\"y\":166,\"x\":68,\"w\":61,\"h\":61},\"rotated\":false,\"sourceSize\":{\"h\":61,\"w\":61},\"spriteSourceSize\":{\"y\":0,\"x\":0,\"w\":61,\"h\":61}},\"shadow.png\":{\"trimmed\":false,\"frame\":{\"y\":2,\"x\":2,\"w\":76,\"h\":78},\"rotated\":false,\"sourceSize\":{\"h\":78,\"w\":76},\"spriteSourceSize\":{\"y\":0,\"x\":0,\"w\":76,\"h\":78}},\"selection.png\":{\"trimmed\":false,\"frame\":{\"y\":85,\"x\":2,\"w\":76,\"h\":76},\"rotated\":false,\"sourceSize\":{\"h\":76,\"w\":76},\"spriteSourceSize\":{\"y\":0,\"x\":0,\"w\":76,\"h\":76}}},\"meta\":{\"scale\":\"1\",\"format\":\"RGBA8888\",\"app\":\"http://www.texturepacker.com\",\"version\":\"1.0\",\"smartupdate\":\"$TexturePacker:SmartUpdate:89901ac97cb2eae3221b3ed315bc5e53$\",\"image\":\"roundball.png\",\"size\":{\"h\":256,\"w\":256}}}"); +} \ No newline at end of file diff --git a/lime/demos/roundball/assets/roundball.png b/lime/demos/roundball/assets/roundball.png new file mode 100644 index 0000000000000000000000000000000000000000..c55c5fb968086bd6d604e6603cca2e019dc1cd93 GIT binary patch literal 48633 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�KT$ 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 Ef1M|U1^@s6 literal 0 HcmV?d00001 diff --git a/lime/demos/roundball/game.js b/lime/demos/roundball/game.js index 5c327cc9..9b6b492a 100644 --- a/lime/demos/roundball/game.js +++ b/lime/demos/roundball/game.js @@ -24,7 +24,7 @@ rb.Game = function(size) { var back = new lime.RoundedRect().setSize(690, 690).setAnchorPoint(0, 0).setPosition(17, 166).setRadius(30); for (var c = 0; c < this.board.cols; c++) { for (var r = 0; r < this.board.rows; r++) { - var b = new lime.Sprite().setFill('assets/shadow.png').setAnchorPoint(0, 0). + var b = new lime.Sprite().setFill(rb.ss.getFrame('shadow.png')).setAnchorPoint(0, 0). setSize(this.board.GAP * .94, this.board.GAP * .94). setPosition(11 + c * this.board.GAP, 11 + r * this.board.GAP); b.qualityRenderer = true; // no jagged edges on moz for this one diff --git a/lime/demos/roundball/gem.js b/lime/demos/roundball/gem.js index 5e19b082..2879e1fc 100644 --- a/lime/demos/roundball/gem.js +++ b/lime/demos/roundball/gem.js @@ -35,7 +35,7 @@ rb.Gem.random = function() { //var color = rb.Gem.colors[id]; var gem = new rb.Gem(); gem.index = id; - gem.circle.setFill('assets/ball_' + id + '.png'); + gem.circle.setFill(rb.ss.getFrame('ball_' + id + '.png')); return gem; }; @@ -45,7 +45,7 @@ rb.Gem.random = function() { rb.Gem.prototype.select = function() { if (this.selected_) return; var size = this.getSize().clone(); - this.highlight = new lime.Sprite().setSize(size).setFill('assets/selection.png'); + this.highlight = new lime.Sprite().setSize(size).setFill(rb.ss.getFrame('selection.png')); this.appendChild(this.highlight, 0); this.selected_ = true; diff --git a/lime/demos/roundball/rb.js b/lime/demos/roundball/rb.js index f823b8c2..80a0dada 100644 --- a/lime/demos/roundball/rb.js +++ b/lime/demos/roundball/rb.js @@ -12,17 +12,15 @@ goog.require('rb.Board'); goog.require('rb.Button'); goog.require('rb.Game'); goog.require('rb.Help'); -goog.require('lime.dom') +goog.require('lime.dom'); +goog.require('lime.SpriteSheet'); +goog.require('lime.ASSETS.roundball.json'); +goog.require('lime.parser.JSON'); //constant iPad size rb.WIDTH = 720; rb.HEIGHT = 1004; -// Ejecta has some issues on adding new textures on the fly. -var img = new Image(); -img.src = 'assets/selection.png'; -img = new Image(); -img.src = 'assets/shadow.png'; // entrypoint @@ -38,6 +36,9 @@ rb.start = function(parent) { rb.director = new lime.Director(parent || document.body, rb.WIDTH, rb.HEIGHT); rb.director.makeMobileWebAppCapable(); + rb.ss = new lime.SpriteSheet('assets/roundball.png',lime.ASSETS.roundball.json, lime.parser.JSON); + + rb.loadMenu(); }; From 03c1f837e2a11b6f76c7f422e2b4852f27922c35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Wed, 15 May 2013 16:23:16 +0300 Subject: [PATCH 24/31] Optimize properties --- lime/src/node.js | 16 ++++++++++++++++ lime/src/renderer/canvas.js | 2 +- lime/src/schedulemanager.js | 2 ++ lime/src/shape/label.js | 19 ++++++++++++++----- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/lime/src/node.js b/lime/src/node.js index 38a855a4..be64fed6 100644 --- a/lime/src/node.js +++ b/lime/src/node.js @@ -75,6 +75,22 @@ lime.Node = function() { this.setRenderer(this.supportedRenderers[0].getType()); this.setDirty(lime.Dirty.LAYOUT); + + this.activeMask_ = null; + this.isMask = null; + this.targetNode = null; + this.mWidth = null; + this.mHeight = null; + this.mPos = null; + this.mSet = null; + this.mX = null; + this.mY = null; + this.mRot = null; + this.relativeQuality_ = null; + this.hidden_ = null; + this.autoHide_ = null; + this.dependencySet_ = null; + this.maskTarget_ = null; }; goog.inherits(lime.Node, goog.events.EventTarget); diff --git a/lime/src/renderer/canvas.js b/lime/src/renderer/canvas.js index 733e6b59..68485c6c 100644 --- a/lime/src/renderer/canvas.js +++ b/lime/src/renderer/canvas.js @@ -236,7 +236,7 @@ lime.Renderer.CANVAS.drawCanvasObject = function(context) { var zero = new goog.math.Coordinate(0, 0); for (var i = 0, child; child = this.children_[i]; i++) { - var pos = child.localToParent(zero).clone(), rot = child.getRotation(), scale = child.getScale(); + var pos = child.localToParent(zero), rot = child.getRotation(), scale = child.getScale(); context.save(); context.translate(pos.x, pos.y); context.scale(scale.x,scale.y); diff --git a/lime/src/schedulemanager.js b/lime/src/schedulemanager.js index bfc831b5..f9f2ae04 100644 --- a/lime/src/schedulemanager.js +++ b/lime/src/schedulemanager.js @@ -48,6 +48,8 @@ lime.scheduleManager = new (function() { */ this.lastRunTime_ = 0; + this.animationFrameHandlerBinded_ = null; + })(); /** diff --git a/lime/src/shape/label.js b/lime/src/shape/label.js index 50281029..ff27263f 100644 --- a/lime/src/shape/label.js +++ b/lime/src/shape/label.js @@ -36,6 +36,11 @@ lime.Label = function(txt) { this.setStyle("normal"); + this.lastDrawnWidth_ = null; + this.sizeCache_ = null; + this.words_ = null; + this.lines_ = null; + }; goog.inherits(lime.Label, lime.Sprite); @@ -85,7 +90,7 @@ lime.Label.prototype.measureText = function() { w += 1; var stroke = this.stroke_?this.stroke_.width_:0; - return new goog.math.Size( + return this.sizeCache_ = new goog.math.Size( this.padding_[1] + this.padding_[3] + w + stroke*2, this.padding_[0] + this.padding_[2] + lh + stroke*2 ); @@ -96,7 +101,7 @@ lime.Label.prototype.measureText = function() { lime.Label.prototype.getSize = function() { var size = lime.Node.prototype.getSize.call(this); if (!size || (!size.width && !size.height)) { - return this.measureText(); + return this.sizeCache_ || this.measureText(); } return size; }; @@ -117,7 +122,7 @@ lime.Label.prototype.getText = function() { lime.Label.prototype.setText = function(txt) { this.text_ = txt + ''; this.setDirty(lime.Dirty.CONTENT); - delete this.words_; + this.words_ = null; return this; }; @@ -473,8 +478,12 @@ lime.Label.prototype.wrapText = function(context, width) { /** @inheritDoc */ lime.Label.prototype.update = function(){ - if(this.getDirty() & lime.Dirty.CONTENT) - delete this.lastDrawnWidth_; + var dirty = this.getDirty(); + + if (dirty & lime.Dirty.CONTENT) this.lastDrawnWidth_ = null; + if (dirty) { + this.sizeCache_ = null; + } lime.Node.prototype.update.apply(this,arguments); }; From bb8f45a5acd9f787cefaa524e893948eb3bbc166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Thu, 16 May 2013 11:26:40 +0300 Subject: [PATCH 25/31] Optimize properties --- lime/src/animation/animation.js | 10 ++++++++++ lime/src/animation/moveby.js | 7 +++++-- lime/src/animation/sequence.js | 3 +++ lime/src/node.js | 2 +- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lime/src/animation/animation.js b/lime/src/animation/animation.js index 79075d67..e5b1fcd2 100644 --- a/lime/src/animation/animation.js +++ b/lime/src/animation/animation.js @@ -41,6 +41,16 @@ lime.animation.Animation = function() { this.status_ = 0; + this.optimizations_ = null; + + this.playTime_ = 0; + + this.firstFrame_ = 1; + + this.dt_ = 0; + + goog.getUid(this); + }; goog.inherits(lime.animation.Animation, goog.events.EventTarget); diff --git a/lime/src/animation/moveby.js b/lime/src/animation/moveby.js index aa42b1b3..f2eed0d9 100644 --- a/lime/src/animation/moveby.js +++ b/lime/src/animation/moveby.js @@ -25,6 +25,9 @@ lime.animation.MoveBy = function(delta, opt_y) { this.delta_ = /** @type {!goog.math.Coordinate} */ (delta); } + this.speed_ = 0; + this.speedCalcDone_ = 0; + }; goog.inherits(lime.animation.MoveBy, lime.animation.Animation); @@ -64,10 +67,10 @@ lime.animation.MoveBy.prototype.makeTargetProp = function(target) { */ lime.animation.MoveBy.prototype.calcDurationFromSpeed_ = function(){ if(!this.speed_) return; - + this.setDuration(this.speed_ * goog.math.Coordinate.distance( this.delta_, new goog.math.Coordinate(0, 0)) / 100); - + this.speedCalcDone_ = 1; } diff --git a/lime/src/animation/sequence.js b/lime/src/animation/sequence.js index e1379309..b03a534b 100644 --- a/lime/src/animation/sequence.js +++ b/lime/src/animation/sequence.js @@ -31,6 +31,9 @@ lime.animation.Sequence = function(one) { this.setDuration(this.actions[0].duration_ + this.actions[1].duration_); + this.split_ = null; + this.last_ = 0; + }; goog.inherits(lime.animation.Sequence, lime.animation.Animation); diff --git a/lime/src/node.js b/lime/src/node.js index be64fed6..7976ff8e 100644 --- a/lime/src/node.js +++ b/lime/src/node.js @@ -883,7 +883,7 @@ lime.Node.getPropertyForTransition = function(transition) { * @return {lime.Node} Parent node. */ lime.Node.prototype.getParent = function() { - return this.parent_ ? this.parent_ : null; + return this.parent_ || null; }; /** From 5a494a1a2ca5580386d596493ea6968e4ab54f7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Thu, 16 May 2013 11:26:56 +0300 Subject: [PATCH 26/31] Roundball global leak --- lime/demos/roundball/board.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lime/demos/roundball/board.js b/lime/demos/roundball/board.js index 409e1b17..5c332142 100644 --- a/lime/demos/roundball/board.js +++ b/lime/demos/roundball/board.js @@ -182,7 +182,7 @@ rb.Board.prototype.checkSolutions = function() { * @return {Array.} Array of solutions. */ rb.Board.prototype.getSolutions = function() { - var r, c, g, group, res = []; + var r, c, g, group, res = [], i; //todo: this can be done with one loop From 2503c4f0a627e43a2c3c7045d954e67bd998a59b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Thu, 16 May 2013 12:18:44 +0300 Subject: [PATCH 27/31] Optimize Glossybuttons --- lime/demos/roundball/button.js | 19 +++++++++---------- lime/src/helper/glossybutton.js | 31 ++++++++++++++++++++----------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/lime/demos/roundball/button.js b/lime/demos/roundball/button.js index 4ac51766..7c5b5e77 100644 --- a/lime/demos/roundball/button.js +++ b/lime/demos/roundball/button.js @@ -12,6 +12,9 @@ goog.require('lime.GlossyButton'); rb.Button = function(txt) { lime.GlossyButton.call(this, txt); + this.updateState(this.upstate_); + this.updateState(this.downstate_); + this.borderWidth = 4; this.setColor('#000'); }; @@ -20,15 +23,11 @@ goog.inherits(rb.Button, lime.GlossyButton); /** * @inheritDoc */ -rb.Button.prototype.makeState_ = function() { - var state = new lime.RoundedRect().setFill('#fff').setRadius(10); - state.inner = new lime.RoundedRect().setRadius(10); - state.label = new lime.Label().setAlign('center'). +rb.Button.prototype.updateState = function(s) { + s.rect.setFill('#fff').setRadius(10); + s.inner.setRadius(10); + s.label.setAlign('center'). setFontFamily('"Trebuchet MS"').setFontColor('#eef').setFontSize(28); - - state.appendChild(state.inner); - state.inner.appendChild(state.label); - return state; }; /** @@ -36,8 +35,8 @@ rb.Button.prototype.makeState_ = function() { */ rb.Button.prototype.setColor = function(clr) { clr = lime.fill.parse(clr); - goog.array.forEach([this.upstate, this.downstate], function(s) { - var c = s == this.downstate ? clr.clone().addBrightness(.1) : clr; + goog.array.forEach([this.upstate_, this.downstate_], function(s) { + var c = s == this.downstate_ ? clr.clone().addBrightness(.1) : clr; //s.setFill(c); var c2 = c.clone().addBrightness(.3); var grad = new lime.fill.LinearGradient().setDirection(0, 0, 0, 1); diff --git a/lime/src/helper/glossybutton.js b/lime/src/helper/glossybutton.js index 2e9f927f..8ddaeb83 100644 --- a/lime/src/helper/glossybutton.js +++ b/lime/src/helper/glossybutton.js @@ -13,7 +13,12 @@ goog.require('lime.fill.LinearGradient'); * @extends lime.Button */ lime.GlossyButton = function(txt) { - lime.Button.call(this, this.makeState_(txt), this.makeState_(txt)); + var upstate = this.makeState_(txt); + var downstate = this.makeState_(txt); + lime.Button.call(this, upstate.rect, downstate.rect); + + this.upstate_ = upstate; + this.downstate_ = downstate; this.borderWidth = 2; @@ -30,12 +35,14 @@ goog.inherits(lime.GlossyButton, lime.Button); * @return {lime.RoundedRect} state. */ lime.GlossyButton.prototype.makeState_ = function(txt) { - var state = new lime.RoundedRect(); + var state = new lime.GlossyButton.State(); + + state.rect = new lime.RoundedRect(); state.inner = new lime.RoundedRect(); state.label = new lime.Label(txt).setAlign('center'). setFontFamily('"Trebuchet MS"').setFontColor('#010101').setFontSize(17); - state.appendChild(state.inner); + state.rect.appendChild(state.inner); state.inner.appendChild(state.label); return state; }; @@ -47,9 +54,9 @@ lime.GlossyButton.prototype.makeState_ = function(txt) { */ lime.GlossyButton.prototype.setColor = function(clr) { clr = lime.fill.parse(clr); - goog.array.forEach([this.upstate, this.downstate], function(s) { - var c = s == this.downstate ? clr.clone().addSaturation(-.2) : clr; - s.setFill(c); + goog.array.forEach([this.upstate_, this.downstate_], function(s) { + var c = s == this.downstate_ ? clr.clone().addSaturation(-.2) : clr; + s.rect.setFill(c); var grad = new lime.fill.LinearGradient().setDirection(0, 0, 0, 1); grad.addColorStop(0, c.clone().addBrightness(.13)); grad.addColorStop(.5, c.clone().addBrightness(.05)); @@ -66,8 +73,8 @@ lime.GlossyButton.prototype.setColor = function(clr) { * @return {lime.GlossyButton} object itself. */ lime.GlossyButton.prototype.setText = function(txt) { - this.upstate.label.setText(txt); - this.downstate.label.setText(txt); + this.upstate_.label.setText(txt); + this.downstate_.label.setText(txt); return this; }; @@ -98,9 +105,9 @@ lime.GlossyButton.prototype.setFontFamily = function(font) { lime.GlossyButton.prototype.setSize = function(value, opt_height) { if (this.upstate) { this.upstate.setSize.apply(this.upstate, arguments); - var size = this.upstate.getSize(); - goog.array.forEach([this.upstate, this.downstate], function(s) { - s.setSize(size); + var size = this.upstate_.rect.getSize(); + goog.array.forEach([this.upstate_, this.downstate_], function(s) { + s.rect.setSize(size); var innerSize = size.clone(); innerSize.width -= this.borderWidth; innerSize.height -= this.borderWidth; @@ -114,3 +121,5 @@ lime.GlossyButton.prototype.setSize = function(value, opt_height) { lime.GlossyButton.prototype.getSize = function() { return this.upstate.getSize(); }; + +lime.GlossyButton.State = function() {}; From c7e89c3146054d485a96b998e56307ed90805cfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CC=83nis=20Tiigi?= Date: Thu, 16 May 2013 13:55:09 +0300 Subject: [PATCH 28/31] Audio fixes for ejecta. --- lime/lib/jukebox/Manager.js | 2 +- lime/src/audio/audiomap.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lime/lib/jukebox/Manager.js b/lime/lib/jukebox/Manager.js index 6278af92..f028b8ed 100644 --- a/lime/lib/jukebox/Manager.js +++ b/lime/lib/jukebox/Manager.js @@ -164,7 +164,7 @@ jukebox.Manager.prototype = { * Flash Audio Support * Hint: All Android devices support Flash, even Android 1.6 ones */ - this.features.flashaudio = !!navigator.mimeTypes['application/x-shockwave-flash'] || !!navigator.plugins['Shockwave Flash'] || false; + this.features.flashaudio = !!navigator.mimeTypes && (!!navigator.mimeTypes['application/x-shockwave-flash'] || !!navigator.plugins['Shockwave Flash'] || false); // Internet Explorer if (window.ActiveXObject){ diff --git a/lime/src/audio/audiomap.js b/lime/src/audio/audiomap.js index 9e98593e..57ca1cf5 100644 --- a/lime/src/audio/audiomap.js +++ b/lime/src/audio/audiomap.js @@ -88,7 +88,7 @@ lime.audio.AudioMap.prototype.play = function(sprite, opt_loop, opt_after) { else if (this.player && this.config['spritemap'][sprite] && !lime.audio.getMute()) { this.player.play(sprite, true); var ctx = (this.player.context); - if (!ctx.duration || ctx.buffered.end(0) | 0 < ctx.duration | 0) return; + if (!ctx.duration || (ctx.buffered && (ctx.buffered.end(0) | 0 < ctx.duration | 0))) return; if (lime.audio._playQueue.indexOf(this) == -1) { lime.audio._playQueue.push(this); } From 15626abb8980688b8ca16921f9cbe5660fc06214 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Mon, 4 Nov 2013 17:12:22 +0200 Subject: [PATCH 29/31] Fix Zlizer buttons --- lime/demos/zlizer/button.js | 25 ++++++++++++------------- lime/demos/zlizer/game.js | 2 +- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/lime/demos/zlizer/button.js b/lime/demos/zlizer/button.js index d45dac22..c962ce3a 100644 --- a/lime/demos/zlizer/button.js +++ b/lime/demos/zlizer/button.js @@ -12,24 +12,23 @@ goog.require('lime.GlossyButton'); zlizer.Button = function(txt) { lime.GlossyButton.call(this, txt); + this.updateState(this.upstate_); + this.updateState(this.downstate_); + this.borderWidth = 4; this.setColor('#000'); }; goog.inherits(zlizer.Button, lime.GlossyButton); + /** - * Make state for a button. - * @private - * @return {lime.RoundedRect} state. + * @inheritDoc */ -zlizer.Button.prototype.makeState_ = function() { - var state = new lime.RoundedRect().setFill('#fff').setRadius(15); - state.inner = new lime.RoundedRect().setRadius(15); - state.label = new lime.Label().setAlign('center').setFontColor('#eef').setFontSize(35).setSize(250, 35); - - state.appendChild(state.inner); - state.inner.appendChild(state.label); - return state; +zlizer.Button.prototype.updateState = function(s) { + s.rect.setFill('#fff').setRadius(15); + s.inner.setRadius(15); + s.label.setAlign('center'). + setFontColor('#eef').setFontSize(35).setSize(250, 35); }; /** @@ -39,8 +38,8 @@ zlizer.Button.prototype.makeState_ = function() { */ zlizer.Button.prototype.setColor = function(clr) { clr = lime.fill.parse(clr); - goog.array.forEach([this.upstate, this.downstate], function(s) { - var c = s == this.downstate ? clr.clone().addBrightness(.1) : clr; + goog.array.forEach([this.upstate_, this.downstate_], function(s) { + var c = s == this.downstate_ ? clr.clone().addBrightness(.1) : clr; //s.setFill(c); var c2 = c.clone().addBrightness(.3); var grad = new lime.fill.LinearGradient().setDirection(0, 0, 0, 1); diff --git a/lime/demos/zlizer/game.js b/lime/demos/zlizer/game.js index fbbd0849..be8dd3f4 100644 --- a/lime/demos/zlizer/game.js +++ b/lime/demos/zlizer/game.js @@ -113,7 +113,7 @@ zlizer.Game.prototype.start = function() { this.layer.runAction(new lime.animation.FadeTo(1)); - this.graphics = new lime.CanvasContext().setSize(zlizer.director.getSize().clone()).setAnchorPoint(0,0).setQuality(.5); + this.graphics = new lime.CanvasContext().setSize(zlizer.director.getSize().clone()).setAnchorPoint(0,0); this.appendChild(this.graphics); this.graphics.draw = goog.bind(this.drawTouches_,this); From d54df185bf1eddd2fd3c90ec8e080863a6e3671d Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Mon, 4 Nov 2013 17:13:58 +0200 Subject: [PATCH 30/31] Include html files for demo games canvas only mode --- lime/demos/roundball/rb2.html | 23 +++++++++++++++++++++++ lime/demos/zlizer/zlizer2.html | 26 ++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 lime/demos/roundball/rb2.html create mode 100644 lime/demos/zlizer/zlizer2.html diff --git a/lime/demos/roundball/rb2.html b/lime/demos/roundball/rb2.html new file mode 100644 index 00000000..cf925a1f --- /dev/null +++ b/lime/demos/roundball/rb2.html @@ -0,0 +1,23 @@ + + + + + RoundBall + + + + + + + + + + + + \ No newline at end of file diff --git a/lime/demos/zlizer/zlizer2.html b/lime/demos/zlizer/zlizer2.html new file mode 100644 index 00000000..e2163338 --- /dev/null +++ b/lime/demos/zlizer/zlizer2.html @@ -0,0 +1,26 @@ + + + + + zlizer + + + + + + + + + + + + + + From 5ad9eb67a3b297105eac761cd09aa2bbbec39c0e Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Tue, 4 Mar 2014 23:07:30 +0200 Subject: [PATCH 31/31] Check performance.timing API (ConoonJS) --- lime/src/schedulemanager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lime/src/schedulemanager.js b/lime/src/schedulemanager.js index f9f2ae04..e85510ce 100644 --- a/lime/src/schedulemanager.js +++ b/lime/src/schedulemanager.js @@ -248,7 +248,7 @@ lime.scheduleManager.disable_ = function() { lime.scheduleManager.animationFrameHandler_ = function(time){ var performance = goog.global['performance'], now; - if (performance && (now = performance['now'] || performance['webkitNow'])) { + if (performance && performance['timing'] && (now = performance['now'] || performance['webkitNow'])) { time = performance['timing']['navigationStart'] + now.call(performance); } else if (!time) {