» ,

Microsoft Advertising Ad Vision Tool

Microsoft Ad Vision Tool, made with Silverlight

Microsoft Ad Vision Tool, made with Silverlight

Last July I had the pleasure of creating my second Silverlight app for Microsoft Advertising (You can read about the first one here) while working at VCCP. This Silverlight tool lets you view and filter videos from the Ad Vision series in an easy to use and visually engaging way.

 

Turning scamps into designs

This time around a creative team was involved and came to the briefing with a scamp (Thanks Ant & Rich!). “We’d like the videos to float in 3D space… and can you put some controls down the left to filter them according to date or who is in them.” Sure, that sounds great ;-).

Here’s the designs exported from Adobe Illustrator.

Ad Vision Tool design with videos floating in 3D space

Ad Vision Tool design with videos floating in 3D space

If you don’t want to filter the videos the panel on the left will slide out of the way so you can enjoy the videos clutter free.

Filter the videos with options on the left

Filter the videos with options on the left

Note the inclusion of the search box. This was removed in development. Unless the users were familiar with the speakers, or we included topics in the tagging, it wasn’t that useful.

Interesting quotes from the videos are highlighted

Interesting quotes from the videos are highlighted

Actually the zoomed in ‘quote’ plaque didn’t make it into the development. Clicking the plaque takes you to the video that the quote is from.

Watch videos streamed from MSN Video

Watch videos streamed from MSN Video

All videos are hosted on MSN Video and streamed in by the custom XAML video player. With some visual trickery the plaque in space is tweened using a XAML storyboard animation and swapped to the fixed position video player at the end.

 

Linq, XML and plaques

Linq is great for importing XML. All the plaque data and text (including buttons) are stored and updated in XML. Here’s a sample.

<plaque ref="plaque7" type="quote">
  <quote><![CDATA["I'm most excited about the merging of the physical and digital world."]]></quote>
  <cite><![CDATA[Trevor Kaufman]]></cite>
</plaque>

<plaque ref="plaque7" type="hidden">
  <title><![CDATA[Interview with Trevor Kaufman, CEO of Possible Worldwide]]></title>
  <desc><![CDATA[Trevor Kaufman on the future of digital creativity and keeping up with the pace of change.]]></desc>
  <video><![CDATA[mms://….wmv]]></video>
  <speaker><![CDATA[Trevor Kaufman]]></speaker>
  <thumb><![CDATA[/images/thumbs/thumb_7.jpg]]></thumb>
  <tag><![CDATA[Interviews]]></tag>
  <date year="2011" month="5" day="17" />
</plaque>

There are three types of plaques, quote, hidden and video. When clicked a quote plaque will use the ref attribute to animate to a video. The reference should match a hidden plaque’s reference. Hidden plaques are otherwise the same as the video ones.

The speaker, tag and date nodes are used by the filtering tools.

 

Zoom slider

The most exciting part of this project was creating the custom slider for zooming through the videos in 3D space. This was done by extending the default Slider control, appropriately named ‘ZoomSlider’. An extra dependency property (UpdateTicksHeight) was added to update the height, and tick marks along the slider, whenever the videos are filtered. Here’s the C#.

…
namespace AdVisionTool.View
{
  public class ZoomSlider : Slider
  {
    public static readonly DependencyProperty UpdateTicksHeightProperty = DependencyProperty.Register("UpdateTicksHeight", typeof(double), typeof(ZoomSlider), new PropertyMetadata(UpdateTicksHeight_Changed));

    private double _height { get; set; }

    public double UpdateTicksHeight
    {
      get { return (double)GetValue(UpdateTicksHeightProperty); }
      set { SetValue(UpdateTicksHeightProperty, value); }
    }

    public ZoomSlider()
    {
      DefaultStyleKey = typeof(ZoomSlider);
      this.Loaded += new RoutedEventHandler(ZoomSlider_Loaded);
    }

    private void ZoomSlider_Loaded(object sender, RoutedEventArgs e)
    {
      _height = base.ActualHeight;
    }

    public override void OnApplyTemplate()
    {
      AddOrUpdateTicks();
      base.OnApplyTemplate();
    }

    private void ZoomSlider_LayoutUpdated(object sender, EventArgs e)
    {
      AddOrUpdateTicks();
    }

    private void AddOrUpdateTicks()
    {
      Grid ticksOuter = (Grid)GetTemplateChild("VerticalTrackTicksOuter");
      Grid ticksInner = (Grid)GetTemplateChild("VerticalTrackTicksInner");
      Thumb thumb = (Thumb)GetTemplateChild("VerticalThumb");

      if (ticksOuter != null && ticksInner != null)
      {
        // remove any ticks from previous updates
        if (ticksOuter.Children.Count > 0)
          while (ticksOuter.Children.Count > 0) 
            ticksOuter.Children.RemoveAt(0);

        if (ticksInner.Children.Count > 0)
          while (ticksInner.Children.Count > 0) 
            ticksInner.Children.RemoveAt(0);

        GradientStopCollection stops = new GradientStopCollection();
        GradientStop stop1 = new GradientStop();
        GradientStop stop2 = new GradientStop();
        stop1.Color = Color.FromArgb(255, 242, 242, 242);
        stop2.Color = Color.FromArgb(255, 204, 204, 204);
        stop1.Offset = 0;
        stop1.Offset = 1;
        stops.Add(stop1);
        stops.Add(stop2);
        LinearGradientBrush grad = new LinearGradientBrush(stops, 90);

        int h = Convert.ToInt32(Math.Floor(_height / 20));

        // add ticks 
        for (int i = 0; i < h; i++)
        {
          Rectangle r = new Rectangle();
          r.SetValue(NameProperty, "TickOuter_" + i);
          r.Height = 3;
          r.Width = 11;
          r.HorizontalAlignment = HorizontalAlignment.Center;
          r.VerticalAlignment = VerticalAlignment.Top;
          if (i==0)
             r.Margin = new Thickness(0, 4, 0, 0);
          else
            r.Margin = new Thickness(0,i*((_height-11)/(h-1))+4,0,0);
          r.Fill = grad;
          ticksOuter.Children.Add(r);

          Rectangle g = new Rectangle();
          g.SetValue(NameProperty, "TickInner_" + i);
          g.Height = 1;
          g.Width = 9;
          g.HorizontalAlignment = HorizontalAlignment.Center;
          g.VerticalAlignment = VerticalAlignment.Top;
          if (i == 0)
            g.Margin = new Thickness(0, 5, 0, 0);
          else
            g.Margin = new Thickness(0,i*((_height-11)/(h-1))+5,0,0);
          g.Fill = new SolidColorBrush(Colors.Black);
          ticksInner.Children.Add(g);
        }
      }
    }

    public static void UpdateTicksHeight_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
      ZoomSlider slider = (ZoomSlider)d;
      slider._height = (double)e.NewValue;
      slider.AddOrUpdateTicks();
    }

  }
}

 

Most of the Microsoft Advertising website has gone all HTML 5. The Ad Vision Tool is no longer available. For those of you with the Silverlight 4 or higher plug-in I’ve placed a copy link. :-)

Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>