Click here to Skip to main content
Click here to Skip to main content

Parallax Background in XAML Revisited

By , 12 Oct 2012
Rate this:
Please Sign up or sign in to vote.

Adapted from the original post Metro Parallax Background in XAML.

Those who are super observant may have noticed that as you scroll through the tiles in the Windows 8 start screen, the background moves at about 1/10th the speed as the foreground. I've heard some people call this a "parallax background". No matter what we call it, I'm sure we all want it in our own Windows 8 app. This post explains one relatively simple way to accomplish this.

Trees

I am assuming that the foreground content is stored within a horizontal scrolling ScrollViewer. Let's give this ScrollViewer a name, like MyScrollViewer. In this demo, the content of the foreground is the front row of trees. The background can be anything: an Image, a Canvas, or in the case of this demo, more (smaller) trees.

<OBJECT type="application/x-shockwave-flash" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=3,0,0,0" WIDTH="570" HEIGHT="351" data="http://www.youtube.com/v/anKiCkiJAtY?hl=en&hd=1"></OBJECT>

I've added a RenderTransform to the background trees that allows me to translate (move) the starting position (x) of the background. I could set the TranslateX of the transform to a constant, or bind it to any value I wish. What I want to do is bind the TranslateX to the HorizontalOffset property of MyScrollViewer.

If I do this, the background will move at the same speed and in the opposite direction of the ScrollViewer. This is because as we scroll to the right and the foreground trees move left, HorizontalOffset increases. Increasing the value of TranslateX causes the background text to move right.

To slow down the background and reverse its direction, we need to multiply HorizontalOffset by something like -0.1 before assigning it to TranslateX. For this we write a converter called ParallaxConverter and apply the converter to the binding.

ParallaxConverter.cs
using System;
using Windows.UI.Xaml.Data;

namespace ParallaxBackgroundLibrary
{
    public class ParallaxConverter : IValueConverter
    {
        const double _factor = -0.10;

        public object Convert(object value, Type targetType, object parameter, string language)
        {
            double factor;
            if (!Double.TryParse(parameter as string, out factor))
            {
                factor = _factor;
            }

            if (value is double)
            {
                return (double)value * factor;
            }
            return 0;
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            double factor;
            if (!Double.TryParse(parameter as string, out factor))
            {
                factor = _factor;
            }

            if (value is double)
            {
                return (double)value / factor;
            }
            return 0;
        }
    }
}

If you look closely at the converter, it accepts a parameters in case you are not particularly pleased with my selection of -0.1. You can also use the parameter to create even more depth in you application by supporting two or more backgrounds with different converter factors. The demo code below demonstrates the use of the converter parameter by constructing two background rows of trees that move at different speeds as you pan left and right.

MainPage.xaml
<Page
   x:Class="ParallaxBackgroundDemoApp.MainPage"
   IsTabStop="false"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local="using:ParallaxBackgroundDemoApp"
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   xmlns:pbl="using:ParallaxBackgroundLibrary"
   mc:Ignorable="d">
    <Page.Resources>
        <pbl:ParallaxConverter
           x:Key="ParallaxConverter" />
    </Page.Resources>
    <Grid>
        <Rectangle>
            <Rectangle.Fill>
                <LinearGradientBrush
                   EndPoint="0.5,1"
                   StartPoint="0.5,0">
                    <GradientStop
                       Color="#FF5A8302"
                       Offset="0" />
                    <GradientStop
                       Color="#FFEEEE00"
                       Offset="1" />
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>
        <Canvas>
            <local:Trees>
                <local:Trees.RenderTransform>
                    <CompositeTransform
                       TranslateX="{Binding ElementName=MyScrollViewer, 
                         Path=HorizontalOffset, Converter={StaticResource ParallaxConverter}}"
                       ScaleX="0.25"
                       ScaleY="0.25" />
                </local:Trees.RenderTransform>
            </local:Trees>
        </Canvas>
        <Rectangle
           Fill="Black"
           Opacity="0.2" />
        <Canvas>
            <local:Trees>
                <local:Trees.RenderTransform>
                    <CompositeTransform
                       TranslateX="{Binding ElementName=MyScrollViewer, Path=HorizontalOffset, 
                         Converter={StaticResource ParallaxConverter}, ConverterParameter=-0.2}"
                       ScaleX="0.5"
                       ScaleY="0.5" />
                </local:Trees.RenderTransform>
            </local:Trees>
        </Canvas>
        <Rectangle
           Fill="Black"
           Opacity="0.2" />
        <ScrollViewer
           x:Name="MyScrollViewer"
           HorizontalScrollMode="Enabled"
           HorizontalScrollBarVisibility="Auto">
            <local:Trees />
        </ScrollViewer>
    </Grid>
</Page>

That’s it.

ParallaxBackground binary (basically just the converter) resides here: http://nuget.org/packages/parallaxbackground/

ParallaxBackground source (complete with the demo trees application) resides here: http://parallaxbackground.codeplex.com/

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

John Michael Hauck
Software Developer (Senior) LECO Corporation
United States United States
John Hauck has been developing software professionally since 1981, and focused on Windows-based development since 1988. For the past 17 years John has been working at LECO, a scientific laboratory instrument company, where he manages software development. John also served as the manager of software development at Zenith Data Systems, as the Vice President of software development at TechSmith, as the lead medical records developer at Instrument Makar, as the MSU student who developed the time and attendance system for Dart container, and as the high school kid who wrote the manufacturing control system at Wohlert. John loves the Lord, his wife, their three kids, and sailing on Lake Michigan.
Follow on   Twitter

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web01 | 2.8.140421.2 | Last Updated 12 Oct 2012
Article Copyright 2012 by John Michael Hauck
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid