Hatena::ブログ(Diary)

latest log このページをアンテナに追加 RSSフィード

2009-10-29

canvas 周りの I/F を変更しました。

window.uudraw を window.xcanvas に、window.uuboot を window.xboot に変更しました。

uupaa.js / uuCanvas.js コードリード用のエントリです。

I/F をスッキリさせたかった → Silverlight初期化周りの問題を解決した

Silverlight初期化処理を非同期から同期処理に書き換えることが出来たので、uuCanvas.js初期化系の I/F を変更します。

経緯とか、何が問題だったのか とか

uuCanvas.js は元々「excanvas.js の機能不足を何とかしよう」を基点にスタートしたプロジェクトです。

excanvas.js は動的に生成した canvas の利用にちょっとしたコツが必要で document.body.appendChild(document.createElement("canvas")) するだけでは canvas を利用できず、G_vmlCanvasManager.initElement(node) で初期化にする必要があります。また初期化タイミングもユーザが意識する必要があるなど、慣れが必要です。

uuCanvas.js も同様に、 uuCanvas.init(node) で初期化する必要がありましたが、今回はそういうのを無くしてスッキリさせました。

変更前の I/F

uuCanvas.js version 1.0.x では、このような I/F を出しています。

  • uuCanvas.init
  • uuCanvas.ready
    • uuCanvas.ready(fn) は レンダリングが可能になったタイミングで fn をコールバックします。
  • uuCanvas.already
    • uuCanvas.already() は ページ上の全ての canvas が使用可能なら true を返します。

このような I/F になっているのは、

という理由からです。

変更後の I/F

このようにしました。

  • uu.canvas(var_args)
    • 初期化済みの(すぐに利用可能な) canvas 要素を返します。uu.canvas("width,300,height,150") とするとサイズ付きで生成します。他の属性やスタイルも生成時に一緒に指定できます。
  • document.createElement("canvas")
  • document.createElement("canvas", 1)
  • uu.canvas.init()
    • ライブラリの遅延ロード(ページをロードしてから2秒後にライブラリAjaxで読み込むとか)した際に呼び出すと、ページに存在する <canvas> 要素を探し、色々と必要な処理を行います。
  • window.xcanvas = function(uu, CanvasNodeList) { ... 描画処理 ... }

インライン XAML は基本的に不要に

XAML 用のコード(↓)を埋め込む必要はなくなりました。

  <script type="text/xaml" id="xaml"><?xml version="1.0"?>
        <Canvas xmlns="http://schemas.microsoft.com/client/2007"></Canvas></script>

# 埋め込んだままでも問題ありません。

2009-10-29 追記

ライブラリの遅延ロードを行う場合は、従来どおり ページ内に inline XAML を埋め込んでおく必要があります。

<!doctype html><html><head><title>lazyLoad</title>
<!--
<script type="text/javascript" src="../uupaa.js"></script>
 -->
<script type="text/xaml" id="xaml"><?xml version="1.0"?>
  <Canvas xmlns="http://schemas.microsoft.com/client/2007"></Canvas>
</script>
    <script>
      function jsloader() {
        lazyLoad("../uupaa.js", function() {
            drawShape(document.getElementById('canvas'));
            drawShape(document.getElementById('vmlcanvas'));
        });
      }
   :
   :
変更前

uuCanvas.js 1.0.x 用のコード

<!doctype html><html><head>
  <title>Hello HTML5::Canvas world</title>
  <script type="text/xaml" id="xaml"><?xml version="1.0"?>
        <Canvas xmlns="http://schemas.microsoft.com/client/2007"></Canvas></script>
  <script src="../uuCanvas.js"></script>
  <script>
  window.onload = function() {
    uuCanvas.ready(function() {
      var ctx = document.getElementById("canvas").getContext("2d");
         :
    });
  }
  </script>
</head><body>
  <div>
    <canvas id="canvas"></canvas>
  </div>
</body></html>
変更後

uupaa.js 0.7 用のコード

<!doctype html><html><head>
  <title>Hello HTML5::Canvas world</title>
  <script src="../uupaa.js"></script>
  <script>
  function xcanvas(uu, canvas) {
    var ctx = canvas[0].getContext("2d");
         :
  }
  </script>
</head><body>
  <div>
    <canvas></canvas>
  </div>
</body></html>

動的に canvas を生成する

uuCanvas.js 1.0.x 用のコード

<!doctype html><html><head>
  <title>Hello HTML5::Canvas world</title>
  <script type="text/xaml" id="xaml"><?xml version="1.0"?>
        <Canvas xmlns="http://schemas.microsoft.com/client/2007"></Canvas></script>
  <script src="../uuCanvas.js"></script>
  <script>
  window.onload = function() {
    var node1 = document.createElement("canvas"), node2;

    node2 = uuCanvas.init(node1); // 初期化したノードを受け取る(node1 と node2 は別物)

    document.body.appendChild(node2); // node2 を <body> に追加(node1 ではダメ)

    var ctx = canvas.getContext("2d");
         :
  };
  </script>
</head><body></body></html>

uupaa.js 0.7 用のコード

<!doctype html><html><head>
  <title>Hello HTML5::Canvas world</title>
  <script src="../uupaa.js"></script>
  <script>
  function xboot(uu) {
    var node, ctx;

    uu.body(node = uu.canvas()); // <canvas> の生成と、<body> への appendChild

    ctx = node.getContext("2d");
         :
  }
  </script>
</head><body></body></html>

反省会

  • I/F の大幅修正により互換性が無くなりました。
    • uuCanvas.js へのバックポートはしていません。
  • これらの修正と共に、Silverlight モードのレンダリング速度向上と bugfix も行っています。
  • 非同期を同期に書き換えた方法はソースを読んで下さい。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト

コメントを書くには、なぞなぞ認証に回答する必要があります。

トラックバック - http://d.hatena.ne.jp/uupaa/20091029/1256786633