Makale Özeti

Önceden hazırlanmış animasyonların Silverlight ile kullanımı mümkün olduğu gibi JavaScript kodları ile dinamik olarak animasyonlar yaratmak da mümkün. Bu makalemizde dinamik animasyonlar yaratmanın yollarını inceleyeceğiz.

Makale

Silverlight uygulamalarında bazı durumlarda animasyonları dinamik olarak yaratmak gerekebilir. Bu durum genelde söz konusu animasyonla ilgili bazı değerlerin önceden bilinmemesinden kaynaklanır. Örneğin dinamik olarak yarattığınız bir Silverlight nesnesine bağlı bir animasyon hazırlamak isteyebilirsiniz, fakat hedef nesnenin özellikleri belli olmadığı için animasyonu da yaratmanız mümkün olmayacaktır veya animasyonla ilgili bazı değerleri AJAX ile sunucu tarafından alıyor olabilirsiniz. Bu gibi durumlarda dinamik animasyon yaratabiliyor olmak hayati öneme sahip.

Silverlight içerisinde dinamik nesneler yaratırken createFromXaml adında bir metod kullanıyoruz, aynı şekilde dinamil animasyonlar (Storyboard) yaratırken de yine createFromXaml metodunu kullanıyor olacağız. createFromXaml metodu yapısı gereği tek bir parametre alıyor, söz konusu parametre yaratılacak olan nesnenin veya animasyonun XAML kodu. Animasyon tarafına tam olarak geçmeden önce gelin aşağıdaki şekilde bir Silverlight projesi yaratalım.

<Canvas

  xmlns="http://schemas.microsoft.com/client/2007"

  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

  Width="300" Height="300"

  Background="White"

  x:Name="Page"

  MouseLeftButtonDown="Tiklandi"

  >

  <Ellipse Width="45" Height="45" Fill="#FFFF0000" Canvas.Left="22" Canvas.Top="27" x:Name="Top" RenderTransformOrigin="0.5,0.5">

    <Ellipse.RenderTransform>

      <TransformGroup>

        <ScaleTransform ScaleX="1" ScaleY="1"/>

        <SkewTransform AngleX="0" AngleY="0"/>

        <RotateTransform Angle="0"/>

        <TranslateTransform X="0" Y="0"/>

      </TransformGroup>

    </Ellipse.RenderTransform>

  </Ellipse>

</Canvas>

Yukarıdaki Silverlight uygulamamız içerisinde adını Top koyduğumuz bir Ellipse nesnesi yer alıyor. Ayrıca Silverlight uygulamamızın ana öğesi olan root Canvas'ın da MouseLeftButtonDown durumuna bir event handler bağlamış durumdayız. Birazdan Tiklandi adındaki JavaScript fonksiyonumuzu yazmaya başlayacağız.

Uygulamamızda amacımız Silverlight içerisinde kullanıcı her nereye tıklarsa tıklasın topun hoş bir animasyon ile o noktaya gitmesini sağlamak. Bunun için tabi ki her animasyon (StoryBoard) nesneleri yaratmamız gerekecek fakat bu animasyonların özellikleri şu anda belli değil çünkü kullanıcının sahnede nereye tıklayacağını bilmiyoruz. O nedenle animasyonları dinamik olarak tıklama anında yaratarak çalıştırmamız gerekecek. Yaratacağımız animasyonların şablonu aşağıdaki gibi olmalı.

    <Storyboard x:Name="Storyboard1">

      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Top" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">

        <SplineDoubleKeyFrame KeyTime="00:00:01" Value="185"/>

      </DoubleAnimationUsingKeyFrames>

      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Top" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">

        <SplineDoubleKeyFrame KeyTime="00:00:01" Value="200"/>

      </DoubleAnimationUsingKeyFrames>

    </Storyboard>

Yukarıdaki kod içerisinde Top nesnemizin sahnedeki yerini değiştiriyoruz. Bu animasyonu hızlı bir şekilde Blend ile yaratarak örnek XAML kodunu kopyaladık. Animasyon içerisinde özellikle koyu yazılan yerlerdeki Value değerlerine dikkat etmekte fayda var. Bu değerlerin Top'un gideceği hedef X ve Y koordinatları. Şimdi geçip yavaş yavaş Tiklandi JavaScript fonksiyonumuzu yazmaya başlayalım.

function Tiklandi(sender, args)

{

    var TiklananYer = args.getPosition(null);

    var AnimXAML = '<Storyboard xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="Storyboard' + TiklananYer.X.toString() + TiklananYer.Y.toString() + '"><DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Top" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"><SplineDoubleKeyFrame KeyTime="00:00:01" Value="' + (TiklananYer.X - sender.findName("Top").width) + '"/></DoubleAnimationUsingKeyFrames><DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Top" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)"><SplineDoubleKeyFrame KeyTime="00:00:01" Value="' + (TiklananYer.Y - sender.findName("Top").height) + '"/></DoubleAnimationUsingKeyFrames></Storyboard>';

    var Anim = sender.getHost().content.createFromXaml(AnimXAML);

    sender.resources.Add(Anim);

    Anim.Begin();

}

Yukarıdaki fonksiyon istediğimiz işlemi tamamlamamız için yeterli. Gelin bu fonksiyon içerisinde neler yaptığımıza bir bakalım. Birinci satırda hemen TiklananYer adındaki bir değişkene fare ile tıklanan noktanın koordinatlarını kaydediyoruz. Bunun için Tiklandi fonksiyonumuza gelen ikinci parametre olan args üzerinden getPosition metodunu kullanıyoruz. Bir sonraki adımda sıra geldi yaratacağımız animasyonun XAML kodunu hazırlamaya.

AnimXAML adında bir değişkene Blend içerisinde hazırladığımız XAML metnini aktarıyoruz. Fakat bunu yaparken metin içerisindeki bazı şeyleri de JavaScript ile atamamız gerekiyor. Örneğin hem X hem de Y yönünde gidilmesi hedeflenen noktanın koordinatlarını TiklananYer değişkenimizden alarak XAML içerisine yerleştiriyoruz. Top nesnemizin tam olarak tıklanan noktayı ortalayabilmesi için fareden gelen koordinatların topun yüksekliğini veya genişliğini çıkartmayı da unutmamamız gerek. XAML kodu içerisinde değiştirdiğimiz bir diğer özellik de StoryBoard nesnesinin adı. Her tıklama işleminde yeni bir StoryBoard yaratıp Silverlight animasyonumuza ekleyeceğimiz için farklı isimler vermemiz gerekecek. Aynı isimde birden çok StoryBoard ekleyemeyiz. Bunun için biz örneğimizde X ve Y koordinatlarını metin olarak StoryBoard adının sonuna ekledik. Kullanıcının aynı noktaya tıklamayacağını ümit ediyoruz :) İsterseniz siz söz konusu animasyonun var olup olmadığını kontrol ederek daha sağlıklı bir işleyiş de sağlayabilirsiniz. Animasyon varsa yaratmadan doğrudan çalıştırabilirsiniz.

createFromXaml metodu ile hazırlamış olduğumuz XAML kodundan StoryBoard nesnemizi yarattırarak Anim adında bir değişkene aktarıyoruz. Artık sıra geldi bu animasyonu Silverlight sayfamızın kaynaklarına (resource) eklemek. O işlemi de tamamladıktan sonra artık animasyonumuzu çalıştırabiliriz.

Uygulamayı çalıştırdığınızda Silverlight içerisinde nereye tıklarsanız tıklayın topun son tıklanan yere doğru hareket ettiğini göreceksiniz. Eğer top tıkladığınız noktaya ulaşmadan başka bir yere tıklarsanız yönünü değiştirerek oraya doğru geldiğini de görebilirsiniz. Bunun nedeni böyle bir durumda iki farklı animasyonun yaratılarak çalıştırılıyor olması. Son biten animasyon son başlatılan olacağı için top en sonunda kendisini son tıklanan noktada bulacaktır.

Hepinize kolay gelsin.

Daron Yöndem
MCT, MCPD, MCITP, MCTS, MCSD, MCAD
MCDBA, MCP, ACP, ICSD, IEL'03
http://daron.yondem.com