2013-06-13 2 views
0

Я создал функцию на javascript и google maps для использования внешнего значка и перерисовал его с помощью html5 canvas, однако, вызвал загрузку значка, когда я использую imageObj. OnLoad, функция sont ничего возвращать, то я удалю эту функцию и послал результат в любом случае, но это не верно форма на работы с иконками и холст Мой кодcanvas function 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; 
    } 

ответ

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 вернется сразу, но это будет, когда готов, передать данные к следующей функции ,

+0

Танки много для ответа, я пытаюсь, возможно, у меня есть некоторые проблемы, надеюсь, вы могли бы дать руку на вероятные проблемы. Большое спасибо – Carlos

+0

То, что я делаю, это вызов функции на значке настройки, например «imageIcon = getIconMarker (позиции [i] .course, position [i] .speed); Я думаю, что мне нужно сделать что-то вроде «getIconMarker (курс, скорость, callbackSuccsess, callbackError)», однако, я также думаю, что я должен отправить идентификатор маркера для обратного вызова успеха, не так ли? – Carlos

+0

@ Карлос, что должно быть хорошо. Вы также можете построить объект/массив со всеми параметрами, необходимыми для следующего вызова, и передать это как один аргумент. – K3N

-2

функция toDataURL из холста не предназначен для изображений. Невозможно нарисовать изображение на холсте и преобразовать его в URL-адрес, используя функцию toDataURL. Только элементы, такие как прямоугольник, линия и другая форма, нарисованные на холсте, могут быть преобразованы в данные URL с функцией toDataURL. Думаю, вам нужно найти другой путь.

+1

Вы ошибаетесь, сэр. Метод toDataURL может использоваться для изображений, сделанных на холсте. Единственная проблема - это одна и та же политика происхождения, которая по соображениям безопасности позволяет отображать только изображения из того же домена, что и страница, на которой отображается холст. Если холст был испорчен данными перекрестного происхождения, toDataURL потерпит неудачу. –

Смежные вопросы