Reaali Robootika.COM

NXT robotimaailm ja programmeerimine C-keeles

Windows Phone – Accelerometer, kiirendusandur

Windows Phone’i on sisse ehitatud kolmesuunaline kiirendusandur. Alljärgnevas rakenduses kasutatakse punase palli liigutamiseks kahte dimensiooni, kuid värvilised jooned ekraanil iseloomustavad telefoni liikumist kolmes erinevas suunas.

MSDN artikkel: http://msdn.microsoft.com/en-us/library/ff431810(v=vs.92).aspx 

Antud kood on internetinäidete põhjal kokku pandud kahest erinevast rakendusest – kolmemõõtmeliste joonte kuvamine ning palli edasi-tagasi sõitmine mööda ekraani.

How accelerometer is working–check it out!

MainPage.xaml

<phone:PhoneApplicationPage
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
   xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   x:Class="AccelerometerTest.MainPage"
   mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
   FontFamily="{StaticResource PhoneFontFamilyNormal}"
   FontSize="{StaticResource PhoneFontSizeNormal}"
   Foreground="{StaticResource PhoneForegroundBrush}"
   SupportedOrientations="Portrait" Orientation="Portrait"
   shell:SystemTray.IsVisible="True">

    <Grid Name="MyGrid" Width="411" Height="768">
        <Line x:Name="xLine" X1="200" Y1="400" X2="260" Y2="400" Stroke="Red" StrokeThickness="4" Margin="0"/>
        <Line x:Name="yLine" X1="200" Y1="400" X2="200" Y2="340" Stroke="Green" StrokeThickness="4" Margin="0"/>
        <Line x:Name="zLine" X1="200" Y1="400" X2="260" Y2="340" Stroke="Blue" StrokeThickness="4" Margin="0"/>
        <Rectangle x:Name="Track" Height="80" Stroke="#FFC0C0C0"
            RadiusX="40" RadiusY="40" Margin="0" Width="410" />
        <Ellipse x:Name="Ball" Width="80" Height="80" Margin="0">
            <Ellipse.Fill>
                <RadialGradientBrush GradientOrigin="0.234,0.255">
                    <GradientStop Color="White"/>
                    <GradientStop Color="Red" Offset="0.759"/>
                </RadialGradientBrush>
            </Ellipse.Fill>
            <Ellipse.RenderTransform>
                <TranslateTransform x:Name="BallTransform" />
            </Ellipse.RenderTransform>
        </Ellipse>
        <TextBlock Height="50" HorizontalAlignment="Left" Margin="0" Name="textBlock1" Text="TextBlock" VerticalAlignment="Top" Width="200" />
        <TextBlock Height="50" HorizontalAlignment="Left" Margin="0,50,0,0" Name="textBlock2" Text="TextBlock" VerticalAlignment="Top" Width="200" />
        <TextBlock Height="50" HorizontalAlignment="Left" Margin="0,100,0,0" Name="textBlock3" Text="TextBlock" VerticalAlignment="Top" Width="200" />
    </Grid
>

</
phone:PhoneApplicationPage
>

MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Devices.Sensors;
using Microsoft.Xna.Framework;
using Microsoft.Phone.Shell;

namespace AccelerometerTest
{
    public partial class MainPage : PhoneApplicationPage
    {
        private const int sum = 25;
        private const double gravity = 32.2; // raskusjõud (ft/sec2)
        private const double damping = 0.5;  // põrketugevus
        private const double mul = 128.0;    // palli liikumise tundlikkus
        private double _sx = 0.0;
        private double _sy = 0.0;
        private double _vx = 0.0;
        private double _vy = 0.0;
        private double _ax = 0.0;
        private double _ay = 0.0;
        private double _time = DateTime.Now.Ticks;
        private double width, height;
        private double time;

        private Accelerometer _accel = new Accelerometer();
        Vector3 acceleration;
        public MainPage()
        {
            InitializeComponent();

            //järgmised kaks rida on selle jaoks, et telefonile ei tuleks "lukku" peale
            PhoneApplicationService phoneAppService = PhoneApplicationService.Current;
            phoneAppService.UserIdleDetectionMode = IdleDetectionMode.Disabled;

            width = (Application.Current.Host.Content.ActualWidth - Ball.Width) / 2.0;
            height = (MyGrid.Height - Ball.Height) / 2.0;

            // Start acceleroemeter
            _accel.CurrentValueChanged +=
                new EventHandler<SensorReadingEventArgs<AccelerometerReading>>(OnReadingChanged);
            _accel.Start();
        }
        private void OnReadingChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
        {
            time = e.SensorReading.Timestamp.Ticks;
            acceleration = e.SensorReading.Acceleration;
            Dispatcher.BeginInvoke(() => UpdateDisplay());
            // käivita UI thread 
        }

        private double calculate(double[] k) {
            double ysum = 0;
            for (int i = 0; i < sum; i++)
                ysum += k[i];
            return ysum;
        }
        private void UpdateDisplay()
        {
            //saadakse kätte kiirendused kolmes suunas
            double x = acceleration.X;
            double y = acceleration.Y;
            double z = acceleration.Z;

            //time on suurusjärgus 0,02 ja = (praegune aeg - eelmine aeg) / 10 000 000
            double ajavahemik = (time - _time) / 10000000.0;

            //ax = ((kiirendus * raskusjõud (1G)) + eelmine kiirendus) / 2
            // keskmine kiirendus kahe ajavahemiku vahel
            double ax = ((x * gravity) + _ax) / 2.0;
            double ay = ((y * gravity) + _ay) / 2.0;

            // vx (kiirus) = eelmine keskmine kiirus + (keskmine kiirendus * aeg [ehk hetkel keskmine kiirus])
            double vx = _vx + (ax * ajavahemik);
            double vy = _vy + (ay * ajavahemik);

            //palli uus asukoht teljel = eelmine asukoht + ((((eelmine kiirus + praegune kiirus) / 2 ) * aeg ) * kordaja=128)
            //lühemalt: palli uus asukoht = eelmine asukoht + käesoleva asukoht
            double sx = _sx + ((((_vx + vx) / 2.0) * ajavahemik) * mul);
            double sy = _sy - ((((_vy + vy) / 2.0) * ajavahemik) * mul);

            //alljärgnev arvutus tekitab põrkamise
            // kui asukoht on väiksem kui -laius. laius on pool ekraanilaiusest - palli läbimõõt
            //siis palli asukoht on minimaalne laius ja kiirus on -kiirus * 0,5
            //(see on siis kiiruse vähenemine poole võrra aga vastassuunas)
            if (sx < -width)
            {
               sx = -width;
               vx = -vx * damping;
           }
           else if (sx > width)
            {
               sx = width;
               vx = -vx * damping;
           }
            if (sy < -height)
            {
                sy = -height;
                vy = -vy * damping;
            }
            else if (sy > height)
            {
                sy = height;
                vy = -vy * damping;
            }
            // salvesta parameetrid järgmise tsükli tarvis
            _time = time;
            _ax = ax;
            _ay = ay;
            _vx = vx;
            _vy = vy;
            _sx = sx;
            _sy = sy;

            //tehakse transformX ning omistatakse sellele asukoha väärtus
            //tulemus on see, et pall liigub ettenähtud kohale
            BallTransform.X = sx;
            BallTransform.Y = sy;

            //joonistatakse kolmemõõtmelised värvilised jooned
            xLine.X2 = xLine.X1 + acceleration.X * 400;
            yLine.Y2 = yLine.Y1 - acceleration.Y * 400;
            zLine.X2 = zLine.X1 - acceleration.Z * 200;
            zLine.Y2 = zLine.Y1 + acceleration.Z * 200;

            //kuvatakse kiirendusnumbrid
            textBlock1.Text = "X: " + x.ToString("0.000");
            textBlock2.Text = "Y: " + y.ToString("0.000");
            textBlock3.Text = "Z: " + z.ToString("0.000");
        }
    }
}

Windows Phone – EASE funktsioonid

EASE-funktsioonid on Silverlightis välja töötatud spetsiaalsete matemaatiliste algoritmidega funktsioonid, mis võimaldavad lihtsal moel objekte erilisel viisil liikuma ja põrkama panna.

Alljärgnevas näites on realiseeritud 4 kõige silmapaistvamat EASE funktsiooni, milleks on

·         BackEase

image

·         BounceEase

image

·         ElasticEase

image

·         ExponentialEase

image

Täpsemalt leiad Ease funktsioonide kohta siit lehelt: http://msdn.microsoft.com/en-us/library/ee308751.aspx 

Vaata kõigepealt antud rakenduse videot, et tekiks parem arusaamine antud funktsioonide eripäradest.

Windows Phone - how Ease functions working

MainPage.xaml

<phone:PhoneApplicationPage
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
   xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   xmlns:Microsoft_Advertising_Mobile_UI="clr-namespace:Microsoft.Advertising.Mobile.UI;assembly=Microsoft.Advertising.Mobile.UI"
   x:Class="PhoneApp1.MainPage"
   mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
   SupportedOrientations="Portrait" Orientation="Portrait"
   shell:SystemTray.IsVisible="True">

      <Grid x:Name="LayoutRoot" Background="Transparent">
        
        <Canvas>
            <Canvas.Resources>
                <Storyboard x:Name="myStoryboard" Completed="myStoryboard_Completed">
                    <DoubleAnimation x:Name="RectangleAnimation" From="0" To="300" Duration="00:00:04"
                                    Storyboard.TargetName="Myrectangle"
                                    Storyboard.TargetProperty="(Canvas.Top)"
                                    >
                                        </DoubleAnimation>
                    <DoubleAnimation x:Name="RectangleAnimation1" From="650" To="351" Duration="00:00:04"
                                    Storyboard.TargetName="Myrectangle1"
                                    Storyboard.TargetProperty="(Canvas.Top)"
                                    >
                    </DoubleAnimation>
                    <DoubleAnimation x:Name="RingAnimationX" From="0" To="1"
                                    Duration="00:00:04"
                                    Storyboard.TargetName="Ring"
                                    Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)"
                                    >
                    </DoubleAnimation>
                    <DoubleAnimation x:Name="RingAnimationY" From="0" To="1"
                                    Duration="00:00:04"
                                    Storyboard.TargetName="Ring"
                                    Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" >
                    </DoubleAnimation>
                    <DoubleAnimation x:Name="SliderRotation1" From="0" To="360"
                                    Duration="00:00:06"
                                    Storyboard.TargetName="slider1"
                                    Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" >
                    </DoubleAnimation>
                    <DoubleAnimation x:Name="SliderRotation2" From="0" To="360"
                                    Duration="00:00:03"
                                    Storyboard.TargetName="slider2"
                                    Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" >
                    </DoubleAnimation>

                </Storyboard>
                <Storyboard x:Name="ProgressStoryBoard">
                    <DoubleAnimation x:Name="Progressbar" From="0" To="100"
                                    Duration="00:00:06"
                                    Storyboard.TargetName="progressBar1"
                                    Storyboard.TargetProperty="Value" >
                    </DoubleAnimation>
                </Storyboard>
            </Canvas.Resources>
            <Rectangle x:Name="Myrectangle" Width="50" Height="50" VerticalAlignment="Center" Canvas.Left="27" Canvas.Top="0" Fill="Blue" RadiusX="10" RadiusY="10" />
            <Rectangle x:Name="Myrectangle1" Width="50" Height="50" VerticalAlignment="Center" Canvas.Left="27" Canvas.Top="650" Fill="Red" RadiusX="10" RadiusY="10" />
            <RadioButton Canvas.Left="235" Canvas.Top="6" Content="Back Ease" Height="71" Name="backEase" Width="245" GroupName="EaseRadio" Checked="backEase_Checked" />
            <RadioButton Canvas.Left="235" Canvas.Top="77" Content="Bounce Ease" Height="71" Name="bounceEase" Width="245" GroupName="EaseRadio" Checked="bounceEase_Checked" />
            <RadioButton Canvas.Left="235" Canvas.Top="154" Content="Elastic Ease" Height="71" Name="elasticEase" Width="245" GroupName="EaseRadio" Checked="elasticEase_Checked" />
            <RadioButton Canvas.Left="235" Canvas.Top="231" Content="Exponential" Height="71" Name="exponentialEase" Width="245" GroupName="EaseRadio" Checked="exponentialEase_Checked" />
            <Slider Canvas.Left="235" Canvas.Top="360" Height="344" Name="slider1" Width="80" Orientation="Vertical" Visibility="Visible" SmallChange="0.5" ValueChanged="slider1_ValueChanged" RenderTransformOrigin="0.5,0.5">
                <Slider.RenderTransform>
                    <CompositeTransform Rotation="0"></CompositeTransform>
                </Slider.RenderTransform>
            </Slider>
            <Slider Canvas.Left="329" Canvas.Top="360" Height="344" Name="slider2" Width="80" Orientation="Vertical" SmallChange="0.5" ValueChanged="slider2_ValueChanged" RenderTransformOrigin="0.5,0.5">
                <Slider.RenderTransform>
                    <CompositeTransform Rotation="0"></CompositeTransform>
                </Slider.RenderTransform>
            </Slider>
            <TextBlock Canvas.Left="170" Canvas.Top="309" Height="46" Name="textBlock1" Width="145" TextAlignment="Center" FontSize="24" />
            <TextBlock Canvas.Left="329" Canvas.Top="309" Height="46" Name="textBlock2" Width="145" TextAlignment="Center" FontSize="24" />
            <TextBlock Canvas.Left="235" Canvas.Top="710" Height="51" Name="textBlock11" Width="80" TextAlignment="Center" />
            <TextBlock Canvas.Left="329" Canvas.Top="710" Height="51" Name="textBlock22" Width="80" TextAlignment="Center" />
            <Button Canvas.Left="98" Canvas.Top="697" Content="RUN" Height="71" Name="button1" Width="131" Click="button1_Click" />
            <Ellipse RenderTransformOrigin="0.5,0.5" Height="100" x:Name="Ring" Canvas.Left="117" StrokeStartLineCap="Round" StrokeEndLineCap="Square" StrokeThickness="10" Canvas.Top="607" Width="96">
                <Ellipse.RenderTransform>
                    <CompositeTransform ScaleX="0" ScaleY="0"></CompositeTransform>
                </Ellipse.RenderTransform>
                <Ellipse.Fill>
                    <RadialGradientBrush GradientOrigin="0.23,0.3">
                        <GradientStop Color="Black" Offset="1"/>
                        <GradientStop Color="White"/>
                    </RadialGradientBrush>
                </Ellipse.Fill>
            </Ellipse>
            <ProgressBar Canvas.Left="0" Canvas.Top="350" Height="1" Name="progressBar1" Width="460" Value="0" Background="White" Foreground="Red" >
            </ProgressBar>
        </Canvas>
    </Grid
>

</
phone:PhoneApplicationPage
>

MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;


namespace PhoneApp1
{
    public partial class MainPage : PhoneApplicationPage
    {
        int MyRadio = 0;

        public MainPage()
        {
            InitializeComponent();
        }
        private void backEase_Checked(object sender, RoutedEventArgs e)
        {
            //kuvatakse peidetakse vajalikud sliderid ja numbrite näitamised
            slider1.Visibility = Visibility.Visible;
            slider2.Visibility = Visibility.Collapsed;
            textBlock2.Visibility = Visibility.Collapsed;
            textBlock22.Visibility = Visibility.Collapsed;
            textBlock1.Text = "Amplituud";
            //algväärtustatakse slider
            slider1.Value = 1;
            //switchi jaoks määratud nupuvajutus
            MyRadio = 1;
        }

        private void bounceEase_Checked(object sender, RoutedEventArgs e)
        {
            slider1.Visibility = Visibility.Visible;
            slider2.Visibility = Visibility.Visible;
            textBlock2.Visibility = Visibility.Visible;
            textBlock22.Visibility = Visibility.Visible;
            textBlock1.Text = "Põrkeid";
            textBlock2.Text = "Tugevus";
            slider1.Value = 6;
            slider2.Value = 2;
            MyRadio = 2;
        }

        private void elasticEase_Checked(object sender, RoutedEventArgs e)
        {
            slider1.Visibility = Visibility.Visible;
            slider2.Visibility = Visibility.Visible;
            textBlock2.Visibility = Visibility.Visible;
            textBlock22.Visibility = Visibility.Visible;
            textBlock1.Text = "Võnkeid";
            textBlock2.Text = "Vetruvus";
            slider1.Value = 3;
            slider2.Value = 1;
            MyRadio = 3;
        }

        private void exponentialEase_Checked(object sender, RoutedEventArgs e)
        {
            slider1.Visibility = Visibility.Visible;
            slider2.Visibility = Visibility.Collapsed;
            textBlock2.Visibility = Visibility.Collapsed;
            textBlock22.Visibility = Visibility.Collapsed;
            textBlock1.Text = "Exponentsiaalsus";
            slider1.Value = 6;
            MyRadio = 4;
        }
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            switch (MyRadio)
            {
                case 1:
                    BackEase be = new BackEase();
                    be.Amplitude = Convert.ToDouble(slider1.Value);
                    be.EasingMode = EasingMode.EaseOut;
                    RectangleAnimation.EasingFunction = be;
                    RectangleAnimation1.EasingFunction = be;
                    RingAnimationX.EasingFunction = be;
                    RingAnimationY.EasingFunction = be;
                    SliderRotation1.EasingFunction = be;
                    SliderRotation2.EasingFunction = be;
                    break;
                case 2:
                    BounceEase boe = new BounceEase();
                    boe.Bounces = Convert.ToInt32(slider1.Value);
                    boe.Bounciness = Convert.ToDouble(slider2.Value);
                    boe.EasingMode = EasingMode.EaseOut;
                    RectangleAnimation.EasingFunction = boe;
                    RectangleAnimation1.EasingFunction = boe;
                    RingAnimationX.EasingFunction = boe;
                    RingAnimationY.EasingFunction = boe;
                    SliderRotation1.EasingFunction = boe;
                    SliderRotation2.EasingFunction = boe;
                    break;
                case 3:
                    ElasticEase ee = new ElasticEase();
                    ee.Oscillations = Convert.ToInt32(slider1.Value);
                    ee.Springiness = Convert.ToDouble(slider2.Value);
                    ee.EasingMode = EasingMode.EaseOut;
                    RectangleAnimation.EasingFunction = ee;
                    RectangleAnimation1.EasingFunction = ee;
                    RingAnimationX.EasingFunction = ee;
                    RingAnimationY.EasingFunction = ee;
                    SliderRotation1.EasingFunction = ee;
                    SliderRotation2.EasingFunction = ee;
                    break;
                case 4:
                    ExponentialEase xe = new ExponentialEase();
                    xe.Exponent = Convert.ToInt32(slider1.Value);
                    xe.EasingMode = EasingMode.EaseOut;
                    RectangleAnimation.EasingFunction = xe;
                    RectangleAnimation1.EasingFunction = xe;
                    RingAnimationX.EasingFunction = xe;
                    RingAnimationY.EasingFunction = xe;
                    SliderRotation1.EasingFunction = xe;
                    SliderRotation2.EasingFunction = xe;
                    break;
            }
            ProgressStoryBoard.Begin();
            myStoryboard.Begin();
            }
        private void myStoryboard_Completed(object sender, EventArgs e)
        {
            //myStoryboard.Stop();
        }

        private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            textBlock11.Text = slider1.Value.ToString("0.00");
        }

        private void slider2_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            textBlock22.Text = slider2.Value.ToString("0.00");
        }
    }
}

Windows Phone – CompositeTransform

Käesolev programminäide iseloomustab seda, kuidas lihtsal moel panna pildid liikuma CompositeTransform funktsiooni abil. Nihutades ekraanil olevaid slaidereid, liigub pilt kas üles-alla, pöörab kohapeal või venitatakse seda x-telje suunas laiemaks-kitsamaks.

CompositeTransform võimaldab järgmisi funktsioone rakendada:

·         Objekti liigutamine x või y telje suunal – TranslateX, TranslateY

·         Objekti suuruse muutmine x või y suunal – scaleX, scaleY

·         Objekti pööramine – Rotation

·         Objekti kuju muutmine – SkewX, SkewY

CompositeTransform kohta leiab siit MSDN artiklist lugemist: http://msdn.microsoft.com/en-us/library/system.windows.media.compositetransform(v=vs.95).aspx 

Vaata videost mida alltoodud rakendus teeb.

Windows Phone Composite Transform

MainPage.xaml

<phone:PhoneApplicationPage
   x:Class="Phone_Liikuvad_pildid.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
   xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
   FontFamily="{StaticResource PhoneFontFamilyNormal}"
   FontSize="{StaticResource PhoneFontSizeNormal}"
   Foreground="{StaticResource PhoneForegroundBrush}"
   SupportedOrientations="Portrait" Orientation="Portrait"
   shell:SystemTray.IsVisible="True">

    <Grid x:Name="LayoutRoot" Background="{StaticResource PhoneBackgroundBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Slider Height="84" HorizontalAlignment="Left" Margin="12,6,0,0" Name="slider1" VerticalAlignment="Top" Width="438" ValueChanged="slider1_ValueChanged" Minimum="0" Maximum="3" SmallChange="0.5" />
            <Slider Height="84" HorizontalAlignment="Left" Margin="12,96,0,0" Name="slider2" VerticalAlignment="Top" Width="438" ValueChanged="slider2_ValueChanged" Maximum="720" />
            <Slider Height="594" HorizontalAlignment="Left" Margin="12,124,0,0" Name="slider3" VerticalAlignment="Top" Width="67" ValueChanged="slider3_ValueChanged" Orientation="Vertical" Maximum="400" />
            <Image HorizontalAlignment="Left" Margin="125,556,0,0" Name="MSlogoPilt" Stretch="Fill" VerticalAlignment="Top" Source="/Phone%20Liikuvad%20pildid;component/MSLogo.jpg" RenderTransformOrigin="0.5,0.5" Height="162" Width="236" />
        </Grid>
    </Grid
>

</
phone:PhoneApplicationPage
>

MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

namespace Phone_Liikuvad_pildid
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();
            //antakse slideritele algväärtused
            slider1.Value = 1;
            slider3.Value = 200;
        }
        private void MoveImage() {
            //loetakse slideritest info
            double scaleX = slider1.Value;
            double Rotation = slider2.Value;
            double TranslateY = slider3.Value;

            //luuakse CompositeTransform objekt
            CompositeTransform ct = new CompositeTransform();

            //antakse loodud objektile edasi omadused
            ct.ScaleX = scaleX;
            ct.TranslateY = -TranslateY;
            ct.Rotation = Rotation;

            //rakendatakse omadused pildi peal
            MSlogoPilt.RenderTransform = ct;
        }

        private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            MoveImage();
        }

        private void slider2_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            MoveImage();
        }

        private void slider3_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            MoveImage();
        }
    }
}

Windows Phone – Hello World! + Storyboard

See on esimene tunnis tehtud Windows Phone programm. Esimesele nupule vajutades trükitakse ekraanil olevasse tekstilahtrisse „Hello World!“ ning teise nupu vajutuse peale pannakse see textbox liikuma.

Liikumise trajektoor ja muud omadused sätiti paika visuaalselt, Expression Blend’i vahendusel, seetõttu siis ka selline kogukas xaml-kood.

Vaata kõigepealt videost mida see rakendus teeb.

Windows Phone–Hello World! ja Storyboard

MainPage.xaml

<phone:PhoneApplicationPage
   x:Class="StoryBoardTest.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
   xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
   FontFamily="{StaticResource PhoneFontFamilyNormal}"
   FontSize="{StaticResource PhoneFontSizeNormal}"
   Foreground="{StaticResource PhoneForegroundBrush}"
   SupportedOrientations="Portrait" Orientation="Portrait"
   shell:SystemTray.IsVisible="True">
    <phone:PhoneApplicationPage.Resources>
        <Storyboard x:Name="Storyboard1" AutoReverse="True" RepeatBehavior="2x">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="textBox1">
                <EasingDoubleKeyFrame KeyTime="0" Value="312"/>
                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="114"/>
                <EasingDoubleKeyFrame KeyTime="0:0:2" Value="114"/>
                <EasingDoubleKeyFrame KeyTime="0:0:2.9" Value="-31.5"/>
                <EasingDoubleKeyFrame KeyTime="0:0:3.9" Value="-31.5"/>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="textBox1">
                <EasingDoubleKeyFrame KeyTime="0" Value="13.5"/>
                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="9"/>
                <EasingDoubleKeyFrame KeyTime="0:0:2" Value="9"/>
                <EasingDoubleKeyFrame KeyTime="0:0:2.9" Value="6"/>
                <EasingDoubleKeyFrame KeyTime="0:0:3.9" Value="6"/>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="textBox1">
                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:2" Value="180.039"/>
                <EasingDoubleKeyFrame KeyTime="0:0:2.9" Value="359.93"/>
                <EasingDoubleKeyFrame KeyTime="0:0:3.9" Value="359.93"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </phone:PhoneApplicationPage.Resources>

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="Storyboard test" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="Hello World!" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Button Content="Hello World!" Height="72" HorizontalAlignment="Right" Margin="0,44,48,0" Name="button1" VerticalAlignment="Top" Width="234" Click="KirjutaHello_Click" />
            <TextBox Height="82" HorizontalAlignment="Left" Margin="34,171,0,0" Name="textBox1" VerticalAlignment="Top" Width="374" RenderTransformOrigin="0.5,0.5" >
                <TextBox.RenderTransform>
                    <CompositeTransform/>
                </TextBox.RenderTransform>
            </TextBox>
            <Button Content="Käivita" Height="72" HorizontalAlignment="Left" Margin="248,429,0,0" Name="button2" VerticalAlignment="Top" Width="160" Click="button2_Click" />
        </Grid>
    </Grid
>

</
phone:PhoneApplicationPage
>

MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

namespace StoryBoardTest
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }
        private void KirjutaHello_Click(object sender, RoutedEventArgs e)
        {
            textBox1.Text = "Hello World!";
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            Storyboard1.Begin();
        }
    }
}