diff --git a/src/android/NativePageTransitions.java b/src/android/NativePageTransitions.java index 83ed8b5..08e9e8b 100644 --- a/src/android/NativePageTransitions.java +++ b/src/android/NativePageTransitions.java @@ -33,6 +33,7 @@ public class NativePageTransitions extends CordovaPlugin { private float retinaFactor; private long duration; private long delay; + private TransitionType pendingTransitionType; private String drawerAction; private String drawerOrigin; private String direction; @@ -61,14 +62,9 @@ public class NativePageTransitions extends CordovaPlugin { public Object onMessage(String id, Object data) { if ("onPageFinished".equalsIgnoreCase(id)) { - if ("slide".equalsIgnoreCase(_action)) { - doSlideTransition(); - } else if ("fade".equalsIgnoreCase(_action)) { - doFadeTransition(); - } else if ("flip".equalsIgnoreCase(_action)) { - doFlipTransition(); - } else if ("drawer".equalsIgnoreCase(_action)) { - doDrawerTransition(); + TransitionType type = TransitionType.fromString(_action); + if (type != null) { + type.doTransition(this); } } return super.onMessage(id, data); @@ -121,16 +117,13 @@ public boolean execute(String action, JSONArray args, final CallbackContext call if ("executePendingTransition".equalsIgnoreCase(action)) { delay = 0; - if ("slide".equalsIgnoreCase(_action)) { - doSlideTransition(); - } else if ("fade".equalsIgnoreCase(_action)) { - doFadeTransition(); - } else if ("flip".equalsIgnoreCase(_action)) { - doFlipTransition(); - } else if ("drawer".equalsIgnoreCase(_action)) { - doDrawerTransition(); + if (pendingTransitionType != null) { + pendingTransitionType.doTransition(this); + pendingTransitionType = null; + return true; + } else { + return false; } - return true; } _action = action; @@ -193,15 +186,12 @@ public void run() { } } - if (href != null && !"null".equals(href)) { - if (!href.startsWith("#") && href.contains(".html")) { + if (href != null && !"null".equals(href) && !href.startsWith("#") && href.contains(".html")) { webView.loadUrlIntoView(HREF_PREFIX + href, false); - } else if (delay > -1) { - // it's a #hash, which is handled in JS + } else if (shouldFireNow()) { doSlideTransition(); - } - } else if (delay > -1) { - doSlideTransition(); + } else { + pendingTransitionType = TransitionType.SLIDE; } } }); @@ -248,15 +238,12 @@ public void run() { bringToFront(imageView2); } - if (href != null && !"null".equals(href)) { - if (!href.startsWith("#") && href.contains(".html")) { + if (href != null && !"null".equals(href) && !href.startsWith("#") && href.contains(".html")) { webView.loadUrlIntoView(HREF_PREFIX + href, false); - } else if (delay > -1) { - // it's a #hash, which is handled in JS + } else if (shouldFireNow()) { doDrawerTransition(); - } - } else if (delay > -1) { - doDrawerTransition(); + } else { + pendingTransitionType = TransitionType.DRAWER; } } }); @@ -272,15 +259,12 @@ public void run() { imageView.setImageBitmap(getBitmap()); bringToFront(imageView); - if (href != null && !"null".equals(href)) { - if (!href.startsWith("#") && href.contains(".html")) { + if (href != null && !"null".equals(href) && !href.startsWith("#") && href.contains(".html")) { webView.loadUrlIntoView(HREF_PREFIX + href, false); - } else if (delay > -1) { - // it's a #hash, which is handled in JS + } else if (shouldFireNow()) { doFadeTransition(); - } - } else if (delay > -1) { - doFadeTransition(); + } else { + pendingTransitionType = TransitionType.FADE; } } }); @@ -295,15 +279,12 @@ public void run() { @Override public void run() { imageView.setImageBitmap(getBitmap()); - if (href != null && !"null".equals(href)) { - if (!href.startsWith("#") && href.contains(".html")) { + if (href != null && !"null".equals(href) && !href.startsWith("#") && href.contains(".html")) { webView.loadUrlIntoView(HREF_PREFIX + href, false); - } else if (delay > -1) { - // it's a #hash, which is handled in JS + } else if (shouldFireNow()) { doFlipTransition(); - } - } else if (delay > -1) { - doFlipTransition(); + } else { + pendingTransitionType = TransitionType.FLIP; } } }); @@ -311,7 +292,7 @@ public void run() { return true; } - private void doFadeTransition() { + public void doFadeTransition() { if (!calledFromJS || this._callbackContext.getCallbackId().equals(lastCallbackID)) { return; } @@ -374,7 +355,7 @@ public void onAnimationRepeat(Animation animation) { }, delay); } - private void doFlipTransition() { + public void doFlipTransition() { if (!calledFromJS || this._callbackContext.getCallbackId().equals(lastCallbackID)) { return; } @@ -444,7 +425,7 @@ public void onAnimationRepeat(Animation animation) { }, delay); } - private void doSlideTransition() { + public void doSlideTransition() { if (!calledFromJS || this._callbackContext.getCallbackId().equals(lastCallbackID)) { return; } @@ -579,7 +560,7 @@ public void onAnimationRepeat(Animation animation) { }, delay); } - private void doDrawerTransition() { + public void doDrawerTransition() { if (!calledFromJS || this._callbackContext.getCallbackId().equals(lastCallbackID)) { return; } @@ -721,4 +702,54 @@ private void enableHardwareAcceleration() { } } } + + private boolean shouldFireNow() { + return delay >= 0; + } + + private enum TransitionType { + FLIP("flip") { + @Override + public void doTransition(NativePageTransitions plugin) { + plugin.doFlipTransition(); + } + }, + SLIDE("slide") { + @Override + public void doTransition(NativePageTransitions plugin) { + plugin.doSlideTransition(); + } + }, + FADE("fade") { + @Override + public void doTransition(NativePageTransitions plugin) { + plugin.doFadeTransition(); + } + }, + DRAWER("drawer") { + @Override + public void doTransition(NativePageTransitions plugin) { + plugin.doDrawerTransition(); + } + }; + + private String code; + + private TransitionType(String code) { + this.code = code; + } + + public abstract void doTransition(NativePageTransitions plugin); + + public static TransitionType fromString(String text) { + if (text != null) { + for (TransitionType type : TransitionType.values()) { + if (text.equalsIgnoreCase(type.code)) { + return type; + } + } + } + return null; + } + } } \ No newline at end of file diff --git a/www/NativePageTransitions.js b/www/NativePageTransitions.js index 33ac670..fd24140 100755 --- a/www/NativePageTransitions.js +++ b/www/NativePageTransitions.js @@ -4,16 +4,14 @@ function NativePageTransitions() { NativePageTransitions.prototype.globalOptions = { duration: 400, iosdelay: 60, // a number of milliseconds, or -1 (call executePendingTransition() when ready) - androiddelay: 70, // a number of milliseconds, or -1 (call executePendingTransition() when ready) + androiddelay: 70, // a number of milliseconds, a function that takes an animate callback that will execute pending transition when invoked, or -1 to manually call executePendingTransition() when ready winphonedelay: 200, slowdownfactor: 4, fixedPixelsTop: 0, // currently for slide left/right only fixedPixelsBottom: 0 // currently for slide left/right only }; -NativePageTransitions.prototype.executePendingTransition = function (onSuccess, onError) { - cordova.exec(onSuccess, onError, "NativePageTransitions", "executePendingTransition", []); -}; +NativePageTransitions.prototype.executePendingTransition = executePendingTransition; NativePageTransitions.prototype.slide = function (options, onSuccess, onError) { var opts = options || {}; @@ -24,15 +22,7 @@ NativePageTransitions.prototype.slide = function (options, onSuccess, onError) { if (opts.duration == undefined || opts.duration == "null") { opts.duration = this.globalOptions.duration; } - if (opts.androiddelay == undefined || opts.androiddelay == "null") { - opts.androiddelay = this.globalOptions.androiddelay; - } - if (opts.iosdelay == undefined || opts.iosdelay == "null") { - opts.iosdelay = this.globalOptions.iosdelay; - } - if (opts.winphonedelay == undefined || opts.winphonedelay == "null") { - opts.winphonedelay = this.globalOptions.winphonedelay; - } + var delayCallbacks = setupDelayOptions(opts); if (opts.fixedPixelsTop == undefined || opts.fixedPixelsTop == "null") { opts.fixedPixelsTop = this.globalOptions.fixedPixelsTop; } @@ -42,6 +32,7 @@ NativePageTransitions.prototype.slide = function (options, onSuccess, onError) { // setting slowdownfactor > 1 makes the next page slide less pixels. Use 1 for side-by-side. opts.slowdownfactor = opts.slowdownfactor || this.globalOptions.slowdownfactor; cordova.exec(onSuccess, onError, "NativePageTransitions", "slide", [opts]); + fireDelayCallbacks(delayCallbacks); }; NativePageTransitions.prototype.drawer = function (options, onSuccess, onError) { @@ -54,16 +45,9 @@ NativePageTransitions.prototype.drawer = function (options, onSuccess, onError) if (opts.duration == undefined || opts.duration == "null") { opts.duration = this.globalOptions.duration; } - if (opts.androiddelay == undefined || opts.androiddelay == "null") { - opts.androiddelay = this.globalOptions.androiddelay; - } - if (opts.iosdelay == undefined || opts.iosdelay == "null") { - opts.iosdelay = this.globalOptions.iosdelay; - } - if (opts.winphonedelay == undefined || opts.winphonedelay == "null") { - opts.winphonedelay = this.globalOptions.winphonedelay; - } + var delayCallbacks = setupDelayOptions(opts); cordova.exec(onSuccess, onError, "NativePageTransitions", "drawer", [opts]); + fireDelayCallbacks(delayCallbacks); }; NativePageTransitions.prototype.flip = function (options, onSuccess, onError) { @@ -75,16 +59,9 @@ NativePageTransitions.prototype.flip = function (options, onSuccess, onError) { if (opts.duration == undefined || opts.duration == "null") { opts.duration = this.globalOptions.duration; } - if (opts.androiddelay == undefined || opts.androiddelay == "null") { - opts.androiddelay = this.globalOptions.androiddelay; - } - if (opts.iosdelay == undefined || opts.iosdelay == "null") { - opts.iosdelay = this.globalOptions.iosdelay; - } - if (opts.winphonedelay == undefined || opts.winphonedelay == "null") { - opts.winphonedelay = this.globalOptions.winphonedelay; - } + var delayCallbacks = setupDelayOptions(opts); cordova.exec(onSuccess, onError, "NativePageTransitions", "flip", [opts]); + fireDelayCallbacks(delayCallbacks); }; NativePageTransitions.prototype.curl = function (options, onSuccess, onError) { @@ -96,10 +73,9 @@ NativePageTransitions.prototype.curl = function (options, onSuccess, onError) { if (opts.duration == undefined || opts.duration == "null") { opts.duration = this.globalOptions.duration; } - if (opts.iosdelay == undefined || opts.iosdelay == "null") { - opts.iosdelay = this.globalOptions.iosdelay; - } + var delayCallbacks = setupDelayOptions(opts, {android: false, winphone: false}); cordova.exec(onSuccess, onError, "NativePageTransitions", "curl", [opts]); + fireDelayCallbacks(delayCallbacks); }; NativePageTransitions.prototype.fade = function (options, onSuccess, onError) { @@ -110,13 +86,9 @@ NativePageTransitions.prototype.fade = function (options, onSuccess, onError) { if (opts.duration == undefined || opts.duration == "null") { opts.duration = this.globalOptions.duration; } - if (opts.androiddelay == undefined || opts.androiddelay == "null") { - opts.androiddelay = this.globalOptions.androiddelay; - } - if (opts.iosdelay == undefined || opts.iosdelay == "null") { - opts.iosdelay = this.globalOptions.iosdelay; - } + var delayCallbacks = setupDelayOptions(opts, {winphone: false}); cordova.exec(onSuccess, onError, "NativePageTransitions", "fade", [opts]); + fireDelayCallbacks(delayCallbacks); }; NativePageTransitions.prototype._validateHref = function (href, errCallback) { @@ -173,4 +145,54 @@ NativePageTransitions.install = function () { return window.plugins.nativepagetransitions; }; +function setupDelayOptions(opts, whichOS) { + whichOS = whichOS || {}; + whichOS = { + android: whichOS.android !== false, + ios: whichOS.ios !== false, + winphone: whichOS.winphone !== false + }; + var callbacks = []; + var globalOptions = NativePageTransitions.prototype.globalOptions; + if (whichOS.android) { + if (opts.androiddelay == undefined || opts.androiddelay == "null") { + opts.androiddelay = globalOptions.androiddelay; + } else if (typeof opts.androiddelay == 'function') { + callbacks.push(opts.androiddelay); + opts.androiddelay = -1; + } + } + if (whichOS.ios) { + if (opts.iosdelay == undefined || opts.iosdelay == "null") { + opts.iosdelay = globalOptions.iosdelay; + } else if (typeof opts.iosdelay == 'function') { + callbacks.push(opts.iosdelay); + opts.iosdelay = -1; + } + } + if (whichOS.winphone && (opts.winphonedelay == undefined || opts.winphonedelay == "null")) { + opts.winphonedelay = globalOptions.winphonedelay; + } + return callbacks; +} + +function animate(onSuccess, onError) { + onSuccess = onSuccess || function() {}; + onError = onError || function() {}; + executePendingTransition(onSuccess, onError); +} + +function fireDelayCallbacks(callbacks) { + if (callbacks) { + for (var i = 0; i < callbacks.length; i++) { + var callback = callbacks[i]; + callback(animate); + } + } +} + +function executePendingTransition(onSuccess, onError) { + cordova.exec(onSuccess, onError, "NativePageTransitions", "executePendingTransition", []); +}; + cordova.addConstructor(NativePageTransitions.install); \ No newline at end of file