Silverlight 2.0 içerisinde MultiScaleImage kullanımı ve DeepZoom maceraları

0 dakikada yazıldı

6561 defa okundu

Düzenle

Silverlight 2.0 ile beraber gelen kontrollerden biri de
MultiScaleImage kontrolü. Bu kontrolün yapabildikleri arasında
gerçekten çok ilginç uygulamalar var. Genel itibari ile çok büyük
boyutta resimlerin istemci tarafında bant genişliğinin en uygun
performans ile kullılarak gösterilmesini sağladığını söyleyebiliriz.
Örneğin elinizde çok yüksek çözünürlükte 2GB'lık bir fotoğraf var ve bu
fotoğrafı istemci tarafında göstermek istiyorsunuz veya elinizde toplam
3GB'lık bir fotoğraf arşivi var ve bunu güzel bir Silverlight galerisi
şeklinde kullanıcılarla paylaşmak istiyorsunuz. Fakat uygulamanın
çalışırken doğal olarak tüm resimleri yüklememesi hatta sadece o an
ekranda gözüken kısımları yüklemesi gerekiyor. Tüm bunları elle tek tek
kodlayarak yapabiliriz fakat MultiScaleImage varken aslında herşey
çok daha kolay ilerliyor.

Deep Zoom Composer

MultiScaleImage kontrolü içerisinde gösterilecek resimlerin farklı
detaylarda gösterilebilmesi ve kullanıcı resme zoom yaptıkça yeni
detayların yüklenerek ekranda gösterilebilmesi için arkaplanda
resimlerin biraz detaylı bir yapıda hazırlanmış olması gerekiyor. Bu
işlemleri otomatik olarak yapabilecek bir uygulama olan Deep Zoom
Composer'ı aşağıdaki adresten bilgisayarınıza indirip kurabilirsiniz.

http://www.microsoft.com/downloads/details.aspx?FamilyID=457b17b7-52bf-4bda-87a3-fa8a4673f8bf&DisplayLang=en

Yüklemeyi yapıp yeni bir DeepZoom projesi yarattığınızda programın
arayüzündeki "Add Image" düğmesi ile projeye istediğiniz kadar resim
ekleyebilirsiniz. Eklediğiniz bu resimleri "Compose" sekmesinde sahneye
sürükleyerek istediğiniz şekilde resimleri iç içe veya üst üste
koyabilirsiniz. Resimleri ufaltabilir veya büyütebilirsiniz. Unutmayın
ki burada bir resmi diğerine göre çok ufak yerleştirseniz de kullanıcı
birazdan hazırlayacağımız uygulamada zoom yaparak tüm detayları
görebilecek. Yani bir insan resmi koyup gözünün içine de ufacık
görünecek şekilde aslında 5MB'lık kocaman bir fotoğraf
yerleştirebilirsiniz. Kullanıcı resmi ilk açtığında bu fotoğraf insanın
gözünün içinde ufacık olduğu için tamamen yüklenmeyecek ve sadece
gözüktüğü kadarı istemciye gönderilecektir. Oysa kullanıcı zoom yaparak
gözün içine girip büyük fotoğrafı görmeye başladığında ise detaylar
yüklenerek fotoğrafınız tüm çözünürlüğü ile net bir şekilde
gözükecektir. DeepZoom Composer'ın kullanımı ile ilgili detaylı bilgiyi
sevgili Turhal Temizer'in
yazısından

edinebilirsiniz.

DeepZoom Composer içerisinde fotoğraflarımız.
DeepZoom Composer içerisinde fotoğraflarımız.

Biz uygulamamızda yukarıdaki gibi fotoğrafları sahneye ekleyip sağ tuş
ile gelen menüden de tüm fotoğrafları "Arrange to Grid" diyerek bir
tablo içerisindeymiş gibi hizalatalım. Böylece tüm fotoğraflar yan yana
ve alt alta sıralanacaktır. Daha önce de bahsettiğim gibi isterseniz
fotoğrafları üst üste yerleştirme ve farklı tasarımlar yapma şansınız da
var. Örneğin bir mekanın duvarındaki reklamı ayrı bir detaylı fotoğraf
olarak koyabilirsiniz. Böylece kullanıcı mekan fotoğrafındaki duvarda
yer alan reklama zoom yaptığında aslında daha detaylı farklı bir görsel
yüklenmeye başlayacak ve normalde elde edilemeyen bir detay gösterimi
yapılabilecektir.

Son olarak DeepZoom Composer içerisinde "Export" bölümüne geçerek
artık fotoğraflarımızın gerekli çıktılarını almak istiyoruz. Export
esnasında özellikle "Output Type" olarak "Export Images"
seçeneğini işaretlemeyi unutmayın. Normalde DeepZoomComposer isterseniz
size hazır bir Silverlight projesi de yaratabiliyor fakat bu yazımızda
biz kendi uygulamamızı hazırlayacağımız için sadece fotoğrafların
düzenlenerek gerekli arşivin oluşturulmasını istiyoruz.

DeepZoom Composer arşivimiz.
DeepZoom Composer arşivimiz.

Yukarıda da gördüğünüz üzere gerekli dosyalar bizim için hazırlanmış.
Buradaki XML dosyalarını tek tek inceleyebilirsiniz. Aslında her bir
dosya ayrı birer XML dosyasına yönlendiriyor bizi. Arşive eklediğimiz
her resim için ayrıca birer XML dosyası yaratılıyor ve bu dosyalar
içerisinde resimlerle ilgili konum bilgisi gibi detaylar yer alıyor.
Ayrıca her resmimizin farklı boyutlarda kopyaları da klasörler içerisine
kopyalanmış durumda. Hatta çok büyük resimler parçalara bölünerek ayrı
ayrı dosyalar olarak da kaydedilmiş. MultiScaleImage kontrolünün de
gücü zaten buradan geliyor. Kaynaktaki farklı boyuttaki ve parçalardaki
fotoğrafları gerçek zamanlı olarak birleştirebiliyor ve otomatik olarak
ekranda gözüken detaya uygun hedef dosyaları istemciye yüklüyor. Tüm
geçiş efektlerini de tabi ki otomatik olarak yapıyor. Peki artık kaynak
dosyalarımız hazır olduğuna göre uygulamamızı da hazırlamaya başlayalım.

Silverlight projemizi yaratalım...

Yeni bir Silverlight projesi yaratarak hemen içerisine bir
MultiScaleImage kontrolü yerleştiriyoruz. Şimdilik tasarım anlamında
farklı birşey yapmayacağız. Uygulamamızın XAML kodu aşağıdaki gibi basit
bir şekilde sonlanıyor.

<UserControl
x
:Class="SilverlightApplication6.Page"

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

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

   Width="1024"
Height
="768">

    <Grid
x
:Name="LayoutRoot"
Background
="White">

        <MultiScaleImage x:Name="DeepZoom"/>

    </Grid>

</UserControl>

DeepZoom adını verdiğim MultiScaleImage kontrolümüzü programlamaya
başlayacağız. İlk olarak yapmak istediğimiz işlemleri bir sıralayalım;

Listemizdeki tek tek yaparak ilerleyelim. İlk olarak fotoğraf arşivimizi
doğrudan kontrolümüze bağlayalım.

[VB]

        DeepZoom.Source = New
DeepZoomImageTileSource(New Uri("GeneratedImages/dzc_output.xml",
UriKind.Relative))

[C#]

            DeepZoom.Source = new
DeepZoomImageTileSource(new Uri("GeneratedImages/dzc_output.xml", UriKind.Relative));

Gördüğünüz üzere doğrudan DeepZoom kontrolümün Source özelliğini
değiştiriyorum ve yarattığımız yeni bir DeepZoomImageTileSource
nesnesini kendisine atıyoruz. Bu esnada bir önceki adımda DeepZoom
Composer'ın bizim için yarattığı arşivden dzc_output.xml dosyasını
kaynak olarak gösteriyoruz. DeepZoom Composer'ın yarattığı
GeneratedImages klasörünü doğru olarak çalışabilmesi için XAP
dosyanız ile aynı konuma kopyalamanız gerekecektir.

Fotoğraf arşivini gezelim.

Sıra geldi fare ile fotoğrafların arasındaki gezintimize başlamaya.
Aslında yapacağımız işlem klasik bir Sürükle&Bırak işleminden farklı
değil. Fakat bu sefer sürükleyip bıraktıracağımız şey aslında
MultiScaleImage kontrolünün ViewPortOrigin'i. Yani bizim bu
arşive MultiScaleImage aracılığı ile bakış noktamızı değiştreceğiz.

[VB]

    Dim Tasiniyor = False

    Dim FareKonum As Point

    Dim DeepZoomOrigin As Point

[C#]

        bool Tasiniyor = false;

        Point FareKonum;

        Point DeepZoomOrigin;

Sürükle ve bırak işlemi öncesinde ihtiyacımız olacak global
değişkenlerimizi yukarıdaki gibi yaratalım. Sonrasında toplam üç farklı
event için kod yazmamız gerekiyor. MouseLeftButtonDown,
MouseMove ve MouseLeftButtonUp durumlarında sürükleme işlemini
başlatıp durdurmaya karar vereceğiz.

[VB]

    Private Sub Page_MouseLeftButtonDown(ByVal sender As Object,
ByVal e As
System.Windows.Input.MouseButtonEventArgs) Handles Me.MouseLeftButtonDown

        Tasiniyor = True

        FareKonum = e.GetPosition(Me)

        DeepZoomOrigin = DeepZoom.ViewportOrigin

    End Sub

[C#]

        void
Page_MouseLeftButtonDown(object
sender, MouseButtonEventArgs e)

        {

            Tasiniyor = true;

            FareKonum = e.GetPosition(this);

            DeepZoomOrigin = DeepZoom.ViewportOrigin;

        }

Kullanıcı fare ile sahneye tıkladığında hemen taşınma işlemini
başlattığımız için global Tasiniyor değişkenini True yapıyoruz.
Böylece ileride yazacağımız MouseMove kodu durumdan haberdar
olabilecek. Bir sonraki adımda farenin pozisyonunu ve sonrasında da
DeepZoom kontrolünün o anki orijin noktasını kenara not alıyoruz. Bu
bilgileri ileriki hesaplamalarımızda kullanacağız.

[VB]

    Private Sub Page_MouseMove(ByVal sender As Object,
ByVal e As System.Windows.Input.MouseEventArgs)
Handles Me.MouseMove

        If Tasiniyor Then

            Dim YeniDeepZoomOrigin
As New Point

            YeniDeepZoomOrigin.X = DeepZoomOrigin.X -
(((e.GetPosition(DeepZoom).X - FareKonum.X) / DeepZoom.ActualWidth) *
DeepZoom.ViewportWidth)

            YeniDeepZoomOrigin.Y = DeepZoomOrigin.Y -
(((e.GetPosition(DeepZoom).Y - FareKonum.Y) / DeepZoom.ActualHeight) *
DeepZoom.ViewportWidth)

            DeepZoom.ViewportOrigin = YeniDeepZoomOrigin

        Else

            FareKonum = e.GetPosition(Me)

        End If

    End Sub

[C#]

        void Page_MouseMove(object sender, MouseEventArgs e)

        {

            if (Tasiniyor)

            {

                Point
YeniDeepZoomOrigin = new Point();

                YeniDeepZoomOrigin.X = DeepZoomOrigin.X -
(((e.GetPosition(DeepZoom).X - FareKonum.X) / DeepZoom.ActualWidth) *
DeepZoom.ViewportWidth);

                YeniDeepZoomOrigin.Y = DeepZoomOrigin.Y -
(((e.GetPosition(DeepZoom).Y - FareKonum.Y) / DeepZoom.ActualHeight) *
DeepZoom.ViewportWidth);

                DeepZoom.ViewportOrigin = YeniDeepZoomOrigin;

            }

            else

            {

                FareKonum = e.GetPosition(this);

            }

        }

Sahnenin MouseMove durumunda ilk olarak bir taşıma işlemi olup
olmadığını kontrol ediyoruz. Eğer taşıma işlemi yoksa FareKonum
adındaki ve farenin mevcut konumunu saklayan değişkeni yeniliyoruz. Bunu
yapmamızın nedeni ileride yazacağımız zoom işlemleri. Zoom işlemini
yaparken farenin konumuna hep ihtiyacımız olacak. Burada sürekli güncel
konumu FareKonum'a aktarmak gerekiyor. Eğer taşıma işlemi
yapılıyorsa bu sefer de DeepZoom kontrolümüzün ViewPortOrigin'ini uygun
şekilde ayarlamamız gerek. Bu amaçla kodumuzda yeni bir Point
değişkeni tanımlayarak farenin mevcut konumu, eski konumu ve eski orijin
noktası arasında koordinat hesaplamaları yaparak ilerliyoruz.

[VB]

    Private Sub Page_MouseLeftButtonUp(ByVal sender As Object,
ByVal e As
System.Windows.Input.MouseButtonEventArgs) Handles Me.MouseLeftButtonUp

        Tasiniyor = False

    End Sub

[C#]

        void
Page_MouseLeftButtonUp(object sender,
MouseButtonEventArgs e)

        {

            Tasiniyor = false;

        }

Son olarak farenin sol tuşu bırakıldığında da taşıma işlemini
sonlandırıyoruz. Böylece artık fotoğraf arşivi içerisinde kullanıcılar
rahatlıkla gezebilecektir. Sıra geldi zoom meselesine.

Fare ile Zoom-In ve Zoom-Out

Fare ile zoom işlemleri için farenin roller'ını kullanacağız. Detaylar
için Silverlight 2.0 içerisinde fare roller'ı kullanmayla ilgili
buradaki
makleyi inceleyebilirsiniz. İlk olarak DOM üzerinden gerekli eventları
Silverlight ile yakalamamız gerekiyor.

[VB]

        System.Windows.Browser.HtmlPage.Window.AttachEvent("DOMMouseScroll", AddressOf FareTekerlekDondu)

        System.Windows.Browser.HtmlPage.Window.AttachEvent("onmousewheel", AddressOf FareTekerlekDondu)

        System.Windows.Browser.HtmlPage.Document.AttachEvent("onmousewheel", AddressOf FareTekerlekDondu)

[C#]

            System.Windows.Browser.HtmlPage.Window.AttachEvent("DOMMouseScroll", FareTekerlekDondu);

            System.Windows.Browser.HtmlPage.Window.AttachEvent("onmousewheel", FareTekerlekDondu);

            System.Windows.Browser.HtmlPage.Document.AttachEvent("onmousewheel", FareTekerlekDondu);

FareTekerlekDondu eventı içerisinde aşağıda kodları yazmamız
gerekiyor. Bu kodların çok detayına inmeyeceğiz çünkü bir önceki
paragrafta bahsettiğim makalede zaten bu konu detayları ile inceleniyor.
Bizim için bu kodda önemli olan kısım Zoom işleminin yapıldığı satırlar.

[VB]

    Private Sub FareTekerlekDondu(ByVal sender As Object,
ByVal e As System.Windows.Browser.HtmlEventArgs)

        Dim DonMiktar As Integer
= 0

        Dim Gelen As System.Windows.Browser.ScriptObject =
e.EventObject

        'IE ve OPERA

        If Not Gelen.GetProperty("wheelDelta") Is Nothing
Then

            'OPERA'da ters!

            If Not Gelen.GetProperty("opera") Is Nothing
Then

                DonMiktar = -DonMiktar

            End If

            DonMiktar = Gelen.GetProperty("wheelDelta")

            'Mozilla ve Safari

        ElseIf Not Gelen.GetProperty("detail") Is Nothing
Then

            DonMiktar = -Gelen.GetProperty("detail")

        End If

        If DonMiktar > 0 Then

            'Zoom yap

**           ** Dim
ZoomlananNokta As Point =
DeepZoom.ElementToLogicalPoint(FareKonum)

**            DeepZoom.ZoomAboutLogicalPoint(2, ZoomlananNokta.X,
ZoomlananNokta.Y)**

        Else

            'Uzaklaş

      **     ** Dim
ZoomlananNokta As Point =
DeepZoom.ElementToLogicalPoint(FareKonum)

**            DeepZoom.ZoomAboutLogicalPoint(0.5, ZoomlananNokta.X,
ZoomlananNokta.Y)**

        End If

 

        If DonMiktar <> 0 Then

            e.PreventDefault()

            Gelen.SetProperty("returnValue", False)

        End If

    End Sub

[C#]

        private void FareTekerlekDondu(object sender, System.Windows.Browser.HtmlEventArgs e)

        {

            int DonMiktar = 0;

            System.Windows.Browser.ScriptObject Gelen = e.EventObject;

            //IE ve OPERA

            if
((Gelen.GetProperty("wheelDelta")
!= null)) {

                //OPERA'da ters!

                if
((Gelen.GetProperty("opera") !=
null)) {

                    DonMiktar = -DonMiktar;

                }

                DonMiktar = (int)Gelen.GetProperty("wheelDelta");

            }

            //Mozilla ve Safari

            else if ((Gelen.GetProperty("detail") != null)) {

                DonMiktar = -1 * (int)Gelen.GetProperty("detail");

            }

            if (DonMiktar > 0) {

                //Zoom yap

**               ** Point
ZoomlananNokta = DeepZoom.ElementToLogicalPoint(FareKonum);

**                DeepZoom.ZoomAboutLogicalPoint(2, ZoomlananNokta.X,
ZoomlananNokta.Y);**

            }

            else {

                //Uzaklaş

**               ** Point
ZoomlananNokta = DeepZoom.ElementToLogicalPoint(FareKonum);

**                DeepZoom.ZoomAboutLogicalPoint(0.5, ZoomlananNokta.X,
ZoomlananNokta.Y);**

            }

 

            if (DonMiktar != 0) {

                e.PreventDefault();

                Gelen.SetProperty("returnValue", false);

            }

        }

İlk olarak ElementToLogicalPoint metodu ile elimizdeki fare
konumunun DeepZoom içerisinde tam olarak hangi koordinatlara
geldiğini buluyoruz. Sonrasında da ZoomAboutLogicalPoint metodu ile
zoom işlemini yapıyoruz. Zoom işlemi esnasında bizden üç parametre
isteniyor, zoom miktarı, zoomlanacak noktanın X ve Y koordinatları.
Böylece basit bir şekilde zoom işlemini de çözmüş olduk.

Atraksyon zamanı!

Yapılacaklar listemizde son bir öğe kaldı :) "Atraksyon". Şimdi biraz
hareketli birşeyler yapalım. Eğer uygulamanın başından beridir benimle
aynı adımları takip ediyorsunuz şu an DeepZoom kontrolü içerisinde yan
yana ve alt alta sıralı onlarca fotoğrafınız var demektir. Peki bu
fotoğrafları rastgele karıştıran bir düğme eklesek? Animasyonlarla
fotoğraf düğmeye her basıldığında rastgele olarak yerlerini
değiştirseler hoş olmaz mıydı? Belki de sizin istediğiniz farklı
sıralara bile gelebilirler. Hemen kolları sıvayalım ve XAML'ımıza basit
bir düğme ekleyelim.

<UserControl
x
:Class="SilverlightApplication6.Page"

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

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

   Width="1024"
Height
="768">

    <Grid
x
:Name="LayoutRoot"
Background
="White">

        <MultiScaleImage
x
:Name="DeepZoom"/>

        <Button
Height
="65" HorizontalAlignment="Right"
Margin
="0,0,30,19" VerticalAlignment="Bottom"
Width
="174" Content="Karistis"
x
:Name="Karistir"/>

    </Grid>

</UserControl>

Artık uygulamamızın XAML kodu yukarıdaki şekilde olacak. Düğmeye
tıklandığında DeepZoom kontrolü içerisindeki tüm resimleri alarak
sırasını karıştırmamız sonra da animasyonlarla yeni konumlara
yerleştirmemiz gerek. İlk olarak resimleri karıştıracak olan kodu
yazalım.

[VB]

        Dim FotoList As New
List(Of MultiScaleSubImage)

        FotoList = DeepZoom.SubImages.ToList()

 

        For x As Integer
= 0 To FotoList.Count - 1

            Dim Simdiki As MultiScaleSubImage = FotoList(x)

            FotoList.RemoveAt(x)

            FotoList.Insert(Rnd() * FotoList.Count, Simdiki)

        Next

[C#]

            List<MultiScaleSubImage> FotoList = new List<MultiScaleSubImage>();

            FotoList = DeepZoom.SubImages.ToList();

            Random Rastgele = new Random();

 

            for (int x = 0; x <= FotoList.Count - 1; x++)

            {

                MultiScaleSubImage
Simdiki = FotoList[x];

                FotoList.RemoveAt(x);

                FotoList.Insert(Rastgele.Next(FotoList.Count), Simdiki);

            }

Bir DeepZoom içerisinde tüm resimler birer MultiScaleSubImage
olarak bulunuyor. DeepZoom içerisinden tüm listeyi alıp içerisindeki her
resmi listeden çıkartıp yeni bir rastgele indeks ile ekliyoruz. Böylece
her seferinde sıralamayı rastgele değiştirmiş olduk. Sıra geldi bu
sıralama ile resimleri sahnedeki yeni konumlarına birer animasyon ile
göndermeye.

[VB]

        Dim KolonSayisi As Integer
= 5

        Dim SatirSayisi As Integer
= 5

        Dim ToplamEklenen As Integer
= 0

 

        For Satir As Integer
= 0 To SatirSayisi

            For Kolon As Integer
= 0 To KolonSayisi

                If ToplamEklenen <>
FotoList.Count Then

 

....................                

 

        ToplamEklenen += 1

                Else

        Exit Sub

                End If

            Next

        Next

[C#]

            int KolonSayisi = 5;

            int SatirSayisi = 5;

            int ToplamEklenen = 0;

 

            for (int Satir = 0; Satir <= SatirSayisi;
Satir++)

            {

                for (int Kolon = 0; Kolon <= KolonSayisi;
Kolon++)

                {

                    if (ToplamEklenen
!= FotoList.Count)

                    {

                       

..............................

 

                        ToplamEklenen += 1;

                    }

                    else

                    {

                        break;

                    }

                }

            }

Yukarıdaki kodumuzun orta kısmında birazdan her resmi farklı bir konuma
animasyon ile gönderen kodu yazacağız. Fakat onun öncesinde kodun ana
yapısını bir inceleyelim. Resimler yan yana ve alt alta sıralayacağımız
için aslında bir Grid yapısında görsellik yaratmış olacağız. Kodumuzda
KolonSayisi ve SatirSayisi değişkenleri kaç kolon ve satırlık
bir sıralama yapılacağını belirliyor. ToplamEklenen değişkeni ise o ana
kadar kaç fotoğraf eklediğimizi hafızada tutacak, böylece döngü
içerisinde eklenen toplam fotoğraf sayısı elimizdeki fotoğraf sayısına
ulaşırsa döngüden çıkacağız. Şimdi gelelim fotoğrafları yeni konumlarına
gönderecek animasyonları yaratacak kodumuza.

[VB]

        Dim Foto As MultiScaleSubImage =
FotoList(ToplamEklenen)

        Dim MevcutKonum As Point = Foto.ViewportOrigin

        Dim HedefKonum As Point = New Point(-1.14 * Kolon, -0.8 * Satir)

 

        'Animasyonu yaratalım

        Dim Anim As New
Storyboard

        Dim NoktaAnim As New
PointAnimationUsingKeyFrames

        Dim KeyFrame As New
SplinePointKeyFrame

        KeyFrame.Value = HedefKonum

        KeyFrame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1))

 

        Dim Ivme As New
KeySpline

        Ivme.ControlPoint1 = New
Point(0, 1)

        Ivme.ControlPoint2 = New
Point(1, 1)

        KeyFrame.KeySpline = Ivme

        NoktaAnim.KeyFrames.Add(KeyFrame)

 

        Storyboard.SetTarget(NoktaAnim, Foto)

        Storyboard.SetTargetProperty(NoktaAnim, New PropertyPath("ViewportOrigin"))

 

        Anim.Children.Add(NoktaAnim)

 

        Anim.Begin()

[C#]

        MultiScaleSubImage Foto =
FotoList[ToplamEklenen];

        Point MevcutKonum =
Foto.ViewportOrigin;

        Point HedefKonum = new Point(-1.14 * Kolon, -0.8 * Satir);

 

        //Animasyonu yaratalım

        Storyboard Anim = new Storyboard();

        PointAnimationUsingKeyFrames NoktaAnim =
new PointAnimationUsingKeyFrames();

        SplinePointKeyFrame
KeyFrame = new SplinePointKeyFrame();

        KeyFrame.Value = HedefKonum;

        KeyFrame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1));

 

        KeySpline Ivme = new KeySpline();

        Ivme.ControlPoint1 = new Point(0, 1);

        Ivme.ControlPoint2 = new Point(1, 1);

        KeyFrame.KeySpline = Ivme;

        NoktaAnim.KeyFrames.Add(KeyFrame);

 

        Storyboard.SetTarget(NoktaAnim, Foto);

        Storyboard.SetTargetProperty(NoktaAnim,
new PropertyPath("ViewportOrigin"));

 

        Anim.Children.Add(NoktaAnim);

 

        Anim.Begin();

Kodumuz biraz uzun gibi gözükse de aslında özünde yaptığımız şey çok
basit. İlk olarak döngümüzle oluşturduğumuz ToplamEklenen sayısı
üzerinden o anki resmi FotoList içerisinden bir değişkene alıyoruz.
MevcutKonum ve HedefKonum değişkenlerimiz ise fotoğrafın şu anki
ve animasyonun sonundaki konumlarını saklıyor. Yeni konum hesaplarken
kolon ve satır arası mesafelerle sayıları çarparak yeni konumu
rahatlıkla hesaplayabiliyoruz. Artık hedeflediğimiz konum da belli
olduğuna göre geriye kaldı eldeki fotoğrafı hedef konuma taşıyacak
animasyonu yaratmak. Animasyon yapacağımız şey fotoğrafın
ViewportOrigin özelliği ve bu özelliği Point tipinde. Bu nedenle
PointAnimationUsingKeyFrame kullanarak hedef KeyFrame'i
yaratacağız. Kodumuzda baktığımızda KeyFrame adındaki değişkenimiz 1
saniye sonra ViewPortOrigin değerini değiştiriyor. Ayrıca animasyonu
ivme vermek için bir de KeySpline kullanıyoruz. Tüm bu nesnelerin
birbirlerine eklenme şekilleri XAML'da bir StoryBoard yaratmaktan farklı
değil. Kodumuzun en sonunda artık animasyonumuzu çalıştırmak için Begin
metodunu çağırabiliriz.

Herşey bitti

Uygulamamız bitti. Artık istediğimiz kadar fotoğraflarımız arasında
geçebilir, zoom yapabilir hatta resimleri bir düğme ile animasyonlu bir
şekilde karıştırabiliriz. Uygulamanın tam kodunu aşağıda
inceleyebilirsiniz.

[VB]

Partial Public Class Page

    Inherits UserControl

 

    Public Sub New()

        InitializeComponent()

    End Sub

 

    Dim Tasiniyor = False

    Dim FareKonum As Point

    Dim DeepZoomOrigin As Point

 

    Private Sub Page_Loaded(ByVal sender As Object,
ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded

        'Kaynağımızı bağlayalım

        DeepZoom.Source = New
DeepZoomImageTileSource(New Uri("NewFolder1/dzc_output.xml",
UriKind.Relative))

 

        'MouseWheel bağlantısı
yapalım

        System.Windows.Browser.HtmlPage.Window.AttachEvent("DOMMouseScroll", AddressOf FareTekerlekDondu)

        System.Windows.Browser.HtmlPage.Window.AttachEvent("onmousewheel", AddressOf FareTekerlekDondu)

        System.Windows.Browser.HtmlPage.Document.AttachEvent("onmousewheel", AddressOf FareTekerlekDondu)

    End Sub

 

    Private Sub FareTekerlekDondu(ByVal sender As Object,
ByVal e As System.Windows.Browser.HtmlEventArgs)

        Dim DonMiktar As Integer
= 0

        Dim Gelen As System.Windows.Browser.ScriptObject =
e.EventObject

        'IE ve OPERA

        If Not Gelen.GetProperty("wheelDelta") Is Nothing
Then

            'OPERA'da ters!

            If Not Gelen.GetProperty("opera") Is Nothing
Then

                DonMiktar = -DonMiktar

            End If

            DonMiktar = Gelen.GetProperty("wheelDelta")

            'Mozilla ve Safari

        ElseIf Not Gelen.GetProperty("detail") Is Nothing
Then

            DonMiktar = -Gelen.GetProperty("detail")

        End If

        If DonMiktar > 0 Then

            'Zoom yap

            Dim ZoomlananNokta As Point =
DeepZoom.ElementToLogicalPoint(FareKonum)

            DeepZoom.ZoomAboutLogicalPoint(2, ZoomlananNokta.X,
ZoomlananNokta.Y)

        Else

            'Uzaklaş

            Dim ZoomlananNokta As Point =
DeepZoom.ElementToLogicalPoint(FareKonum)

            DeepZoom.ZoomAboutLogicalPoint(0.5, ZoomlananNokta.X,
ZoomlananNokta.Y)

        End If

 

        If DonMiktar <> 0 Then

            e.PreventDefault()

            Gelen.SetProperty("returnValue", False)

        End If

    End Sub

 

    Private Sub Page_MouseLeftButtonDown(ByVal sender As Object,
ByVal e As
System.Windows.Input.MouseButtonEventArgs) Handles Me.MouseLeftButtonDown

        Tasiniyor = True

        FareKonum = e.GetPosition(Me)

        DeepZoomOrigin = DeepZoom.ViewportOrigin

    End Sub

 

    Private Sub Page_MouseLeftButtonUp(ByVal sender As Object,
ByVal e As
System.Windows.Input.MouseButtonEventArgs) Handles Me.MouseLeftButtonUp

        Tasiniyor = False

    End Sub

 

    Private Sub Page_MouseMove(ByVal sender As Object,
ByVal e As System.Windows.Input.MouseEventArgs)
Handles Me.MouseMove

        If Tasiniyor Then

            Dim YeniDeepZoomOrigin
As New Point

            YeniDeepZoomOrigin.X = DeepZoomOrigin.X -
(((e.GetPosition(DeepZoom).X - FareKonum.X) / DeepZoom.ActualWidth) *
DeepZoom.ViewportWidth)

            YeniDeepZoomOrigin.Y = DeepZoomOrigin.Y -
(((e.GetPosition(DeepZoom).Y - FareKonum.Y) / DeepZoom.ActualHeight) *
DeepZoom.ViewportWidth)

            DeepZoom.ViewportOrigin = YeniDeepZoomOrigin

        Else

            FareKonum = e.GetPosition(Me)

        End If

    End Sub

 

    Private Sub Karistir_Click(ByVal sender As Object,
ByVal e As System.Windows.RoutedEventArgs) Handles Karistir.Click

        Dim FotoList As New
List(Of MultiScaleSubImage)

        FotoList = DeepZoom.SubImages.ToList()

 

        For x As Integer
= 0 To FotoList.Count - 1

            Dim Simdiki As MultiScaleSubImage = FotoList(x)

            FotoList.RemoveAt(x)

            FotoList.Insert(Rnd() * FotoList.Count, Simdiki)

        Next

 

        Dim KolonSayisi As Integer
= 5

        Dim SatirSayisi As Integer
= 5

        Dim ToplamEklenen As Integer
= 0

 

        For Satir As Integer
= 0 To SatirSayisi

            For Kolon As Integer
= 0 To KolonSayisi

                If ToplamEklenen <>
FotoList.Count Then

                    Dim Foto As MultiScaleSubImage =
FotoList(ToplamEklenen)

                    Dim MevcutKonum
As Point = Foto.ViewportOrigin

                    Dim HedefKonum
As Point = New Point(-1.14 * Kolon, -0.8 * Satir)

 

                    'Animasyonu
yaratalım

                    Dim Anim As New
Storyboard

                    Dim NoktaAnim
As New PointAnimationUsingKeyFrames

                    Dim KeyFrame As New
SplinePointKeyFrame

                    KeyFrame.Value = HedefKonum

                    KeyFrame.KeyTime =
KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1))

 

                    Dim Ivme As New
KeySpline

                    Ivme.ControlPoint1 = New Point(0, 1)

                    Ivme.ControlPoint2 = New Point(1, 1)

                    KeyFrame.KeySpline = Ivme

                    NoktaAnim.KeyFrames.Add(KeyFrame)

 

                    Storyboard.SetTarget(NoktaAnim, Foto)

                    Storyboard.SetTargetProperty(NoktaAnim, New PropertyPath("ViewportOrigin"))

 

                    Anim.Children.Add(NoktaAnim)

 

                    Anim.Begin()

 

                    ToplamEklenen += 1

                Else

                    Exit Sub

                End If

            Next

        Next

    End Sub

End Class

[C#]

namespace SilverlightApplication1

{

    public partial class Page : UserControl

    {

        bool Tasiniyor = false;

        Point FareKonum;

        Point DeepZoomOrigin;

 

        public Page()

        {

            InitializeComponent();

            this.Loaded += new RoutedEventHandler(Page_Loaded);

            this.MouseLeftButtonDown += new MouseButtonEventHandler(Page_MouseLeftButtonDown);

            this.MouseLeftButtonUp +=
new MouseButtonEventHandler(Page_MouseLeftButtonUp);

            this.MouseMove += new MouseEventHandler(Page_MouseMove);

            this.Karistir.Click +=
new RoutedEventHandler(Karistir_Click);

        }

 

        void Karistir_Click(object sender, RoutedEventArgs e)

        {

            List<MultiScaleSubImage> FotoList = new List<MultiScaleSubImage>();

            FotoList = DeepZoom.SubImages.ToList();

            Random Rastgele = new Random();

 

            for (int x = 0; x <= FotoList.Count - 1; x++)

            {

                MultiScaleSubImage
Simdiki = FotoList[x];

                FotoList.RemoveAt(x);

                FotoList.Insert(Rastgele.Next(FotoList.Count), Simdiki);

            }

 

            int KolonSayisi = 5;

            int SatirSayisi = 5;

            int ToplamEklenen = 0;

 

            for (int Satir = 0; Satir <= SatirSayisi;
Satir++)

            {

                for (int Kolon = 0; Kolon <= KolonSayisi;
Kolon++)

                {

                    if (ToplamEklenen
!= FotoList.Count)

                    {

                        MultiScaleSubImage Foto =
FotoList[ToplamEklenen];

                        Point
MevcutKonum = Foto.ViewportOrigin;

                        Point
HedefKonum = new Point(-1.14 * Kolon, -0.8 * Satir);

 

                        //Animasyonu
yaratalım

                        Storyboard
Anim = new Storyboard();

                        PointAnimationUsingKeyFrames NoktaAnim =
new PointAnimationUsingKeyFrames();

                        SplinePointKeyFrame KeyFrame = new SplinePointKeyFrame();

                        KeyFrame.Value = HedefKonum;

                        KeyFrame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1));

 

                        KeySpline
Ivme = new KeySpline();

                        Ivme.ControlPoint1 = new Point(0, 1);

                        Ivme.ControlPoint2 = new Point(1, 1);

                        KeyFrame.KeySpline = Ivme;

                        NoktaAnim.KeyFrames.Add(KeyFrame);

 

                        Storyboard.SetTarget(NoktaAnim, Foto);

                        Storyboard.SetTargetProperty(NoktaAnim,
new PropertyPath("ViewportOrigin"));

 

                        Anim.Children.Add(NoktaAnim);

 

                        Anim.Begin();

 

                        ToplamEklenen += 1;

                    }

                    else

                    {

                        break;

                    }

                }

            }

 

        }

 

        void Page_MouseMove(object sender, MouseEventArgs e)

        {

            if (Tasiniyor)

            {

                Point
YeniDeepZoomOrigin = new Point();

                YeniDeepZoomOrigin.X = DeepZoomOrigin.X -
(((e.GetPosition(DeepZoom).X - FareKonum.X) / DeepZoom.ActualWidth) *
DeepZoom.ViewportWidth);

                YeniDeepZoomOrigin.Y = DeepZoomOrigin.Y -
(((e.GetPosition(DeepZoom).Y - FareKonum.Y) / DeepZoom.ActualHeight) *
DeepZoom.ViewportWidth);

                DeepZoom.ViewportOrigin = YeniDeepZoomOrigin;

            }

            else

            {

                FareKonum = e.GetPosition(this);

            }

        }

 

        void
Page_MouseLeftButtonUp(object sender,
MouseButtonEventArgs e)

        {

            Tasiniyor = false;

        }

 

        void
Page_MouseLeftButtonDown(object
sender, MouseButtonEventArgs e)

        {

            Tasiniyor = true;

            FareKonum = e.GetPosition(this);

            DeepZoomOrigin = DeepZoom.ViewportOrigin;

        }

 

        void Page_Loaded(object sender, RoutedEventArgs e)

        {

            //Kaynağımızı bağlayalım

            DeepZoom.Source = new
DeepZoomImageTileSource(new Uri("NewFolder1/dzc_output.xml", UriKind.Relative));

 

            //MouseWheel bağlantısı
yapalım

            System.Windows.Browser.HtmlPage.Window.AttachEvent("DOMMouseScroll", FareTekerlekDondu);

            System.Windows.Browser.HtmlPage.Window.AttachEvent("onmousewheel", FareTekerlekDondu);

            System.Windows.Browser.HtmlPage.Document.AttachEvent("onmousewheel", FareTekerlekDondu);

        }

 

        private void FareTekerlekDondu(object sender, System.Windows.Browser.HtmlEventArgs e)

        {

            int DonMiktar = 0;

            System.Windows.Browser.ScriptObject Gelen = e.EventObject;

            //IE ve OPERA

            if
((Gelen.GetProperty("wheelDelta")
!= null)) {

                //OPERA'da ters!

                if
((Gelen.GetProperty("opera") !=
null)) {

                    DonMiktar = -DonMiktar;

                }

                DonMiktar = (int)Gelen.GetProperty("wheelDelta");

            }

            //Mozilla ve Safari

            else if ((Gelen.GetProperty("detail") != null)) {

                DonMiktar = -1 * (int)Gelen.GetProperty("detail");

            }

            if (DonMiktar > 0) {

                //Zoom yap

                Point
ZoomlananNokta = DeepZoom.ElementToLogicalPoint(FareKonum);

                DeepZoom.ZoomAboutLogicalPoint(2, ZoomlananNokta.X,
ZoomlananNokta.Y);

            }

            else {

                //Uzaklaş

                Point
ZoomlananNokta = DeepZoom.ElementToLogicalPoint(FareKonum);

                DeepZoom.ZoomAboutLogicalPoint(0.5, ZoomlananNokta.X,
ZoomlananNokta.Y);

            }

 

            if (DonMiktar != 0) {

                e.PreventDefault();

                Gelen.SetProperty("returnValue", false);

            }

        }

    }

}

Hepinize kolay gelsin.