IanG on Tap

Ian Griffiths in Weblog Form (RSS 2.0)

Blog Navigation

July (2014)

(5 items)

April (2014)

(1 item)

March (2014)

(1 item)

January (2014)

(2 items)

November (2013)

(2 items)

July (2013)

(4 items)

April (2013)

(1 item)

February (2013)

(6 items)

September (2011)

(2 items)

November (2010)

(4 items)

September (2010)

(1 item)

August (2010)

(4 items)

July (2010)

(2 items)

September (2009)

(1 item)

June (2009)

(1 item)

April (2009)

(1 item)

November (2008)

(1 item)

October (2008)

(1 item)

September (2008)

(1 item)

July (2008)

(1 item)

June (2008)

(1 item)

May (2008)

(2 items)

April (2008)

(2 items)

March (2008)

(5 items)

January (2008)

(3 items)

December (2007)

(1 item)

November (2007)

(1 item)

October (2007)

(1 item)

September (2007)

(3 items)

August (2007)

(1 item)

July (2007)

(1 item)

June (2007)

(2 items)

May (2007)

(8 items)

April (2007)

(2 items)

March (2007)

(7 items)

February (2007)

(2 items)

January (2007)

(2 items)

November (2006)

(1 item)

October (2006)

(2 items)

September (2006)

(1 item)

June (2006)

(2 items)

May (2006)

(4 items)

April (2006)

(1 item)

March (2006)

(5 items)

January (2006)

(1 item)

December (2005)

(3 items)

November (2005)

(2 items)

October (2005)

(2 items)

September (2005)

(8 items)

August (2005)

(7 items)

June (2005)

(3 items)

May (2005)

(7 items)

April (2005)

(6 items)

March (2005)

(1 item)

February (2005)

(2 items)

January (2005)

(5 items)

December (2004)

(5 items)

November (2004)

(7 items)

October (2004)

(3 items)

September (2004)

(7 items)

August (2004)

(16 items)

July (2004)

(10 items)

June (2004)

(27 items)

May (2004)

(15 items)

April (2004)

(15 items)

March (2004)

(13 items)

February (2004)

(16 items)

January (2004)

(15 items)

Blog Home

RSS 2.0

Writing

Programming C# 5.0

Programming WPF

Other Sites

Interact Software

Animating Custom Types in Avalon

Thursday 2 December, 2004, 03:49 PM

DirectX guru Brandon Furtwangler recently posted a blog on his experiments with Avalon animation. His example zooms in on some text, and reveals a little bit about how Avalon renders stuff internally - the way he scales the text up reveals some tesselated rendering artifacts. (I'm guessing the final product won't exhibit this behaviour by the way - I suspect Brandon has simply uncovered a rough edge in the current preview implementation.)

He then goes on to say this:

"FontSize is not animatable. You typically just set FontSize with a number like FontSize="32" but it is not actually a number, but rather a structure. This means you cant use DoubleAnimation or Int32Animation of anything on it. I think they should have a FontSizeAnimation."

I thought it would be interesting to see if I could address this limitation, so I wrote my own FontSizeAnimation:

using System;
using System.Windows;
using System.Windows.Media.Animation;

namespace AnimLib
{
    public class FontSizeAnimation : AnimationTimeline
    {
        // The animation system will call this when the element
        // tree is built to make sure that we are going to be
        // returning the right kind of data.

        public override Type BaseValueType
        {
            get { return typeof(FontSize); }
        }


        // I don't know what this does, but it's abstract, so we
        // have to override it...

        protected override bool UsesBaseValueCore
        {
            get { return false; }
        }


        // This is where we do the actual animation work.
        // We are passed a clock to indicate the point in time
        // for which we are generating a FontSize.

        protected override object GetValueCore(object baseValue,
            AnimationClock animationClock)
        {
            double start = fsFrom.Pixels;
            double by = fsTo.Pixels - start;
            double size = start + animationClock.Progress * by;
            return new FontSize(size);
        }


        // Start value

        public FontSize From
        {
            get
            {
                ReadPreamble();
                return fsFrom;
            }
            set
            {
                WritePreamble();
                fsFrom = value;
                WritePostscript();
            }
        }
        private FontSize fsFrom;


        // End value

        public FontSize To
        {
            get
            {
                ReadPreamble();
                return fsTo;
            }
            set
            {
                WritePreamble();
                fsTo = value;
                WritePostscript();
            }
        }
        private FontSize fsTo;
    }
}

This isn't quite complete - for consistency with the built-in animation classes, I should really have supported From, To, and By properties, but I was just aiming for a proof of concept here. It lets you write this kind of thing in XAML:

<?Mapping XmlNamespace="anim" ClrNamespace="AnimLib" Assembly="AnimLib"?>
...
<Canvas xmlns:anim="anim">
    <Text>
        <Text.FontSize>
            <anim:FontSizeAnimation From="12" To="360" Duration="5"
                     AutoReverse="True" RepeatDuration="Indefinite" />
        </Text.FontSize>
    Hello</Text>
</Canvas>

(I'll just wait while the XML purists cringe at my namespace URI. Done? Good.) This particular example requires that you've compiled the code above into a AnimLib.dll class library, and made that accessible to whatever project you're building this XAML code into.

This seems to work fine, but raises a few interesting points. Brendon went on to hypothesize as to why animation of FontSize properties isn't already built in to Avalon:

"I think they dont have it animatable because tesselation is too slow and they can't do it without killing the frame rate."

Well... It's a little clunky on my laptop, but then so is pretty much all animation. It's certainly not awful. What's particularly interesting is that it actually gets smoother once the text goes above a certain size. On closer inspection, it turns out that the current Avalon CTP build only uses ClearType when the text is smaller than some threshold. (Not sure what the exact threshold is, but I'd say it looked about 'medium-sized' to me.) The rendering is faster once ClearType is off, understandably. (Although it's initially a bit surprising to see that the animation is much smoother when the text is large!)

I was also interested to see this after running it for a few minutes:

Font cache service crashing

Oops. :-)

Again, I'm guessing this feature won't be part of the final release.

Copyright © 2002-2013, Interact Software Ltd. Content by Ian Griffiths. Please direct all Web site inquiries to webmaster@interact-sw.co.uk