0% found this document useful (0 votes)
68 views9 pages

Silverlight/Javascript Photo Gallery Wall How-To: Written by Jeff Paries

This tutorial describes how to configure the Silverlight client-side photo gallery illustrated in figure 1 for use on a web site. The gallery displays 16 images with configurable descriptions that will be displayed under the image. It will switch into a slideshow mode if no images are selected by the user.

Uploaded by

MessageDance
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
68 views9 pages

Silverlight/Javascript Photo Gallery Wall How-To: Written by Jeff Paries

This tutorial describes how to configure the Silverlight client-side photo gallery illustrated in figure 1 for use on a web site. The gallery displays 16 images with configurable descriptions that will be displayed under the image. It will switch into a slideshow mode if no images are selected by the user.

Uploaded by

MessageDance
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 9

Silverlight/Javascript Photo Gallery Wall How-To

Written by Jeff Paries


http://www.designwithsilverlight.com

Not to be reproduced or redistributed without permission.


©2007
Introduction:
This tutorial describes how to configure the Silverlight client-side photo gallery illustrated in
figure 1 for use on a web site. The gallery displays 16 images with configurable descriptions that
will be displayed under the image. It will switch into a slideshow mode if no images are selected
by the user.

Figure 1
Configuration:
If you would like to change the title, images, or text being displayed in the gallery, you can do so
by editing the galleryConfig.js file. The one used for the example has three parts to it.

The first part is a variable for the gallery title. This is the text that displays above and to the left
of the image gallery. If you do not want a title to display, set the variable to a null string ("").

var galleryTitle = "- Miscellaneous Photos -";

The second part of the gallery configuration file is an array of images to be displayed. All 16
elements of the image array must be filled to ensure that the gallery displays properly. To
change the images being displayed, simply modify the filenames for the array elements.

// set up an array for the images


var photoArray = new Array(16)
photoArray[0]="images/eyes640x480.jpg"
photoArray[1]="images/crescentGlacier640x480.jpg"
photoArray[2]="images/adams640x480.jpg"
photoArray[3]="images/adamsSunrise640x480.jpg"
photoArray[4]="images/msh640x480.jpg"
photoArray[5]="images/fireworks640x480.jpg"
photoArray[6]="images/cityNight640x480.jpg"
photoArray[7]="images/beeFlower640x480.jpg"
photoArray[8]="images/softWater640x480.jpg"
photoArray[9]="images/columbiaRiver640x480.jpg"
photoArray[10]="images/pacific640x480.jpg"
photoArray[11]="images/crownPoint640x480.jpg"
photoArray[12]="images/yellowFlower640x480.jpg"
photoArray[13]="images/purpleFlower640x480.jpg"
photoArray[14]="images/yellowRose640x480.jpg"
photoArray[15]="images/marigold640x480.jpg";
The third part of the gallery configuration file is an array of labels that corresponds to the images
array. Here, you can insert text that will be displayed beneath the corresponding image. It is not
necessary to include text for every image – if you do not wish to display text for a given image,
leave the array element null ("").

// set up an array for the images


var photoLabels = new Array(16)
photoLabels[0] = "My eyes are an ocean in which my dreams are reflected."
photoLabels[1] = "Crescent Glacier, Mt. Adams - June 14th, 2007"
photoLabels[2] = ""
photoLabels[3] = "Sunrise over Mt. Adams (from Mt. St. Helens)"
photoLabels[4] = ""
photoLabels[5] = ""
photoLabels[6] = ""
photoLabels[7] = ""
photoLabels[8] = ""
photoLabels[9] = "The Columbia River"
photoLabels[10] = "Pacific Ocean, Oregon Coast"
photoLabels[11] = "Crown Point / Vista House"
photoLabels[12] = ""
photoLabels[13] = ""
photoLabels[14] = ""
photoLabels[15] = "";

The preceding information describes the utilization of the gallery viewer. If you’re interested in
how it was built and how it works, the following section describes the scripts and XAML in more
detail.
How it Works:
The initial concept for the gallery was fleshed out with a quick mockup in a 3D program. I had an
idea of how I wanted the gallery to look, but needed to be able to make tweaks to it to finalize
the rough design prior to jumping into Blend to begin creating it. Figure 2 shows the rendered
layout I came up with.

Figure 2

The construction of the gallery app involved a lot of tweaking, so I will not be trying to describe
step by step how it was created. Rather, I will provide a high level overview of the process and
allow you to dissect the included XAML file.

The main idea was to create 4 main containers: left side, left side reflections, right side, right
side reflections. The left side contains the base "wall", 16 drop shadows, 16 images, and a
gradient mask for the lighting effect. The left side reflections container is a copy of the left side
container, scaled to -1 Y, then adjusted as necessary to line up right. In the reflections container,
it was not necessary to include all 16 images, so the 8 that would not be seen in the reflection
were removed (images 0-7). The right side follows the same pattern, and contains the base
"wall", 1 drop shadow, 1 image, the image label text, image label text drop shadow, and a
gradient mask for the lighting effect. Like the left side, the right side reflection was done by
copy/pasting the right side container, and scaling to -1 Y. Both the left and right reflections
containers have an extra gradient over them to "fade" the reflection out.
The biggest hurdle I encountered in creating the gallery was how to make images that looked
like they had a perspective warp applied to them since there is no tool for doing that directly in
Blend. This led me to explore the use of Image Brushes applied to paths. As of this writing,
Blend doesn't give you a tool with which to create an image brush when you're creating a
Javascript application. Or perhaps I should say if there is a tool for image brushes in Javascript, I
was not able to find it. However, image brushes still work if you plug them into the XAML
directly.

I opened the layout image shown in figure 2 in Blend, and locked the layer so I could build over
it. I then began creating the images by building rectangular paths over the red rectangles in the
image. Once that was done, a path might look something like this:

<Path " Width="108.75" Height="105.7" Stretch="Fill" Data="M73.452077,83.401408


L181.50719,75.695112 181.50719,167.17681 73.452077,180.7993 z" x:Name="image12"
Opacity="1" Canvas.Left="7.5" Canvas.Top="9.75"/>

To add the image brush, I removed the closing "/" at the end of the <Path>, and added a
<Path.Fill> for the image brush as well as a new closing tag for the <Path>, resulting in
something like this:

<Path " Width="108.75" Height="105.7" Stretch="Fill" Data="M73.452077,83.401408


L181.50719,75.695112 181.50719,167.17681 73.452077,180.7993 z" x:Name="image12"
Opacity="1" Canvas.Left="7.5" Canvas.Top="9.75">
<Path.Fill>
<ImageBrush x:Name="imageBrush12" ImageSource="images/blank.jpg"
Stretch="UniformToFill"/>
</Path.Fill>
</Path>

The image brush is now used as a fill for the path. As a side note, while I haven't yet
experimented with it, the same thing works with video brushes.

I had hoped to get a soft edged drop shadow by using an image I created in Photoshop on the
shadow layers, but the way the fill works, the image did not warp specifically to the rectangle.
The shadows still look good; they're just not exactly what I had hoped for.

The only other mystery shape in the XAML is a small white rectangle floating off canvas to the
left. This rectangle has a 10 second animation attached to it that does virtually nothing. It is
used as a timer to determine when the application will switch into a slideshow mode if no images
are clicked.

As I mentioned earlier, it was just a lot of tweaking that really brought the final version together,
making sure corners lined up, shadows looked right, etc. The next section describes the code
behind the application.
Functionality
The basic functionality of the gallery looks something like this:

When the gallery is loaded, display the title, and load the images from the array into the small
image panes on the left.

When the mouse is moved over an image, draw a black stroke around the image. If the image
has a reflection (images 8-15), draw the stroke on the reflection as well.

When the mouse moves off an image, remove the black stroke around the image. If the image
has a reflection (images 8-15), remove the stroke on the reflection as well.

When an image is clicked, display the image, its reflection, and label text (if present) on the
right-hand side.

If no images are clicked for 10 seconds, begin displaying the slides in a slideshow, starting with
the image following the one that is currently displayed, changing images every 10 seconds.

When loaded, the app begins by calling the loadGalleryImages function. This is attached to the
main canvas via the loaded event:

<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="1024" Height="768"
Background="#FF000000"
x:Name="rootCanvas"
Loaded="loadGalleryImages">

The loadGalleryImages function begins by loading the images from the image array into the
preview panes, as well as the reflection panes. It then displays image 0 and its reflection, as well
as the gallery title. Next, it grabs the label for image 0, writes it into the label and label drop
shadow, determines the width of the text, and positions both the label and drop shadow
centered beneath the image. The text is also drawn into the reflection pane. The last thing
loadGalleryImages does is to start the timer, and add an event listener to it. If the timer
completes, the doSlideshow function is called.

For mouse over functionality, a function called showOutline is attached to the MouseEnter
event on the image (remember the image is a path with an image brush applied).

<Path MouseLeftButtonDown="displayImage" MouseEnter="showOutline"


MouseLeave="hideOutline" Width="72" Height="84.381" Stretch="Fill"
Data="M61.61746,66.863792 L132.57214,75.694792 132.5719,150.76973
61.28035,146.29508 z" x:Name="image03" Opacity="1" Canvas.Top="-0.131"
Canvas.Left="0.75">
<Path.Fill>
<ImageBrush x:Name="imageBrush03" ImageSource="images/blank.jpg"
Stretch="Fill"/>
</Path.Fill>
</Path>
The showOutline function draws a 2px black stroke around the image the mouse is over. It
then determines the image number that was selected (based on its name), checks to see if it is
an image that has a reflection, and if so, draws the stroke on the reflection as well.

For mouse out functionality, a function called hideOutline is attached to the MouseLeave event
on the image.

<Path MouseLeftButtonDown="displayImage" MouseEnter="showOutline"


MouseLeave="hideOutline" Width="72" Height="84.381" Stretch="Fill"
Data="M61.61746,66.863792 L132.57214,75.694792 132.5719,150.76973
61.28035,146.29508 z" x:Name="image03" Opacity="1" Canvas.Top="-0.131"
Canvas.Left="0.75">
<Path.Fill>
<ImageBrush x:Name="imageBrush03" ImageSource="images/blank.jpg"
Stretch="Fill"/>
</Path.Fill>
</Path>

The hideOutline function sets the stroke thickness to 0. It then determines the image number
that was selected (based on its name), checks to see if it is an image that has a reflection, and if
so, hides the stroke on the reflection as well.

For mouse click functionality, a function called displayImage is attached to the


MouseLeftButtonDown event on the image.

<Path MouseLeftButtonDown="displayImage" MouseEnter="showOutline"


MouseLeave="hideOutline" Width="72" Height="84.381" Stretch="Fill"
Data="M61.61746,66.863792 L132.57214,75.694792 132.5719,150.76973
61.28035,146.29508 z" x:Name="image03" Opacity="1" Canvas.Top="-0.131"
Canvas.Left="0.75">
<Path.Fill>
<ImageBrush x:Name="imageBrush03" ImageSource="images/blank.jpg"
Stretch="Fill"/>
</Path.Fill>
</Path>

The displayImage function begins by stopping the timer that started when the app was loaded.
Since user input has been received, the app does not need to enter slideshow mode. It then
plays the fadeOutImage animation. An eventlistener is added to the fadeOutImage animation so
that when it is completed, a function called showNextImage is called.

The showNextImage function updates the display image, text, and reflections based on the
image number that was determined in the displayImage function. It then plays the
fadeInImage animation, and restarts the timer on the page.

The displayImage and showNextImage functions do the work when a user clicks on an
image. However, if the timer is ever allowed to complete, a function called doSlideshow is
called.

doSlideshow checks to see which image is currently being displayed, and sets up a variable for
the next image that should display.
It then calls a function called displayImages that plays the fadeOutImage animation, and adds
an event listener to the animation to call a function called nextSlide upon completion.

The nextSlide function does the majority of the work in slideshow mode. It begins by removing
the event listener that was set on the fadeOutImage animation (nextSlide is called when the
animation is completed).

It then does a quick check to see if the next image to display matches the array length (16). If
so, it loops around to the beginning of the array since the last image in the array is at element
15.

It then builds the proper name for the next image to be displayed, changes the text, text
shadow, and text reflection, adjusts the size of all the text elements, and centers them. Finally,
the display image and reflection are updated, and the fadeInImage animation is started.

And that's it! The gallery scripts are fairly small… the wallGallery.js file, which contains the
functionality for the gallery, is about 5.5K. The configuration file is about 1.5K more. Even the
XAML file is relatively light, at about 43K.

You might also like