f8g

XAMLからJavaScriptへ

http://d.hatena.ne.jp/arikui/20071121/1195578254
の続き。@ITのサンプルXAMLの中のTextBlockを全てJavaScriptで作る。
元のXAML(サンプルから少し変更)

<TextBlock
  Width="304" Height="51" TextWrapping="Wrap"
  FontFamily="Arial" FontSize="48" FontWeight="Bold"
  Text="Hello World!!" RenderTransformOrigin="0.5,0.5"
>
  <TextBlock.Foreground>
    <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
      <GradientStop Color="#f00" Offset="0"/>
      <GradientStop Color="#0f0" Offset="0.5"/>
      <GradientStop Color="#00f" Offset="1"/>
    </LinearGradientBrush>
  </TextBlock.Foreground>
  <TextBlock.RenderTransform>
    <TransformGroup>
      <ScaleTransform ScaleX="-1" ScaleY="3"/>
      <SkewTransform AngleX="10" AngleY="10"/>
      <RotateTransform Angle="30"/>
      <TranslateTransform X="0" Y="150"/>
    </TransformGroup>
  </TextBlock.RenderTransform>
</TextBlock>

JavaScriptで。

// Canvas読み込み時に実行される関数
function Canvas(sender, args){
	var plugin = sender.getHost();

	// TextBlockオブジェクトを作る。
	var text = plugin.content.createFromXAML((new Silverlight.XAML("TextBlock", {
		Width       : 304,
		Height      : 51,
		TextWrapping: "Wrap",
		FontFamily  : "Arial",
		FontSize    : 48,
		FontWeight  : "Bold",
		Text        : "Hello World!!",
		RenderTransformOrigin:"0.5,0.5"
	})).toString());

	// TextBlockのプロパティ
	var propterties = {
		Foreground     : new Silverlight.XAML("LinearGradientBrush", {EndPoint: "1,0.5", StartPoint: "0,0.5"}),
		RenderTransform: new Silverlight.XAML("TransformGroup", {})
	};

	for(var x in propterties)
		text[x] = plugin.content.createFromXAML(propterties[x].toString());

	// transform
	var transforms = {
		ScaleTransform    : {ScaleX: -1, ScaleY: 3},
		SkewTransform     : {AngleX: 10, AngleY: 10},
		RotateTransform   : {Angle: 30},
		TranslateTransform: {X: 0, Y: 150}
	};

	for(var x in transforms){
		text.renderTransform.children.add(
			plugin.content.createFromXAML(
				(new Silverlight.XAML(x, transforms[x])).toString()
			)
		);
	}

	// gradient
	var gradients = [
		{Color: "#f00", Offset: 0  },
		{Color: "#0f0", Offset: 0.5},
		{Color: "#00f", Offset: 1  }
	];

	for(var i = 0, l = gradients.length; i < l; i++){
		text.foreground.gradientStops.add(
			plugin.content.createFromXAML(
				(new Silverlight.XAML("GradientStop", gradients[i])).toString()
			)
		);
	}
	sender.children.add(text);
}

ところで、sender.getHost()ってのは何なのかというと、DOMでSilverlightをブッ込んだときのObjectエレメント。なので、

alert(sender.getHost() == document.getElementById("silverlightControl"));
// true

Canvasオブジェクトにグローバルからアクセスしたいときは、

function Canvas(sender, args){
    arguments.callee.self = sender;
}

とかやれば、どっからでも使えますね。
図を描くとかならJavaScriptだけでも色々できるということでした。IronPythonJavaScriptから使うとかは分からん。

  • 追記

コードばっかりじゃ分かりづらいと思うので、実行した結果。
http://gyazo.com/aa7960a75bf3a1d51c39a0bcf8c8db88.png
ScaleTransformのScaleXを-1にしているので文字が反転してます。全体的にスケールを変えたい場合は、TextBlockの親の、CanvasのTransformを変えればあとから追加したのにも全部適用されます。地図作るときに便利。