Search code examples
windows-phone-8transitioncross-fade

Cross fade page transitions Windows phone 8 toolkit


I'm implementing the NavigationTransition with the TransitionService provided by the Windows Phone 8 toolkit and Microsoft.Phone.Controls. I was expecting the pages to cross fade during the transition but they don't crossfade by default.

For instance if I'm going back to a previous page using a fade out transition, the origin page fades to full opacity before the target page appears, producing a "popping" effect.

I hoping that someone could provide guidance on getting that effect to happen.


Solution

  • I ended up using some slight-of-hand with screen shots and the far background plane to make the phone pages appear to "cross-fade" - here with edited out biz-details:

    public class FormPage : PhoneApplicationPage {
        public FormPage() {
            InitializeComponent();
            PrepareAnimationIn(FormApp.frameTransition);
        }
    
        void PrepareAnimationIn(string pageAnimation) {
            AnimatedPageFactory.SetNavigationInTransition(pageAnimation, this);
        }
    
        public void PrepareAnimationOut(string pageAnimation) {
            AnimatedPageFactory.SetNavigationOutTransition(pageAnimation, this);
        }
    
        void StoreScreenShot(string name, WriteableBitmap bitmap) {
            using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
                string path = Path.Combine(screenshotDir, name + screenFileType);
                store.CreateDirectory(screenshotDir);
                using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(path, FileMode.Create, store)) {
                    using (BinaryWriter writer = new BinaryWriter(stream)) {
                        int count = bitmap.Pixels.Length * sizeof(int);
                        byte[] pixels = new byte[count];
                        Buffer.BlockCopy(bitmap.Pixels, 0, pixels, 0, count);
                        writer.Write(pixels, 0, pixels.Length);
                    }
                }
            }
        }
    
        WriteableBitmap FetchScreenShot(string name) {
            WriteableBitmap bitmap = new WriteableBitmap((int)this.ActualWidth, (int)this.ActualHeight);
    
            using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
                string path = Path.Combine(screenshotDir, name + screenFileType);
                if (store.FileExists(path)) {
    
                    using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(path, FileMode.Open, store)) {
                        using (BinaryReader reader = new BinaryReader(stream)) {
                            int count = bitmap.Pixels.Length * sizeof(int);
                            byte[] pixels = new byte[count];
                            reader.Read(pixels, 0, count);
                            Buffer.BlockCopy(pixels, 0, bitmap.Pixels, 0, count);
                        }
                    }
    
                    store.DeleteFile(path);
                }
            }
            return bitmap;
        }
    
        WriteableBitmap ScreenShot() {
            WriteableBitmap bmpCurrentScreenImage = new WriteableBitmap((int)this.ActualWidth, (int)this.ActualHeight);
            bmpCurrentScreenImage.Render(_canvas, new MatrixTransform());
            bmpCurrentScreenImage.Invalidate();
            return bmpCurrentScreenImage;
        }
    
        ImageBrush ImageBrushFromBitmap(WriteableBitmap bitmap) {
            return new ImageBrush { ImageSource = bitmap };
        }
    
        static Stack<string> formImages = new Stack<string>();
        static string screenFileType = ".frmscn";
        static string screenshotDir = "frmscrn";
    
        protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) {
    
            var app = Application.Current as App;
    
            if (e.NavigationMode == NavigationMode.New &&
                e.Uri.ToString().Contains("FormPage.xaml")) {
    
                WriteableBitmap screenShot = ScreenShot();
    
                app.RootFrame.Background = ImageBrushFromBitmap(screenShot);
    
                formImages.Push(Name);
                StoreScreenShot(Name, screenShot);
    
            } else if (e.NavigationMode == NavigationMode.Back) {
                if (formImages.Count > 0)
                    app.RootFrame.Background = ImageBrushFromBitmap(FetchScreenShot(formImages.Pop()));
                else {
                    //we're backing out of the last form so reset the background
                    app.RootFrame.Background = null;
                    RemoveCachedScreenshots();
                }
            }
        }
    
        public static void RemoveCachedScreenshots() {
            using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
                string path = Path.Combine(screenshotDir, "*" + screenFileType);
                try {
                    string[] fileList = store.GetFileNames(path);
                    foreach (string f in fileList) {
                        store.DeleteFile(Path.Combine(screenshotDir, f));
                    }
                } catch {
    
                }
            }
        }
    }