3

HTML5キャンバスでアニメーションタイプライター効果を取得しようとしていますが、ワードラップで本当に苦労しています。

これが私のShapes.jsの要点です:https ://gist.github.com/Jamesking56/0d7df54473085b3c5394

そこで、たくさんのメソッドを持つTextオブジェクトを作成しました。そのうちの1つはと呼ばれtypeText()ます。

typeText()基本的にはタイピング効果から始まりますが、それは端から落ち続けており、ワードラップを修正する方法を見つけるのに本当に苦労しています。

誰かがこれを行うための最良の方法について私を導くことができますか?

4

4 に答える 4

2

私が使用した解決策は大まかに:

var maxWidth = 250;
var text = 'lorem ipsum dolor et sit amet...';

var words = text.split(' ');
var line = [words[0]]; //begin with a single word

for(var i=1; i<words.length; i++){
    while(ctx.measureText(line.join(' ')) < maxWidth && i<words.length-1){
        line.push(words[i++]);
    }
    if(i < words.length-1) { //Loop ended because line became too wide
        line.pop(); //Remove last word
        i--; //Take one step back
    }
    //Ouput the line
}

出力テキストの高さを測定する方法がないように思われるため、ハードコードされた行の高さで出力する各行を手動でオフセットする必要があります。

于 2013-03-31T00:43:31.787 に答える
0

Textコンストラクターがどのように機能するか理解できませんでした。そこで、私は独立した関数を作成しました(どのオブジェクトにも属していません)。この関数に渡す必要があるのは、文字列、XandのY位置、行の高さ、およびパディングだけです。キャンバスが変数に割り当てられcanvas、2Dコンテキストが変数に割り当てられることを前提としていますctx

var canvas, ctx;
function typeOut(str, startX, startY, lineHeight, padding) {
    var cursorX = startX || 0;
    var cursorY = startY || 0;
    var lineHeight = lineHeight || 32;
    padding = padding || 10;
    var i = 0;
    $_inter = setInterval(function() {
        var w = ctx.measureText(str.charAt(i)).width;
        if(cursorX + w >= canvas.width - padding) {
            cursorX = startX;
            cursorY += lineHeight;
        }
        ctx.fillText(str.charAt(i), cursorX, cursorY);
        i++;
        cursorX += w;
        if(i === str.length) {
            clearInterval($_inter);
        }
    }, 75);
}

こちらのデモをご覧ください。

ヒント-

私はあなたのコードを調べていて、これにリンクしているものを見つけました-

function Rectangle(x,y,width,height,colour) {
    //properties
    this.draw = function() { //Don't assigns object methods through constructors
        ctx.fillStyle = this.colour;
        ctx.fillRect(this.x, this.y, this.width, this.height);
    };
}

オブジェクトがインスタンス化されるたびにメソッドが作成されるため、コンストラクターを介してオブジェクトにメソッドを追加しないでください。オブジェクトのプロトタイプにメソッドを追加するのではなく、この方法で、メソッドは1回だけ作成され、すべてのインスタンスで共有されます。好き-

function Rectangle(x,y,width,height,colour) {
    //properties
}
Rectangle.prototype.draw = function() {
    ctx.fillStyle = this.colour;
    ctx.fillRect(this.x, this.y, this.width, this.height);
}

また、いくつかのオブジェクトを指すために追加の変数を作成していることがわかりました。好き -

var that = this;
var fadeIn = setInterval(function() {
    //code
    that.draw();
    //code
}, time);

Textオブジェクトへの追加の参照を作成しないでください。オブジェクトを指すbindようにメソッドを使用します。好き-thisText

var fadeIn = setInterval(function() {
    //code
    this.draw(); // <-- Check this it is `this.draw` no need for `that.draw`
    //code
}.bind(this), time);   //bind the object

バインドについて詳しくは、こちらをご覧ください。

お役に立てば幸いです。

PS:各文字で75ミリ秒、それは毎分800文字になります!!!


更新-スケーラブルグラフィックスが必要な場合は、SVGを検討する必要があります。Canvasはラスターベースですが、SVGはベクターベースです。つまり、SVGは簡単にサイズ変更できますが、キャンバスのサイズを変更すると、キャンバスのコンテンツがピクセル化されてぼやけて見えます。続きを読む

キャンバスのコンテンツのサイズを変更するには、キャンバス全体を再描画する必要があります。キャンバスに何かが描かれると、ブラウザはそれを描き忘れてしまいます。したがって、オブジェクトのサイズ/位置を変更する場合は、キャンバスを完全にクリアして、オブジェクトを再描画する必要があります。あなたの場合、ctx.fontキャンバスのサイズに応じて変更してから、キャンバスを更新する必要があります。これは非常に面倒な作業になります。

于 2013-03-31T18:03:35.320 に答える
-1

<canvas>テキスト処理用には設計されていません。の上部に透明なDOM要素をオーバーレイすることで、これを行うのがはるかに簡単になります<canvas>。これは、当然、でテキストピクセルを後処理する必要がないことを前提としています<canvas>。それ以外の場合は、Javascriptでテキスト処理全体を再実装する必要があります。これは、ブラウザが簡単に実行できるため、車輪の再発明のようなものです。

position: absoluteCSSとを使用して実行する方法の詳細は次のとおりposition: relativeです。

ユーザーがHTML5Canvasゲームにテキストを入力できるようにする

すべてのテキストが透明な色で、各文字が。で囲まれているDOM要素が必要だと思います<span>。次に、<span>不透明度を調整して、それらを表示し始めます。このように、文字の位置は変更されません。

于 2013-03-28T14:53:06.717 に答える
-1

個人的には、キャンバスゲームでテキストが必要な場合は常にビットマップフォントを使用します。これにはいくつかの利点があります。

  1. キャンバス上のFillTextは遅いです。ビットマップフォントははるかに高速です。
  2. 各文字の幅がわかっているので、折り返しやテキストの配置がはるかに簡単になります。

ケース合成操作を使用してフォントの色を選択し、描画幅の高さを動的に調整することでフォントサイズを選択できるという利点があります。

于 2013-03-28T18:13:09.597 に答える