Tag Archives: animation

Playing multiple videos simultaneously using HTML5

I was interested to see how playing multiple videos simultaneously affected the performance of a web page. This probably seems a little like a time machine back to 1995 – I’ll soon be posting about flashing red text and Dreamweaver!

However, playing short videos with only a few frames can be a way to draw attention to a particular part of the page; for example, if you’re browsing a clothing catalogue and one of the models moves when you hover over.

It’s worth pointing out that the entire page will be local, and so I have no network considerations whatsoever. This isn’t, however, about having three Netflix streams running at the same time – it’s short, and small videos.

The video that I’m using came from here. I’m creating an effect whereby you hover over an image of a space ship and it explodes.

MP4

It’s worth bearing in mind that most video formats are not supported by most browsers. MP4 is the exception, so it looks like this is the way to go for video encoding. I used this tool to convert the file.

HTML

Here’s the HTML for a single icon:

<head>
  <script src="HoverAnimate.js"></script>
</head>
<body onload="loaded()">
  <div id="ship1" style="background-image: url('assets/titan.png'); background-repeat: no-repeat; background-size: 50px 50px; width: 50px; height: 50px">
    <video  width="50" height="50" id="ship1-video" 
            style="visibility: hidden">
      <source src="assets/explosion.mp4" type="video/mp4" />
    </video>
  </div>
</body>

Clearly this could be neater if the CSS was separated, but essentially what we have is a div element with a scaled background image, which contains a video (currently hidden). The next thing is the Javascript that plays the video:

function loaded() {
    var imgs = document.getElementsByTagName("div");
    [].forEach.call(imgs, function (item) {
        if (item.style.backgroundImage !== "") {
            item.addEventListener('mouseover', hoverImg, false);
        }
    });
   
}

function hoverImg(e) {      
    var vid = document.getElementById(this.id + "-video");
    vid.onended = function() {        
        vid.style.visibility = 'hidden';
    }
        
    vid.style.visibility = 'visible';
    vid.play();
}

This iterates through all the div elements and, for those that has a background image, hooks up a hover event. I’ve also assumed that the div element will be named using the format “{imagename}-video”.

Conclusion

I tried this with seven videos simultaneously, and didn’t see any jerking of the animations. Whether this would stand up under networked conditions, it’s hard to say, but with the video locally available, performance is fine.

References

https://www.w3schools.com/html/html_media.asp

http://www.online-convert.com/

https://www.w3schools.com/html/html5_video.asp

http://www.dreamincode.net/forums/topic/281583-video-plays-on-mouse-over-but-not-with-multiple-videos/

https://stackoverflow.com/questions/10881678/html-play-a-video-inside-an-image

Create CSS effect to “Shine” a button border

Imagine that you have an HTML button or element on a page and you would like an effect where the border shines all around the perimeter. this provides an excellent example of an effect of the entire element shining, and this post will largely be based on that code.

Animations

CSS has the concept of an animation, to define it, use the following syntax:

.growOnHover:hover:after {
    animation: growAnimation 1s;
}

Here is the HTML referencing this:

<a href="#" class="growOnHover">Grow</a>

Tge “growAnimation” refers to a KeyFrame:

@keyframes growAnimation {
    from {width: 100px; height: 100px;}
    to {width: 110px; height: 110px;}
}

The effect

The effect that I want is for a light to run around the circumference of the button when it’s hovered over. In this case, instead of animating from .. to, we can specify at which stage a particular section of the animation kicks in.


.borderShine:after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 5;
  height: 5;
  opacity: 0;  

  border-radius: 1;

  background: rgba(255, 255, 255, 10);
}

.borderShine:hover:after {
  animation: shineAnimation 2s 1;  
}

@keyframes shineAnimation {
  0%   {left: 0; top: 0; width: 2; height: 2; opacity: 0}
  10%  {width: 100; height: 2}  
  20%  {left: 98; top: 0; width: 2; height: 2}
  25%  {opacity: 1;}
  30%  {height: 100}
  40%  {left: 98; top: 98; height: 2}
  50%  {left: 0; top: 98; width: 100}
  55%  {opacity: 1;}
  60%  {left: 0; top: 98; width: 2; height: 2}
  70%  {left: 0; top: 0; width: 2; height: 100}
  80%  {left: 0; top: 0; width: 2; height: 2}
  100% {opacity: 0;}
}

There are a few useful things to remember here:

  • The animation is a transition between the state that the screen is currently in, and the state that you want it to be in; so, for example, the opacity set to 1 at 25% will cause the white bar to gradually appear over the steps between the two. The reason that I’ve set opacity twice here is to prevent it from transitioning back too soon.
  • All the figures above are absolute (as my buttons are 100 x 100).

References

http://jsfiddle.net/AntonTrollback/nqQc7/

https://css-tricks.com/useful-nth-child-recipies/

https://css-tricks.com/using-multi-step-animations-transitions/

Rotate a Shape Around an Axis Using HTML5 and Javascript

Imagine, for a minute, that you want to rotate a red square around its centre… on a web page. Following on from my previous post about games using HTML5 / JS this post details how to do such a thing.

Context

Before drawing a rectangle, rotating it, or anything else, you need a context:

var canvas = document.getElementById("mainCanvas");
var ctx = canvas.getContext("2d");

Now you have a context, you can do things like clear the canvas; for example:

ctx.clearRect(0, 0, windowWidth, windowHeight);

fillRect

In HTML5, you have three methods that will be of use, and the first, and probably most important, is fillRect. It is impossible to rotate a square around its centre without a square. The syntax for fillRect is probably as you would expect:

ctx.fillRect(x, y, width, height);

rotate

The syntax for rotation is this:

ctx.rotate(rotationDegree * Math.PI / 180);

Whilst I may, during my school years, have been able to explain the sum above – I just copied it from the internet. Given the number of places where is looks exactly alike, I would guess that I’m not the first person to do that.

Just using the three lines above will give you a rotating rectangle; however, the rotation axis will be 0, 0. It took me a while to understand exactly how this works, but the key is `translate`.

translate

To me, this function is completely counter-intuitive. What it does it to offset the centre of the context by the parameters given. If the initial centre is 0, 0 (which it is by default), the following line will make it 10, 10:

ctx.translate(10, 10);

The centre of the context is 10, 10; if I call it a second time:

ctx.translate(10, 10);

The centre of the context is now 20, 20! There are two ways to reset the offset – you can simply negate the offset (by calling it with negative values), or you can call ctx.save() before the change, and ctx.restore() afterwards.

Putting it all together

So, what does all this look like in a single coherent piece of code:


        var canvas = document.getElementById("mainCanvas");
        var ctx = canvas.getContext("2d");
        ctx.clearRect(0, 0, windowWidth, windowHeight);

        var halfWidth = (iconWidth / 2);
        var halfHeight = (iconHeight / 2);

        var centreX = x - halfWidth;
        var centreY = y - halfHeight;

        ctx.fillStyle = "#FF0000";
        ctx.translate(centreX, centreY);
        ctx.rotate(rotationDegree * Math.PI / 180);
        ctx.fillRect(-halfWidth, -halfHeight, iconWidth, iconHeight);

        ctx.translate(-centreX, -centreY);

The key part to note here is the call to fillRect. Because the translate has now set the centre to be the centre of the drawn image, the image needs to be positioned at -(image width / 2).

… and you, too can have a spinning red rectangle on your screen.

References

http://www.w3resource.com/html5-canvas/html5-canvas-translation-rotation-scaling.php

https://gist.github.com/geoffb/6392450

Playing a longer running animation in Unity

Continuing on with my list of things that I’ve found in unity (I’m using 5, but have no reason to believe these wouldn’t work for 4), I had cause to execute an attack animation in a character. For reference, the character I’ve been using is here

So far, when playing an animation, I’ve used something similar to this:

gameObject.GetComponent<Animation>().Play("Idle_2");

In fact, if you put that in the Update of the linked object, you’ll get an angry looking chap looking like he’s about to charge. In order to plumb in the attack, it’s necessary to cache the animation. Start with a class level variable:

private Animation _animation;

Then, inside the update statement, something similar to this:

void Update ()
{
    if (_animation != null && _animation.IsPlaying("Attack_1")) return;

    if (Input.GetKeyDown(KeyCode.Space))
    {
        if (_animation == null)
            _animation = gameObject.GetComponent<Animation>();
        _animation.Play("Attack_1");            
    }
}

One of the bizarre things that I learnt about unity while doing this, was that if you have a null reference, it doesn’t crash. It doesn’t work, but it doesn’t crash.

I find this annoying.

Animation in XAML (Part 5)

Introduction

In this post, I would like to specifically focus on the differences between animations in WPF and in WinRT. Some quick disclaimers: As far as I’m aware, Windows Phone and WinRT are interchangeable where animations are concerned, but I base that only on my efforts to move a specific animation between the two. Consequently I won’t look at Windows Phone.

The Animation

Here’s a sample of the animation to cause the button to spin and disappear from previous posts:

         private void SpinAndDisappear_Click( object sender, RoutedEventArgs e)
        {
           
            Button b = (Button)sender;
           
            DoubleAnimation da = new DoubleAnimation (b.Width, 0, TimeSpan.FromSeconds(.5));
            b.BeginAnimation( Button.WidthProperty, da);

            DoubleAnimation da2 = new DoubleAnimation (b.Height, 0, TimeSpan.FromSeconds(.5));
            b.BeginAnimation( Button.HeightProperty, da2);

            DoubleAnimation da3 = new DoubleAnimation (0, 360, TimeSpan.FromSeconds(.5));           
            RotateTransform transform = (RotateTransform )b.RenderTransform;
            transform.BeginAnimation( RotateTransform.AngleProperty, da3 );
        }

How it Works in WinRT

Okay, so the short answer is: it doesn’t – well, that doesn’t anyway! There are a few reasons why this won’t work in WinRT, but the most annoying one is that WinRT doesn’t support multiple animations on the same element. That is, only one storyboard can be running for a given element at any time.

Before we get into a workaround, so cunning, you could tie a tail to it and call it a fox, let’s look at the size animation in WinRT (as it’s not exactly the same); first the XAML:

             < Button x : Name="SpinAndDisappear" Content ="Don't press me" Click="SpinAndDisappear_Click"
                RenderTransformOrigin ="0.5, 0.5" Height ="100" Width="300"/>

And the code behind:

             UIElement obj = ( UIElement)SpinAndDisappear;

            obj.RenderTransform = new CompositeTransform ();

            var story = new Storyboard ();

            var xAnim = new DoubleAnimation ();
            var yAnim = new DoubleAnimation ();           

            xAnim.Duration = TimeSpan.FromSeconds(2);
            yAnim.Duration = TimeSpan.FromSeconds(2);           

            xAnim.To = 0;
            yAnim.To = 0;
           
            story.Children.Add(xAnim);
            story.Children.Add(yAnim);

            Storyboard .SetTarget(xAnim, obj);
            Storyboard .SetTarget(yAnim, obj);

            Storyboard .SetTargetProperty(xAnim, "(UIElement.RenderTransform).(CompositeTransform.ScaleX)" );
            Storyboard .SetTargetProperty(yAnim, "(UIElement.RenderTransform).(CompositeTransform.ScaleY)" );
                      
            story.Begin();

I’ve borrowed quite heavily here from this article by Iris Classon:

http://irisclasson.com/2012/06/28/creating-a-scaletransform-animation-in-c-for-winrt-metro-apps/

Okay, so I want to execute two animations at the same time; surely I just do this:

         void SpinAnimation()
        {
            UIElement obj = ( UIElement)SpindAndDisappear;

            obj.RenderTransform = new RotateTransform ();
            var storySpin = new Storyboard ();
            var spinAnim = new DoubleAnimation ();
            spinAnim.Duration = TimeSpan.FromSeconds(2);
            spinAnim.From = 0;
            spinAnim.To = 360;
            storySpin.Children.Add(spinAnim);
            Storyboard .SetTarget(spinAnim, obj);
            Storyboard .SetTargetProperty(spinAnim, "(UIElement.RenderTransform).(RotateTranform.Angle)" );
           
            storySpin.Begin();
        }

And call SpinAnimation after the first StoryBegin()? That did work in WPF. If you do this, what you get is a rotation animation only. As stated before, one element, one animation. The workaround is ingenious and, unfortunately, not my idea:

http://stackoverflow.com/questions/20224307/running-multiple-animations-in-windows-store-app

But here’s how it looks:

         < Frame x : Name="SpindAndDisappearParent" Height ="100" Width ="300"
               RenderTransformOrigin ="0.5, 0.5">
            < Button x : Name="SpinAndDisappear" Content ="Don't press me"Click="SpinAndDisappear_Click"
                RenderTransformOrigin ="0.5, 0.5" Height ="100" Width="300"/>

         </ Frame>

It’s important that the sizes of the parent and child elements are the same; next, just change the SpinAnimation() function like so:

         void SpinAnimation()
        {
            UIElement obj = ( UIElement)SpindAndDisappearParent;

            obj.RenderTransform = new RotateTransform ();
            var storySpin = new Storyboard ();
            var spinAnim = new DoubleAnimation ();
            spinAnim.Duration = TimeSpan.FromSeconds(2);
            spinAnim.From = 0;
            spinAnim.To = 360;
            storySpin.Children.Add(spinAnim);
            Storyboard .SetTarget(spinAnim, obj);
            Storyboard .SetTargetProperty(spinAnim, "(UIElement.RenderTransform).(RotateTranform.Angle)" );
           
            storySpin.Begin();
        } 

Conclusion

As you can see, I’ve rested heavily on the shoulders of giants here (which is another way of saying I’ve basically used other peoples code and ideas). Having said that, this area is virtually deserted as far as internet resources go; that’s why I started this series of articles in the first place.

Hopefully they’ve proved helpful.

Animation in XAML (Part 4)

Introduction

Following on from http://pmichaelsdev.wordpress.com/2013/11/18/animation-in-xaml-part-3/ this post is about achieving the simultaneous effect of spinning and disappearing. I thought I’d also use it to list a few other animations and how to achieve them. They’re all variations on a theme to be honest, but I’ll try to list as many as may be useful.

A word of note: most of the animations will be on buttons, but I’m not aware of any restrictions as to the target (it can be any UI Element). Also, the code listed is all based on a button event; again, this can be any event that makes sense… or even one that doesn’t. For example; try the spin and disappear on MouseOver!

Spin And Disappear

Code behind:

             Button b = (Button)SpinAndDisappear;
           
            DoubleAnimation da = new DoubleAnimation (b.Width, 0, TimeSpan.FromSeconds(.5));
            b.BeginAnimation( Button.WidthProperty, da);

            DoubleAnimation da2 = new DoubleAnimation (b.Height, 0, TimeSpan.FromSeconds(.5));
            b.BeginAnimation( Button.HeightProperty, da2);

            DoubleAnimation da3 = new DoubleAnimation (0, 360, TimeSpan.FromSeconds(.5));           
            RotateTransform transform = (RotateTransform )b.RenderTransform;
            transform.BeginAnimation( RotateTransform.AngleProperty, da3 );

XAML:

         <Button x:Name="SpinAndDisappear" ...
                RenderTransformOrigin="0.5, 0.5">           
           
            <Button.RenderTransform>
               
                 <RotateTransform>
               
                 </RotateTransform>
            </Button.RenderTransform>
               </Button>

Fade

Code behind:

             Button b = ( Button)Fade;

            DoubleAnimation da = new DoubleAnimation (b.Opacity, 0, TimeSpan.FromSeconds(.5));
            b.BeginAnimation(Button.OpacityProperty, da);


Highlight The Current Textbox (Border Animation)

This is a nice little effect: when the user hovers the mouse over the textbox, the border is animated to make it stand out.

XAML:

             <TextBox Width ="300" Height="50" x:Name ="border" MouseEnter="border_MouseEnter"
                     MouseLeave="border_MouseLeave">
               
            </TextBox>

Code behind:

         private void border_MouseEnter( object sender, RoutedEventArgs e)
        {
            TextBox t = ( TextBox)border;
            ThicknessAnimation ta = new ThicknessAnimation (new Thickness (3), TimeSpan.FromSeconds(.3));
            t.BeginAnimation( TextBox.BorderThicknessProperty, ta);
        }

        private void border_MouseLeave( object sender, MouseEventArgs e)
        {
            TextBox t = ( TextBox)border;
            ThicknessAnimation ta = new ThicknessAnimation (new Thickness (1), TimeSpan.FromSeconds(.3));
            t.BeginAnimation( TextBox.BorderThicknessProperty, ta);

        }

As a minor (and obvious caveat): make sure that the starting width is the same as that on MouseLeave.

Conclusion

That’s all the animations and effects that I could think of. If you know of, or can come up with any more then if you eitjer add them in the comments, or contact me (www.twitter.com/paul_michaels or pcm2605@hotmail.co.uk) and I’ll add them in.

In the next (and final) post, I’ll focus on the differences in WinRT / Windows Phone 8.

Animation in XAML (Part 3)

Introduction

In this article, I’m going to expand on the first posts, by providing an alternative way to chain animations. In this article http://pmichaelsdev.wordpress.com/2013/10/29/animation-in-xaml-part-1/, I showed how to use the BeginTime property to do this; and that works fine; however, I did come across, what appeared to me to be, a slightly more elegant way of doing this: events.

Just for the sake of being different, I’ll use a different animation

Using Events to Chain Animations in WPF

Let’s start by creating a button that spins when you click it. The code isn’t too dis-similar to that in Part 1. Let’s have a look at the XAML first:


         <Button x:Name="SpinAndDisappear" Width="200" Height="50" Content ="Don't press me" Click="SpinAndDisappear_Click"
                RenderTransformOrigin="0.5, 0.5">
            <Button.RenderTransform>
                <RotateTransform/>
            </Button.RenderTransform>
        </Button>

Two things to note here: The RenderTransformOrigin will make it spin round the centre. Remove that and it’ll spin round the top left corner (and that would be just silly); and the RotateTransform section. That has to be there in order for WPF to know it can rotate the button.

Okay, here’s the code to spin the button:

         private void SpinAndDisappear_Click( object sender, RoutedEventArgs e)
        {
            Storyboard spin = (Storyboard )FindResource("sbSpin");
            spin.Begin( this);

        }

If you’ve been paying close attention, you’ll notice that this won’t work (even without running it and getting an error saying it can’t find the storyboard!). Here’s what the storyboard should look like:

    <Window.Resources >
        <Storyboard x:Key="sbSpin">
            <DoubleAnimation
              Storyboard.TargetName="SpinAndDisappear"
              Storyboard.TargetProperty="(Button.RenderTransform).(RotateTransform.Angle)"
              From="0"
              To="360"
              Duration="0:0:3" />
        </Storyboard>
    </Window.Resources >

That’s better, try that and you’ll have a spinning button.

Okay, so it spins. It’s not that impressive to be honest. Lets add another effect to the storyboard to make it more impressive (the clue to what that will be is in the name of the button). Let’s create that effect now:

     <Window.Resources>;
        <Storyboard x :Key="sbDisappear">
            <DoubleAnimation
                Storyboard.TargetName="SpinAndDisappear2"
                           Storyboard.TargetProperty="(Button.RenderTransform).(ScaleTransform.ScaleX)"
                           From="1" To ="0" Duration="0:0:0.2"/>
            <DoubleAnimation
                Storyboard.TargetName="SpinAndDisappear2"
                           Storyboard.TargetProperty="(Button.RenderTransform).(ScaleTransform.ScaleY)"
                           From="1" To ="0" Duration="0:0:0.2"/>
        </Storyboard>

If you’re starting to think this is getting repetitive then there’s a reason (that you’re thinking that – it is).

Now, let’s hook that in, first, just handle the Completed event of the spin:

         <Storyboard x :Key="sbSpin">
            <DoubleAnimation
              Storyboard.TargetName="SpinAndDisappear2"
              Storyboard.TargetProperty="(Button.RenderTransform).(RotateTransform.Angle)"
              From="0"
              To="360"
              Duration="0:0:3" Completed ="DoubleAnimation_Completed" />
        </Storyboard>

Finally, here’s the code for the DoubleAnimation_Completed:

         private void DoubleAnimation_Completed( object sender, EventArgs e)
        {
            Button b = ( Button)SpinAndDisappear;

            DoubleAnimation da = new DoubleAnimation (b.Width, 0, TimeSpan.FromSeconds(.5));
            b.BeginAnimation( Button.WidthProperty, da);

            DoubleAnimation da2 = new DoubleAnimation (b.Height, 0, TimeSpan.FromSeconds(.5));
            b.BeginAnimation( Button.HeightProperty, da2);

        }

Again, not rocket science, but probably the least familiar thing so far. Basically, I’m taking a reference to the button, creating a DoubleAnimation and starting it (twice, one for width and one for height).

But that looks a bit odd… and seems useless

That’s it; you now have a button that spins, and then disappears. Okay, well, wouldn’t it be much better if it just span and disappeared at the same time?

Yes!

Next post!

Animation in XAML (Part 2)

Introduction

This is the second of my series of posts on animation, using WPF and XAML. In this post, I’m looking at how we can control an animation in WPF using code behind, and also, how two animations can be triggered simultaneously.

Button Animation in WPF with code-behind

The problem with a statement like this, is that you can pretty much replicate anything in XAML in code, so you can do everything in code, some, a little or nothing. So far, I’ve come across three approaches that make sense to me. In this article I’ll cover triggering animations from code behind; following articles will cover creating animations for elements that have the transform set in XAML, and finally, no XAML at all!

Triggering an animation from code

There’s little point in re-explaining the XAML; it’s essentially the same XAML that I’ve shown in the first post. It looks like this:


    <Window.Resources>
        <Storyboard x :Key="sbExpand">
            <DoubleAnimation
                Storyboard.TargetName="codebehindbutton"
                Storyboard.TargetProperty="(Button.RenderTransform).(ScaleTransform.ScaleX)"
                From="0" To ="1.2" Duration="0:0:0.3"/>
            <DoubleAnimation
                Storyboard.TargetName="codebehindbutton"
                Storyboard.TargetProperty="(Button.RenderTransform).(ScaleTransform.ScaleY)"
                From="0" To ="1.2" Duration="0:0:0.3"/>
       
            <DoubleAnimation
                Storyboard.TargetName="codebehindbutton"
                Storyboard.TargetProperty="(Button.RenderTransform).(ScaleTransform.ScaleX)"
                From="1.2" To ="1" Duration="0:0:0.3"
                BeginTime="0:0:0.3"/>
            <DoubleAnimation
                Storyboard.TargetName="codebehindbutton"
                Storyboard.TargetProperty="(Button.RenderTransform).(ScaleTransform.ScaleY)"
                From="1.2" To ="1" Duration="0:0:0.3"
                BeginTime="0:0:0.3"/>
        </Storyboard>
  

So, there’s a few things to note here:
– The storyboard is not part of the button definition; it’s actually part of the Window.Resources.
– We don’t use a named transition, but instead, specify the button name; however, we still have to tell the button that it has a transition:


    <Button Name ="codebehindbutton" Width="200" Height="150" Click="Button_Click" BorderThickness="2" Content="Don't Click Me">
          <Button.RenderTransform>
              <ScaleTransform 
                         ScaleX="1" ScaleY ="1" CenterX="100" CenterY="175"  />
          </Button.RenderTransform>
    </Button>

Generally speaking, there’s nothing new. The same transformation, the same effect; the only difference is that it’s defined as a resource for the Window rather than for the Button.

So, now we get to the crux; now that it doesn’t fire on a button event, how does it get fired? As usual with these things, it’s surprisingly easy when you look at the code:

    Storyboard sb = (Storyboard )FindResource("sbExpand");
    sb.Begin( this);

You also have access to the storyboard itself; for example, try this:

    Storyboard sb = (Storyboard )FindResource( "sbExpand");
    sb.AutoReverse = true;
    sb.Begin( this);

Multiple Animations

Cool eh?

Additionally, if you had two animations to start at the same time; this would be the way. For example, add the following label to your page:

         <Label x :Name="lblHello" Content="Spin Me!" Margin ="50,152,417,250" Width="50" Height="30"
               RenderTransformOrigin="0.5,0.5">
            <Label.RenderTransform>
                <RotateTransform/>
            </Label.RenderTransform>
        </Label>

And the following storyboard definition:

         <Storyboard x :Key="sbdLabelRotation">
            <DoubleAnimation
              Storyboard.TargetName="lblHello"
              Storyboard.TargetProperty="(Label.RenderTransform).(RotateTransform.Angle)"
              From="0"
              To="360"
              Duration="0:0:3"
              RepeatBehavior="4x" />
        </Storyboard>

(This was taken from the Laurent Bugnion article on the same subject http://www.galasoft.ch/mydotnet/articles/article-2006102701.aspx).

Now, try running both animations together:

             Storyboard sb = (Storyboard )FindResource("sbExpand");           
            sb.Begin( this);

             Storyboard sbdLabelRotation = (Storyboard)FindResource("sbdLabelRotation" );
            sbdLabelRotation.Begin( this);

Conclusion

So, both animations run at the same time. Admittedly, I’m not strictly sure what you could do with this particular animation; it’s certainly not my intention that WPF apps start taking a mid ’90s web-site feel!

In this article, we looked at controlling pre-defined storyboard definitions in code. In a future article, I intend to cover the creation of an animation from within code.

Animation in XAML (Part 1)

Introduction

I recently wrote a little application in WPF, which displayed a button. I thought it would be nice to have the button “burst” onto the screen, which is unlike me… normally the screen looks like it looks, or it looks like a command prompt (apparently not everything can be a console app).

When looking around on the web, I found very little information about this. What I did find was a mixture of code that didn’t work, wasn’t explained, or both. As you may have gathered from the previous paragraph; I’m no expert in this, but I’m going to try and collate my findings into a series of posts.

Button Animation using WPF with no code-behind

So here’s the code for creating a button in WPF (you might want to sit down, as the technical brilliance of this XAML may make you dizzy):

             <Button Width ="200" Height="150" name="testbutton">
                Don't Click Me               
            </Button>

I know, and still no call from Microsoft to go there as a consultant! Anyway, believe it or not, there’s more. I want to make the button expand as it’s loaded; so an event trigger allows me to do this quite easily (this is inside the button definition):

    <Button.Triggers>
        <EventTrigger RoutedEvent ="Button.Loaded">

So, anything in this event should fire when the button is loaded. What I want to fire is an animation. In WPF terms, this is a storyboard; basically, that’s just a collection of animations. The storyboard definition is inside the trigger:

<BeginStoryboard>
     <Storyboard>

The expanding animation looks something like this:

                                
                                <DoubleAnimation
                                    Storyboard.TargetName="MyAnimatedScaleTransform"
                                    Storyboard.TargetProperty="(ScaleTransform.ScaleX)"
                                     From="0" To ="1" Duration="0:0:0.2"/>
                                <DoubleAnimation
                                    Storyboard.TargetName="MyAnimatedScaleTransform"
                                    Storyboard.TargetProperty="(ScaleTransform.ScaleY)"
                                     From="0" To ="1" Duration="0:0:0.2"/>;
  

So what have I told it there? I’ve told it that I want to animate a double value (i.e. a floating point number) – DoubleAnimation; I’ve told it that I want to change a property within something called “MyAnimatedScaleTranform” (more on this in a minute); and that the property is called “ScaleTransform.ScaleX” (“ScaleTransform.ScaleY” for the second one). I’ve then told it what to change that property from and to, and how long to take.

Okay, so we now have a button, a storyboard and an animation that tells it what to do; but that’s not all – remember MyAnimatedScaleTranform from the last paragraph? The problem is that WPF doesn’t know what ScaleTransform is, and so inside the button definition we need to define that. Here’s the full code for the button:

<Button
  Name="testbutton"
  Width="200" Height="150">
    Don't Click Me               
    <Button.RenderTransform>                    
        <ScaleTransform x :Name="MyAnimatedScaleTransform"
              ScaleX="1" ScaleY ="1" CenterX="100" CenterY="75"  />
    </Button.RenderTransform>                
    <Button.Triggers>
        <EventTrigger RoutedEvent ="Button.Loaded">
             <BeginStoryboard>
                 <Storyboard>
                     <DoubleAnimation
                         Storyboard.TargetName="MyAnimatedScaleTransform"
                         Storyboard.TargetProperty="(ScaleTransform.ScaleX)"
                         From="0" To ="1" Duration="0:0:0.2"/>
                     <DoubleAnimation
                         Storyboard.TargetName="MyAnimatedScaleTransform"
                         Storyboard.TargetProperty="(ScaleTransform.ScaleY)"
                         From="0" To ="1" Duration="0:0:0.2"/>
                 </Storyboard>
             </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>

The CentreX and CentreY properties tell it where to grow from (i.e. where the origin is). These values are relative, so you can place this button anywhere on a form and it will still grow from the middle.

So, that should do it… well, it should give you a button that grows into existence; try it. I wanted mine to “pop”, though. So I decided I needed it top grow a bit to big, and then correct itself. To make the button grow too big is easy-peasy:

From ="0" To ="1.2"

Now it grows too big. So it needs to get smaller; that’s “drink me” isn’t it:

                                 <DoubleAnimation
                                    Storyboard.TargetName="MyAnimatedScaleTransform"
                                    Storyboard.TargetProperty="(ScaleTransform.ScaleX)"
                                     From="1.2" To ="1" Duration="0:0:0.1">
                                <DoubleAnimation
                                    Storyboard.TargetName="MyAnimatedScaleTransform"
                                    Storyboard.TargetProperty="(ScaleTransform.ScaleY)"
                                     From="1.2" To ="1" Duration="0:0:0.1">

Add those after the existing two `DoubleAnimation` elements and run again. At first glance, it would appear that they will execute in sequence; but of course if they did, you would have seen the X co-ordinate expand before the Y. What, in fact, happens, is the last animation wins and it just contracts.

With no small help from a well known site that allows programmers to ask questions of other programmers, with the intention of writing a blog post and passing the knowledge off as their own, I found this little trick. There is a `BeginTime` property of DoubleAnimation:

                                 < DoubleAnimation
                                    Storyboard.TargetName="MyAnimatedScaleTransform"
                                    Storyboard.TargetProperty="(ScaleTransform.ScaleX)"
                                     From ="1.2" To ="1" Duration="0:0:0.1"
                                                            BeginTime="0:0:0.2"/>
                                < DoubleAnimation
                                    Storyboard.TargetName="MyAnimatedScaleTransform"
                                    Storyboard.TargetProperty="(ScaleTransform.ScaleY)"
                                     From ="1.2" To ="1" Duration="0:0:0.1"
                                                            BeginTime="0:0:0.2"/>

Now try it – good eh? You can play with the “pop”, make it grow bigger, or smaller. There’s even a repeat property.

Conclusion

I intend this to be the first in a few posts on animation. Next, I intend to write about how you would do the same thing using code; and later, I’ll look at how this all works in WinRT (I’ll give you a clue – it’s not the same!).