Wednesday, October 24, 2007

silverlight experiment: fading 2

I posted a partial solution to fading yesterday. Today, I think i have figured out how to efficiently fade almost anything. The big challenge for me was removing storyboards that I was no longer going to use. The solution was to use and event listener that would remove the storyboard after it had completed. I wasn't sure if the event listener would work (if mouseEnter storyboard fades target to end value, wouldn't that trigger a complete?). Surprisingly though, it actually works quite well.



XAML

<>Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="200" Height="150"
Background="#FF666666" x:Name="Page" Loaded="onLoaded" <>
<>Path Width="63" Height="52" Fill="#FFFF8B00" Stretch="Fill" Canvas.Left="20.794" Canvas.Top="29.663" Data="M56.487645,98 L74.805883,83.663793 92.204852,97.5 89,97.5 89,113.2481 60.029416,113.2481 60.029416,98 z" x:Name="home" Cursor="Hand"
MouseLeave="fadeMeIn" MouseEnter="fadeMeOut"/<>
<>Path Width="63" Height="52" Fill="#FFFF8B00" Stretch="Fill" Canvas.Left="112.794" Canvas.Top="29.663" Data="M56.487645,98 L74.805883,83.663793 92.204852,97.5 89,97.5 89,113.2481 60.029416,113.2481 60.029416,98 z" x:Name="home2" Cursor="Hand"
MouseLeave="fadeMeIn" MouseEnter="fadeMeOut"/<>
<>/Canvas<>


Javascript

function onLoaded(s)
{
root=s.findName("Page");
plugin = s.getHost();
}
function fadeMeOut(sender, mouseEventArgs)
{
var sName = makeName(sender);
var sTo = "0.3";
var sFrom = "1.0";
var sTarget = sender.Name;
var fader = makeStoryBoard(sName, sFrom, sTo, sTarget);
sender.findName('rCount').Text = 'Number of Storyboards: '+root.Resources.Count.toString();
fader.begin();
fader.AddEventListener("Completed", "removeStoryBoard")
}
function fadeMeIn(sender, mouseEventArgs)
{
var sName = makeName(sender);
var sTo = 1;
var sFrom = sender.opacity;
var sTarget = sender.Name;
var fader = makeStoryBoard(sName, sFrom, sTo, sTarget);
fader.begin();
fader.AddEventListener("Completed", "removeStoryBoard")
}
function makeName(sender)
{
var sBi= 1;
do
{
var tempName = (sender.Name+'_sb_'+sBi);
var sBtrue = sender.findName(tempName);
sBi++;
}
while (sender.findName(tempName) != null)
return tempName;
}
function removeStoryBoard(targetBoard)
{
root.Resources.remove(targetBoard);
}

function makeStoryBoard(sName, sFrom, sTo, sTarget)
{
var xamlFragment = '<>Storyboard xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="'+sName+'"<>' +
'<>DoubleAnimation Storyboard.TargetName="'+sTarget+'" ' +
'Storyboard.TargetProperty="(Opacity)" ' +
'From="'+sFrom+'" To="'+sTo+'" Duration="0:00:00.3" AutoReverse="False" /<>' +
'<>/Storyboard<>';

var myStoryBoard = plugin.content.createFromXaml(xamlFragment);
root.Resources.Add(myStoryBoard);

return myStoryBoard;
}


Does anyone have a better way to achieve this result?

No comments: