(追記:2023/03/20)
下記、p._drawTextLine メソッドはいじらなくても大丈夫でした
p._prepContext メソッド内だけ、letterSpacing の設定をしてあげれば機能します
CreateJSでカーニングを設定したいと思ってドキュメント見ても設定がなくて、
いろいろ悩んでたら、なんか出来たような
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/letterSpacing
に、letterSpacing は書いてあるのだけど、これを、CreateJSでやると、
全テキストに反映しちゃって、使えん orz
んで、いろいろ悩んでて、createjs.js 本体をいろいろいじってたら出来たような
createjs.js では毎フレーム?の度に
/**
* @method _drawTextLine
* @param {CanvasRenderingContext2D} ctx
* @param {String} text
* @param {Number} y
* @protected
**/
p._drawTextLine = function(ctx, text, y) {
// Chrome 17 will fail to draw the text if the last param is included but null, so we feed it a large value instead:
if (this.outline) { ctx.strokeText(text, 0, y, this.maxWidth||0xFFFF); }
else { ctx.fillText(text, 0, y, this.maxWidth||0xFFFF); }
};
_drawTextLine メソッドが呼ばれてて、ここの最後の行
ctx.fillText(text, 0, y, this.maxWidth||0xFFFF);
これが、毎回呼ばれるので最後に設定した letterSpacing、例えば、
ctx.letterSpacing = "5px";
とすると、この "5px" が毎回全テキストに反映されてしまう
なので、ctx.fillText() の前で、テキスト毎に letterSpacing に再設定してあげれば
個々のテキストに対応できるようになります
んで、こんな感じに変更してみた
/**
* @method _drawTextLine
* @param {CanvasRenderingContext2D} ctx
* @param {String} text
* @param {Number} y
* @protected
**/
p._drawTextLine = function(ctx, text, y) {
// console.log("p._drawTextLine()");
// Chrome 17 will fail to draw the text if the last param is included but null, so we feed it a large value instead:
ctx.save(); // ← これ要らないかも
ctx.letterSpacing = (this.letterSpacing === undefined)? "" : this.letterSpacing + "px";
if (this.outline) {
ctx.strokeText(text, 0, y, this.maxWidth||0xFFFF);
}else{
ctx.fillText(text, 0, y, this.maxWidth||0xFFFF);
}
ctx.restore(); // ← これ要らないかも
};
ctx.letterSpacing = (this.letterSpacing === undefined)? "" : this.letterSpacing + "px";
これを追加
この2行は念のためしてるけど要らないかも、
ctx.save(); // ← これ要らないかも
ctx.restore(); // ← これ要らないかも
これで、個々の Text 毎にカーニングが設定できます
それと、Textの幅を取得するメソッド p._getMeasuredWidth でも、letterSpacing を設定してあげないと、正常な幅が取れないので、
p._getMeasuredWidth 内から呼ばれている、p._prepContext メソッド内に、
/**
* @method _getWorkingContext
* @param {CanvasRenderingContext2D} ctx
* @return {CanvasRenderingContext2D}
* @protected
**/
p._prepContext = function(ctx) {
ctx.font = this.font||"10px sans-serif";
ctx.textAlign = this.textAlign||"left";
ctx.textBaseline = this.textBaseline||"top";
ctx.lineJoin = "miter";
ctx.miterLimit = 2.5;
ctx.letterSpacing = (this.letterSpacing === undefined)? "" : this.letterSpacing + "px";
return ctx;
};
ctx.letterSpacing = (this.letterSpacing === undefined)? "" : this.letterSpacing + "px";
を追加します
これで、letterSpacing を設定後も正常な幅が取得できます
また、Textのコンストラクタに、
function Text(text, font, color) {
this.letterSpacing = 0;
と、this.letterSpacing の初期値を与えておけば、上記の undefined のチェックは要らないかも
使い方は、
let txt:createjs.Text = new createjs.Text("ほげほげ");
txt.letterSpacing = 10;
こんな感じ
また、
txt.letterSpacing -= 1;
とかも可
Animateのステージ上に配置してある Textインスタンス についても、
test_txt.letterSpacing = 10;
な感じで設定ができます