0

我在 javascript 和谷歌地图上创建了一个使用外部图标的函数,并使用 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

图像加载是异步的,因此您必须链接调用。一种方法是使用事件创建调用链。

调用链从一个函数开始,完成后调用链中的下一个函数,完成后调用下一个函数,依此类推。

主要区别在于您将代码划分为函数,而不是拥有一个单一的全局函数。

典型的同步代码如下所示:

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()

使用异步方法在全局上下文中唯一发生的事情是启动链的第一部分,因为我们必须等待某些事情完成才能继续。当我们在函数内收到事件时,我们将知道何时继续。我们不像在同步方法中那样处理来自 aync 函数的任何结果。异步函数不能返回任何数据。他们需要将数据作为参数传递给下一个函数,该函数在需要数据的事件发生时调用

全局上下文基本上和一般来说仅用于保存我们的链所需的函数和变量并启动它。

例如,你可以修改你的函数来接受回调,一个代表成功,一个代表错误。当图像加载事件完成后,它将调用那些将进入链中下一步的函数:

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 回答
-2

画布的 toDataURL 函数不适用于图像。无法在画布上绘制图像并使用 toDataURL 函数将其转换为 URL。只有在画布上绘制的矩形、线条等形状的元素才能通过toDataURL函数转换为URL数据。我想你必须找到其他方法。

于 2013-06-13T16:22:26.210 回答