Makale Özeti

Silverlight animasyonlarındaki nesneleri fare ile tutup sürükle&bırak tekniği ile taşımanın yanı sıra isterseniz fare ile tuarak herhangi bir nesneyi kendi etrafında çevirebilirsiniz. Bunun için biraz ortaokul matematik bilgisi ile JavaScript'i birleştirdiğimiz makalemizi inceleyebilirsiniz.

Makale

Silverlight içerisinde fare ile nesneler arasında bir etkileşim kurmak için JavaScript ile çok farklı kodlar yazılabilir. Bu makalede herhangi bir nesneyi fare ile tutarak sahnede kendi etrafında çevirmeyi deneyeceğiz. Bunun için hemen yeni bir Silverlight animasyonu yaratıyoruz ve içerisinde örnek olması amacıyla ufak bir resim yerleştiriyoruz. Image nesnesinin adını Foto olarak verdikten sonra Image tagları arasına aşağıdaki şekliyle RotateTransform nesnesi yerleştirmemiz gerekiyor.

<Canvas

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

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

  Width="400" Height="400"

  Background="White"

  x:Name="Page"

  >

  <Image Width="185" Height="184" Canvas.Left="110" Canvas.Top="103" Source="image[1].jpg" x:Name="Foto" RenderTransformOrigin="0.5,0.5">

    <Image.RenderTransform>

      <TransformGroup>

        <RotateTransform x:Name="FotoAci" Angle="0"/>

      </TransformGroup>

    </Image.RenderTransform>

  </Image>

</Canvas>

Yukarıdaki kod içerisinde özellikle dikkat etmemiz gereken iki nokta var. Bunlardan ilki Image nesnemizin adının Foto olması, ikincisi ise aynı şekilde Foto'ya ait RotateTransform nesnesine de FotoAci ismini vermiş olmamış. Bu isimler üzerinden söz konusu nesnelere ulaşıyor olacağız.

Kullanıcılar fotoğrafımıza tıklayarak döndürme işlemini başlatabilsinler. Yani Foto nesnesinin MouseLeftButtonDown durumunu kontrol etmeliyiz. Aynı şekilde döndürme işlemini bitirebilmek için MouseLeftButtonUp durumunu da kontrol etmemiz gerekecek. Fakat bunların haricinde fare ile döndürme işlemi yapılırken kullanıcı Foto nesnesinin dışına da çıkabilir. Bu durumda döndürmenin devam edebilmesi için tüm sahnedeki MouseMouve durumunu kontrol etmemiz gerekecek. Ayrıca döndürme işlemine fotoğrafın üzerinde başlayıp dışarıda sonlandırılabilir. Özetle aşağıdaki şekilde dört farklı durumu kontrol etmemiz gerekiyor.

<Canvas

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

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

  Width="400" Height="400"

  Background="White"

  x:Name="Page"

  MouseMove="FareHareketli"

  MouseLeftButtonUp="FareGitti"

  >

  <Image MouseLeftButtonDown="FareGeldi" MouseLeftButtonUp="FareGitti" Width="185" Height="184" Canvas.Left="110" Canvas.Top="103" Source="image[1].jpg" x:Name="Foto" RenderTransformOrigin="0.5,0.5">

    <Image.RenderTransform>

      <TransformGroup>

        <RotateTransform x:Name="FotoAci" Angle="0"/>

      </TransformGroup>

    </Image.RenderTransform>

  </Image>

</Canvas>

Şimdi sıra geldi gerekli JavaScript kodlarını yazmaya. Doğruda projemizin Page.xaml.js dosyasına yöneliyoruz. İlk olarak FareGeldi fonksiyonunu yazalım.

var FareBasili;

var SonDurum;

 

function FareGeldi(sender, args)

{

    //Global fare takibini başlat

    sender.captureMouse();

    //Tuşa BASILDI!! :)

    FareBasili = true;

    // Durumu bir kenara kaydet

    SonDurum = args.getPosition(null);

}

Yukarıdaki kodun öncesinde iki adet global değişken tanımlıyoruz. Bu değişkenlerden biri farenin tuşunun basılı olup olmadığı kontrol edecek. Böylece MouseMove durumunda gerekli işlemlerin yapılıp, yapılmamasını sağlayacağız. Diğer değişken ise fare imlecinin pozisyonunu bir kenara kaydediyor, ileride kullanıyor olacağız.

Sıra geldi nesneyi çevirme işlemine, yani FareHareketli JavaScript fonksiyonunu yazmaya.

function FareHareketli(sender,args)

{

    var GuncelDurum = args.getPosition(null);

 

    // Fareye basılı mı??

    if (FareBasili)

    {   

        var AciNesnesi = sender.findName("FotoAci");

 

       // Nesnenin merkez noktasının global

       //koordinatlarını bulalım.

        var Merkez = {};     

        Merkez.X = sender.findName("Foto")["Canvas.Left"] + sender.findName("Foto").width/2;

        Merkez.Y = sender.findName("Foto")["Canvas.Top"] + sender.findName("Foto").height/2;

 

        // Çeviri işlemi

        var SonAci = parseInt(Math.atan2(SonDurum.Y - Merkez.Y, SonDurum.X - Merkez.X) * 360 / (2 * Math.PI));

        var GuncelAci = parseInt(Math.atan2(GuncelDurum.Y - Merkez.Y, GuncelDurum.X - Merkez.X) * 360 / (2 * Math.PI));

        AciNesnesi.Angle += GuncelAci-SonAci;

 

        // Son durumu tekrar sakla.

        SonDurum = GuncelDurum;

    }

}

Yukarıdaki kod sizi korkutmasın. Aslında epey basit bir işlemden bahsediyoruz. İlk satırda farenin güncel koordinatlarını alıyoruz sonrasında da fareye basılı mı yoksa değil mi kontrolünü yapmak için kendi FareBasili değişkenimize danışıyoruz. Eğer farenin düğmesine basılmış ise döndürme işlemini yapmamız gerekecek.

Döndürme işlemini yaptıktan sonra hesapladığımız yeni açı değerini adını FotoAci koyduğumuz RotateTransform nesnesine aktarmamız gerekecek. O nedenle baştan nesnemizi AciNesnesi adında bir değişkene aktarıyoruz. Sıra geldi hesaplamalara; kullanacağımız teknik farenin sahnedeki konumu ile çevirmek istediğimiz nesnenin merkez noktası arasında bir doğru çizerek bu döğrunun X aksına açısını almak olacak. Bu nedenle ilk olarak nesnenin merkezinin global koordinatlarını buluyoruz. Sonrasında açı hesaplama işlemlerini yaparken ilk olarak bir önceki durumdaki, yani bizim SonDurum değişkenine kaydettiğimiz durumdaki açıyı hesaplıyoruz sonra da şu anki durumdaki açıyı hesaplıyoruz. Açı hesaplama için standart JavaScript fonksiyonları kullanıyoruz. Kullandığımız esas fonksiyon olan Math.atan2 geriye Radiant döndürdüğü için onu da dereceye çeviriyoruz.

Son olarak önceki ile sonraki açı arasındaki farkı alarak RotateTransform nesnesinin açısına ekliyoruz. SonDurum değişkenini de güncelledikten sonra işimiz bitiyor.

İşimiz bitiyor derken sadece FareHareketli fonksiyonundan bahsediyordum. Tabi ki daha FareGitti fonksiyonunu da yazmamız lazım.

function FareGitti(sender,args)

{

    FareBasili = false;

    sender.releaseMouseCapture();

}

Gördüğünüz gibi FareGitti kısmı belki de işin en kolay kısmı. Global FareBasili değişkenimizi false yaptıktan sonra global fare yakalamayı da kapatıyoruz.

Artık projemizi çalıştırabiliriz. Foto nesnemizi faremiz ile istediğimiz gibi döndürebiliyoruz.

Hepinize kolay gelsin.

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