0

外部アイコンを使用するためにjavascriptとGoogleマップで関数を作成し、html5キャンバスを使用して再描画しましたが、アイコンのロードの原因であるimageObj.onloadを使用すると、関数は何も返されず、その関数を削除して送信しましたとにかく結果ですが、アイコンとキャンバスを操作する際の正しい形式ではありません 私のコードは

function getIconMarker(course, speed){
        course = parseFloat (course) * 0.01745327777;
        if (parseInt(speed) != 0) {
            imageIcon = '{% static "markers/onmove.gif" %}';
        } else {
            imageIcon = '{% static "markers/onstop.png" %}';
        }
        var elemento = document.createElement("canvas");
        elemento.width = 80;
        elemento.height = 80;
        if(elemento && elemento.getContext){
            var context = elemento.getContext('2d');
            if(context){
                var imageObj = new Image();
                imageObj.src = imageIcon;
                //imageObj.onload = function(){
                    //console.debug('image loaded');
                    context.save();
                    context.translate(imageObj.width, imageObj.height);
                    context.rotate(course);
                    context.drawImage(imageObj, -(imageObj.width/2), -(imageObj.height/2));
                    context.restore();
                    //console.debug(elemento.toDataURL());
                    return elemento.toDataURL();
                //} 
                console.debug('image no loaded');
            }
            console.debug('no context created');
        }
        console.debug('no context enblaed');
        //return imageIcon;
    }
4

2 に答える 2

1

画像の読み込みは非同期であるため、呼び出しをチェーンする必要があります。これを行う 1 つの方法は、イベントを使用して呼び出しチェーンを作成することです。

呼び出しチェーンは関数で開始され、実行されるとチェーン内の次の関数が呼び出され、実行されると次の関数が呼び出されます。

主な違いは、1 つのグローバル関数ではなく、コードを関数に分割することです。

典型的な同期コードは次のようになります。

Start:
result = doSomething()
result = doSomethingElse()
result = calc something
result = andDoSomeMore()
...
Finished!

現在の関数が終了する前に次の関数が呼び出されないため、これは正常に機能します。

非同期アプローチは次のようになります。

function doSomething()           then call doSomethingElse(result)
function doSomethingElse(result) then call calc function(result)
function calcSomething(result)   calc something, call andDoSomeMore(result)
function andDoSomeMore(result)   Finished!

Start: doSomething()

非同期アプローチのグローバル コンテキストで発生する唯一のことは、チェーンの最初の部分を開始することです。これは、続行する前に何かが完了するのを待たなければならないためです。関数内でイベントを受け取ると、いつ続行するかがわかります。sync アプローチのように、aync 関数からの結果を処理しません。非同期関数はデータを返すことができません。必要なデータでイベントが発生したときに呼び出される次の関数に引数としてデータを渡す必要があります。

グローバル コンテキストは、基本的に、一般的に言えば、チェーンに必要な関数と変数を保持し、それを開始するためだけのものです。

たとえば、関数を変更して、1 つは成功用、もう 1 つはエラー用のコールバックを受け取ることができます。画像読み込みイベントが終了すると、チェーンの次のステップに進む関数が呼び出されます。

function getIconMarker(course, speed, callback, callbackError){
    // other code snipped...

    if(elemento && elemento.getContext){
        var context = elemento.getContext('2d');
        if(context){
            var imageObj = new Image();
            imageObj.onload = function(){
                console.debug('image loaded');
                context.save();
                context.translate(imageObj.width, imageObj.height);
                context.rotate(course);
                context.drawImage(imageObj, -(imageObj.width/2), -(imageObj.height/2));
                context.restore();

                //use a callback to trigger next function with image as argument
                callback(elemento.toDataURL());
            }
            imageObj.onerror = callbackError;
            imageObj.src = imageIcon; // start loading image and return (void)
        }
    }
}

これで、データを関数の引数として渡すことができます。コールバック関数は次のようになります。

function callbackSuccess(dataUri) {
    // we got an image
    //perform next step, upload etc.
    //...
}

エラー ハンドラ (典型的なシナリオでは一般的) の場合 - (より論理的な名前、つまり、次のステップに適した名前を付けます)、例:

function callbackError(errorEvent) {
    console.log(errorEvent);
    alert('An error occurred loading an image');
}

それはすべて呼び出すことによって機能します:

getIconMarker(course, speed, callbackSuccsess, callbackError);

getIconMarkerすぐに戻りますが、準備ができたら次の関数にデータを渡します。

于 2013-06-25T08:28:40.417 に答える