HTML5テクニカルノート EaselJSの次期バージョンにおけるオブジェクトの幅と高さの取得
EaselJSのDisplayObjectインスタンスについては、基本的にオブジェクトの幅や高さが調べられません。CreateJS Blogの記事「Width & Height in EaselJS」にそれが難しい理由と、次期バージョン(NEXT)に備わる簡易的なメソッドが紹介されました。その記事にもとづいて解説します。 01 Shapeオブジェクトベクターシェイプは大きな課題のひとつです。ちょっと考えると、境界領域を求めるのは、さほど難しくないように感じられます。すでにあるShapeオブジェクトのデータは変わりませんから、新たなパスが加わったときにその範囲を調べて、最大値・最小値から改めて矩形領域を決めればよさそうです。 単純な直線くらいでしたら、それでよいでしょう(図001左図)。けれど、線に加えられるプロパティの様々な定めを考えると、たちまち複雑になります。線幅を20ピクセルにすれば、端の増減する領域を三角関数で計算しなければなりません(図001中左図)。しかも、端のかたち(buttやsquare、あるいはround)も考え合わせなければなりません(「EaselJSのGraphicクラスで2次ベジエ曲線を描く」表001参照)。 図001■連続した座標を軌跡として描く 20ピクセルの線を曲げると、領域の計算はさらに難しくなります。数学的にはできるとしても、線の幅や2次ベジエと3次ベジエを正確に計算することが求められます。曲線の端の角度も求めなければ、正しく領域が定められません(図001中右図)。 線の角のかたち(bevelやround、あるいはmiter)も、忘れてはいけません(前出「EaselJSのGraphicクラスで2次ベジエ曲線を描く」表002参照)。さらに、線の角のとがり方(miterLimit)の計算も含まれます(図001右図)。 これらすべての計算ができたとしても、きわめて負荷は高くなります。そこまでしても、実装すべきかどうかが問われます。 02 オブジェクトの変形オブジェクトの変形について考えます。コンテンツを境界ボックスで囲み、それを変形すればよいのでしたら、計算は楽です。境界ボックスの四角を変形して、新たな矩形領域を決めればよいからです。けれど、ベクターシェイプではそうはいきません。 つぎの図002の左のような単純な曲線を、45度回したとします。境界ボックスの四角から新たな矩形領域を求めれば、図002の真ん中のようになってしまいます。しかし、正しい領域は図002の右のように定めなければならないでしょう。 図002■ベクターシェイプを変形したときの矩形領域 すると、シェイプ上の適切な点すべてについて、変換行列の演算を行わなければなりません。点を間引くロジックで処理が減らせるとしても、負荷は高いでしょう。とくに、表示リストの異なる階層から領域を調べると、座標空間ごとに計算はし直すことになります。 03 TextオブジェクトTextオブジェクトの扱いは、さらに難しくなります。CanvasのテキストのAPIからは、領域を求めることができません。ただ、幅は調べられるので、テキストの配置にもとづいて正しくオフセットできます。 高さは求められません。そこで、正確には程遠いものの、文字「M」の幅から推測することが考えられます。高さが大まかにでも捉えられれば、Text.textBaselineプロパティ(次期バージョンから値は、"top"と"hanging"、"middle"、"alphabetic"、"ideographic"、および"bottom"の6つ)にもとづいてオフセットが決められます。 図003■Text.textBaselineプロパティの設定 Textオブジェクトの矩形領域は、今のところ求められません。Canvas APIは新たにテキストのメトリクスを拡張したので、この計算ができるようになります。ただし、今のところサポートするブラウザがありません。 04 次期バージョンでgetBounds()メソッドが備わるDisplayObjectインスタンスの矩形領域は、今のところ調べる手段を備えるのは難しいようです。その代わり、次期バージョンに簡易なメソッドとして、SpriteおよびBitmapクラスにgetBounds()が加わります[*1]。つぎのようなことが考えられています。
記事「Width & Height in EaselJS」では、このような考えに対して混乱や不満が生じないか、ユーザーの意見を求めています。
作成者: 野中文雄 Copyright © 2001-2013 Fumio Nonaka. All rights reserved. |
|||||