Latest Article:

My Tags:

Silverlight With Java Script Tutorial 09 - Modifying Radial Gradient Parameters at Run-Time

Overview

As I was playing with the Radial Gradient in Tutorial 08, I saw something I wanted to investigate further, and while I was at it, I figured it would make a good tutorial in it's own right.

The investigation this time involves moving the Origin of the Radial Gradient with the mouse at run-time.

As always, I'd like to give a reference to the Microsoft Silverlight SDK Online.

Our XAML

Here is the XAML for the canvas above:

`<Canvas   xmlns="http://schemas.microsoft.com/client/2007"   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">    <TextBlock x:Name="Origin" Canvas.Left="0" Canvas.Top="0" Foreground="Blue" Text="GradientOrigin=.5, .5"/>    <Rectangle x:Name="RadialGradient" Canvas.Left="0" Canvas.Top="40" Width="300" Height="150"  Cursor="Hand" MouseLeftButtonDown="GradientMouseDown" MouseLeftButtonUp="GradientMouseUp" MouseMove="GradientMouseMove">        <Rectangle.Fill>              <RadialGradientBrush x:Name="GradientBrush" GradientOrigin=".5, .5">                 <GradientStop Color="White" Offset="0.0" />                 <GradientStop Color="Blue" Offset="1.0" />              </RadialGradientBrush>        </Rectangle.Fill>    </Rectangle></Canvas>`

Our HTML

`<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head>    <title>Silverlight With Java Script Tutorial 09</title>    <script src="js/Silverlight.js" type="text/javascript"></script></head><script type="text/javascript">var AnimationRunning = 0;var locX = .5;var locY = .5;var HaveMouse = 0;function GradientMouseDown(sender, args){   HaveMouse = 1;   UpdateLocation(sender, args);}function GradientMouseUp(sender, args){   UpdateLocation(sender, args);   HaveMouse = 0;}function GradientMouseMove(sender, args){   if (HaveMouse == 1)    {      UpdateLocation(sender, args);   }}function UpdateLocation(sender, args){   var yOffset = sender.findName("RadialGradient")["Canvas.Top"];   locX = (args.getPosition(null).x/300).toFixed(2);   locY = ((args.getPosition(null).y-yOffset)/150).toFixed(2);   var Center = locX.toString() +  "," + locY.toString();   sender.findName("GradientBrush").GradientOrigin= Center;   sender.findName("Origin").Text="GradientOrigin=\""+Center+"\"";}</script><body bgcolor="white"><br />  <center>     <div id="Ag1Host" style="background:#FFFFFF">        <script type="text/javascript">           var pe1 = document.getElementById("Ag1Host");        </script>     </div>  </center><script type="text/javascript">Silverlight.createObjectEx({source: 'xaml/SilverlightWithJSTutorial09.xml', parentElement:pe1, id:'Ag1', properties:{width:'300', height:'200', background:'#00FFFFFF', isWindowless:'true', framerate:'24', version:'0.90.0'}, events:{onError:null, onLoad:null}, context:null});</script></body></html>`

As I moved the origin of the radial gradient around in the bounding rectangle, I didn't quite get the results I was expecting. I'm not sure what I expected, and the results are very explainable, so I suppose it's just an interesting item to keep in mind.

As the gradient is displayed outward from it's origin, it does not continue to expand to fill the bounding shape, or it doesn't quite do that. As it expands, once a border is reached, the gradient will assume a shape based upon that border.

This is MUCH easier to see by playing with the canvas above.

When the page is refreshed, the origin is set to the center of the rectangle and that is the location of the greatest intensity of the Start color, in the case of this demonstration, White. I have the Stop color set to Blue, and an offset of 1, causing the color to not quite make it to full Blue by the time the rectangle's borders are reached. This fade is important as the Origin is moved.

Clicking the mouse somewhere in the rectangle will cause the Origin to be set to that point. As you click off-center and toward the corners, you will begin to see the fade of the gradient to be not equal in all directions.

Holding the mouse down and moving it will demonstrate this to a greater extent.

As the origin is moved closer to one of the corners, an interesting effect appears making the gradient be more of a 'spotlight' than a radial.

The Code

The XAML for this canvas is very simple, actually less than that of Tutorial 08, but the Java Script this time is a bit more involved.

Introduced this time is the MouseMove event.

Because we're only concerned with the location of the mouse as it is moving, we don't have to worry about 'capturing' the mouse as we would in, for example, a drag-and-drop situation.

We do need to keep track of the fact that the mouse is down so that we know when to allow the MouseMove event to cause changes on our canvas. To that end, I have defined a global variable, "HaveMouse" that is set to 1 if the left mouse is down, and 0 when it is released.

If, during a MouseMove message, "HaveMouse" is 1, then we allow the Origin to be updated.

The same code is called on MouseDown, MouseUp, and MouseMove for updating and displaying the Origin information.

The mouse location is normalized to the location of the rectangle to get a true value for the x,y coordinates, and the values are calculated to 2 decimal places.

The Display

Playing with the display values for the origin, I found I could embed an escape sequence in the Java Script to put in the double quotes used in the XAML. I couldn't include the escaped character in the XAML, but as soon as the origin moves, the quotes appear.

Summary

I found this bit of radial gradient trivia to be interesting and I hope you did as well.

Worst-case is that you can use the canvas, or something like it, to decide where you want to place a radial gradient origin :)

I ended up going way overboard as I was working on this tutorial, and decided to strip it down and use the code I removed for an interesting App that I will post soon.

Keep Having (Silverlight) Fun!