0

次のようなさまざまな関数を含む functions.js というファイルを作成しています。

  1. bgImage()
  2. drawImage()
  3. setText()

私の問題は、私のテキストが遅れ続けていることです。

私がやりたいことは、 setText() を呼び出すと、テキストを好きな場所に置くことができるということです。そして、テキストはコンバスの上に置かれます。テキストを上書きしないようにするには、最初に画像描画ロード関数を呼び出す必要があることを知っています。しかし、私はJSでそうしました。

したがって、すべての画像が描画/設定された後、関数 setText() を何度でも呼び出すことができ、テキストが表示されることが非常に重要です。

上部にテキストが必要です。

これが私のコードです:

functions.js

var canvas = "";
var context = "";

function canvasInit() {
    canvas = document.getElementById('myCanvas');
    context = canvas.getContext('2d');
}

function bgImage() {
    var imageObj = new Image();
    imageObj.onload = function() {
        var pattern = context.createPattern(imageObj, 'repeat');
        context.rect(0, 0, canvas.width, canvas.height);
        context.fillStyle = pattern;
        context.fill();
    };
    imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/wood-pattern.png';
}

function drawImage() {
    var imageObj = new Image();
    imageObj.onload = function() {
        context.drawImage(imageObj, 10, 50);
        context.drawImage(imageObj, x, y, width, height);
    };
    imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
}

function    (text) {
    context.font = 'italic 40pt Calibri';
    context.fillText(text, 150, 100);
}

index.html

<!DOCTYPE html>
<html>
<head>
    <script src="functions.js"></script>
    <script>
        document.addEventListener('DOMContentLoaded',ready);
        function ready() {
            canvasInit();
            bgImage();
            drawImage();
            setText("Yo");
            setText("heyyyy");
        }
    </script>
</head>
<body>
    <canvas id="myCanvas" width="500" height="400"></canvas>
</body>
</html>

動作しない更新されたテスト:

index.html

<!DOCTYPE html>
<html>
<head>
    <script src="functions.js"></script>
    <script>
        document.addEventListener('DOMContentLoaded',ready);
        function ready() {
            canvasInit();
            bgImage(function() {
               setText(); 
            });
        }
    </script>
</head>
<body>
    <canvas id="myCanvas" width="500" height="400"></canvas>
</body>
</html>

functions.js

var canvas = "";
var context = "";

function canvasInit() {
    canvas = document.getElementById('myCanvas');
    context = canvas.getContext('2d');
}

function bgImage(callback) { // add parameter for function

    var imageObj = new Image();
    imageObj.onload = function() {
        var pattern = context.createPattern(imageObj, 'repeat');
        context.rect(0, 0, canvas.width, canvas.height);
        context.fillStyle = pattern;
        context.fill();

        if (typeof callback === 'function')  {
            callback();  // invoke callback function
        }

    };
    imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/wood-pattern.png';

}

function drawImage() {
    var imageObj = new Image();
    imageObj.onload = function() {
        context.drawImage(imageObj, 10, 50);
        context.drawImage(imageObj, x, y, width, height);
    };
    imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
}

function setText() {
    context.font = 'italic 40pt Calibri';
    context.fillText("Yoo adfa ds asd a sd", 150, 100);
}
4

2 に答える 2

1

これは、画像の読み込みが非同期であるために発生します。画像の読み込みが完了する前に、ソースの設定後に関数が終了するときにテキストを描画します。次に、画像の読み込みが完了すると、onload 関数が呼び出され、以前に描画されたもの (この場合はテキスト) の上に画像が描画されます。

これを機能させるには、関数のコールバック ハンドラーを実装する必要があります。たとえば、次のようになります。

function bgImage(callback) { /// add parameter for function

    var imageObj = new Image();
    imageObj.onload = function() {
        var pattern = context.createPattern(imageObj, 'repeat');
        context.rect(0, 0, canvas.width, canvas.height);
        context.fillStyle = pattern;
        context.fill();

        if (typeof callback === 'function')  
            callback();  /// invoke callback function
    };
    imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/wood-pattern.png';
}

次に、それを使用します。

bgImage(function() {
   setText(); 
});

もちろん、他の画像読み込み関数でもこれを行う必要があります。ヒント: チェーンが長くなってしまう場合は、最後の例のようにインライン化するのではなく、非匿名関数を割り当てる方がよいでしょう。

更新

わかりやすくするために: 提供される関数は参照として提供され、呼び出しの結果ではないことが重要です。たとえば、次のようにコールバックを使用します。

bgImage(setText);   /// correct

この方法ではありません:

bgImage(setText()); /// wrong

括弧を使用すると、setTextが単純に呼び出され、その結果がコールバックとして渡されます。これは、テキストが最初に描画されてからbgImage呼び出されることを意味します。

于 2013-10-27T17:23:52.260 に答える