Ziff Davis EnterpriseDevLife
Advertisement

Saturday, July 14, 2007 8:00 PM/EST

Cross browser colors with Silverlight

While I was working on my Silverlight tests for drawing on the InkPresenter, I used IE7 and Firefox to test my work. The only cross-browser scripting issue I had was with colors.

In the SilverInk example, I use a color palette that is basically a rectangle with a gradient fill.

When a user clicks on the palette, there is no way to detect which gradient they are selecting. Remember I am using the Beta1 which is limited to Javascript. There is a great .NET implementation (the Scribbler app)that does have the ability to do this very nicely in the Silverlight samples. But I was stuck (by my own choosing) with javascript. The best solution I could come up with was to determine the position of the click in the rectangle and based on the number of Gradient stops in the rectangle, figure out which gradient stop I must be on. I can't get the true gradient so my palette is limited to the initial color of each gradient.

For example, here is how the rectangle is filled. There are 15 gradient stops that make up the fill.

<Rectangle x:Name="HueRect" MouseLeftButtonDown="javascript:ChangeColor" Width="141" Height="21" Stretch="Fill" StrokeMiterLimit="2.75" Stroke="#FF000000" RenderTransformOrigin="0.5,0.5" Canvas.Left="-53" Canvas.Top="69">
<Rectangle.Fill>


<LinearGradientBrush x:Name="HueGradient"  StartPoint="0.996454,0.5" EndPoint="0.0035461,0.5">
<GradientStop Color="#FFFF0000" Offset="0"/>
<GradientStop Color="#FFFFCA25" Offset="0.0821918"/>
<GradientStop Color="#FFBBFF00" Offset="0.155251"/>
<GradientStop Color="#FF22FF00" Offset="0.22831"/>
<GradientStop Color="#FF00FF53" Offset="0.305936"/>
<GradientStop Color="#FF00FFB1" Offset="0.383562"/>
<GradientStop Color="#FF00EFFF" Offset="0.452055"/>
<GradientStop Color="#FF009DFF" Offset="0.534247"/>
<GradientStop Color="#FF0032FF" Offset="0.611872"/>
<GradientStop Color="#FF4F00FF" Offset="0.684932"/>
<GradientStop Color="#FFA200FF" Offset="0.757991"/>
<GradientStop Color="#FFDC00FF" Offset="0.826484"/>
<GradientStop Color="#FFFF00DB" Offset="0.894977"/>
<GradientStop Color="#FFFF007D" Offset="0.954338"/>
<GradientStop Color="#FFFF0000" Offset="1"/>
</LinearGradientBrush>


 

My crazy method for figuring out which one of those gradients the user clicked on looks like this. Note that I inverted the rectangle, so where it says width, think of height:

function ChangeColor(sender,args)
{
currObj=sender;
//width of entire rectangle
rectWidth=currObj.width;
//calculate width for each gradient stop
gradWidth=rectWidth/currObj.Fill.GradientStops.Count;
//determine current X position
currx= args.GetPosition(currObj).x
//determine current gradient stop based on x
currGrad=(currObj.Fill.GradientStops.Count)-Math.round(currx/gradWidth);
if (currGrad==currObj.Fill.GradientStops.Count) currGrad-=1
//current color
currColor=BrowserColorConverter(currObj.Fill.GradientStops.GetItem(currGrad).Color);
currentColor=currColor+'';
}

But all I'm getting is the start colors for each gradient stop. I'm not going to belabor this because when I move to Silverlight .NET the problem will go away.

Once I determine the color, I apply it to the each subsequent stroke that is added to the inkPresenter.

This worked well in IE, but not in Firefox. The color wasn't being rendered properly. I didn't have a problem if I just applied color using hex values like "#FFFF0000" for red. But the color coming back from currObj.Fill.GradientStops.GetItem(currGrad).Color, even though I created the color with hex, was a number.

After a lot of exploration (just to understand what the heck the problem was) and googling, I found a magic number in this post by a guy named Danny Lloyd who writes a weather application. He had changed his software to use ARGB colors and the post was explaining how to convert from hex to ARGB. It had nothing to do with IE vs. Firefox color rendering or javascript. I must have read the post a hundred times before I realized that this was the solution to my puzzle

You can convert from ARGB to the individual components. It is important to remember that if the number is negative, you first need to add 4294967296 (#100000000).

That was the ticket! I created a little function to always use whenever I need to extract colors. Now that I can test Safari in Windows, I found that I need to do the same for Safari as well.

function BrowserColorConverter(jscolorvalue)
{
if(navigator.userAgent.indexOf("Firefox")!=-1 || navigator.userAgent.indexOf("Safari")!=-1)
return 4294967296 + jscolorvalue;
else
return jscolorvalue;
}


TrackBack

TrackBack

http://blogs.devsource.com/cgi-bin/mte/mt-tb.cgi/11309

Post a Comment

 
 

Advertisement

Syndication

Subscribe: