Programmatic drawing with Silverlight
Posted by Dennis on Feb 19, 2008 in Silverlight • No comments
I’ve finally set myself to doing something with Microsoft’s Silverlight. After reading some of the basic stuff I have to say it looks promising. I can’t wait for C# support though, JavaScript is making my life miserable again :P.
I’ve taken a code sample (written in BASIC) from and old book and converted it to JavaScript. The number of lines drawn and the time taken are displayed on the bottom of the pages to give an idea about the performance.
JavaScript source code
if( typeof com == "undefined" ) com = {};
if( typeof com.rozengain == "undefined" ) com.rozengain = {};
if( typeof com.rozengain.silverlight == "undefined" ) com.rozengain.silverlight = {};
com.rozengain.silverlight.whirl = {
strokeColor : "#990000",
strokeThickness : 1,
control : null,
rootElement : null,
numSides : 3,
/**
* Silverlight initialisation
*/
createSilverlight: function()
{
Silverlight.createObjectEx({
source: "xml/Whirl.xaml",
parentElement: document.getElementById("SilverlightControlHost"),
id: "SilverlightControl",
properties: {
width: "100%",
height: "100%",
version: "1.0"
},
events: {
onLoad: com.rozengain.silverlight.whirl.handleLoad
}
});
},
/**
* Onload event handler
*/
handleLoad: function( cntrl, usrContext, rootElem )
{
var self = com.rozengain.silverlight.whirl;
self.control = cntrl;
self.rootElement = rootElem;
self.drawWhirl();
},
/**
* Draws a whirl shape with n sides
*
* @param {Object} numSides
*/
drawWhirl: function()
{
var x = [];
var y = [];
var startTime = ( new Date() ).getTime();
var scaleFactor = 275;
var self = com.rozengain.silverlight.whirl;
var centerX = self.rootElement.width * .5;
var centerY = self.rootElement.height * .5;
var rotAngle = .05;
var numSides = self.numSides;
var numLinesDrawn = 0;
var rotAngleSin = Math.sin( rotAngle );
var rotAngleCos = Math.cos( rotAngle );
var a = Math.PI * ( 1 - 2 / numSides );
var c = Math.sin( a ) / ( rotAngleSin + Math.sin( a + rotAngle ));
self.rootElement.children.clear();
for( var k = 0; k <= numSides; k++ )
{
var t = ( 2 * k + 1 ) * Math.PI / numSides;
x[ k ] = Math.sin( t );
y[ k ] = Math.cos( t );
}
for (var n = 1; n < 64; n++)
{
var previousPoint = {
x: ( x[ 0 ] * scaleFactor ) + centerX,
y: ( y[ 0 ] * scaleFactor ) + centerY
};
for( var l = 0; l <= numSides; l++ )
{
var newPoint = {
x: ( x[ l ] * scaleFactor ) + centerX,
y: ( y[ l ] * scaleFactor ) + centerY
};
self.drawLine( previousPoint.x, previousPoint.y, newPoint.x, newPoint.y );
numLinesDrawn++;
previousPoint = newPoint;
}
for( var m = 0; m <= numSides; m++ )
{
var z = x[ m ];
x[ m ] = ( x[ m ] * rotAngleCos - y[ m ] * rotAngleSin ) * c;
y[ m ] = ( z * rotAngleSin + y[ m ] * rotAngleCos ) * c;
}
}
document.getElementById( "divInfo" ).innerHTML =
"<strong>Number of sides:</strong> " + numSides + "<br>" +
"<strong>Number of lines drawn:</strong> " + numLinesDrawn + "<br>" +
"<strong>Time:</strong> " + ( ( ( new Date() ).getTime() - startTime ) / 1000 ) + " seconds";
},
/**
* Draw a line between the given points
*
* @param {Object} control
* @param {Object} rootElement
* @param {Object} x1
* @param {Object} y1
* @param {Object} x2
* @param {Object} y2
*/
drawLine : function( x1, y1, x2, y2 )
{
var self = com.rozengain.silverlight.whirl;
var line = self.control.content.CreateFromXaml( '<Line X1="'+x1+'" Y1="'+y1+'" X2="'+x2+'" Y2="'+y2+'" Stroke="'+self.strokeColor+'" StrokeThickness="'+self.strokeThickness+'"/> ');
self.rootElement.children.add(line);
},
/**
* Decreases the number of sides
*/
decreaseNumSides : function()
{
var self = com.rozengain.silverlight.whirl;
if ( self.numSides <= 3 )
{
alert( "The minimum number of sides is 3" );
}
else
{
self.numSides--;
self.drawWhirl();
}
},
/**
* Increases the number of sides
*/
increaseNumSides : function()
{
var self = com.rozengain.silverlight.whirl;
if( self.numSides >= 25 )
{
alert( "The maximum number of sides is 25" );
}
else
{
self.numSides++;
self.drawWhirl();
}
}
};



