2014-01-15 3 views
1

У меня есть набор изображений svg и некоторые атрибуты, которые я бы хотел загрузить на холст HTML. Цель состоит в том, чтобы изображения загружались с заданным размером и на заданные координаты x, y. Вот мой пример объект:Загрузка изображений в HTML-холст

var ObjectInstances = { 
objects:[ 
    { 
    "ID": "1234", 
    "Name": "Backhoe", 
    "x": "0", 
    "y": "0", 
    "height": "150", 
    "width": "350", 
    "svg": "images/svgs/backhoe.svg" 
    }, 
    { 
    "ID": "5678", 
    "Name": "Crane", 
    "x": "350", 
    "y": "150", 
    "height": "200", 
    "width": "200", 
    "svg": "images/svgs/crane1.svg" 
    } 
] 
}; 

Оптимально я петлю через объекты, и использовать эти пар ключ: значение для отображения каждого изображения на холст, но я постоянно работать в тех случаях, когда объекты появляются в разных размерах, или в разных местах после перезагрузки. Я знаю из своих исследований, что мне нужно предварительно загрузить все изображения, чтобы нарисовать их на холсте. Для этого я создал параллельные массивы. Один массив для хранения предварительно загруженных изображений, а другой - для хранения координат и размеров каждого изображения. Затем я попытался нарисовать изображения, используя эти два массива. Вот мой код:

function loadImages(sources, callback) { 
    var images = {}; 
    var loadedImages = 0; 
    var numImages = 0; 
    // get num of sources 
    for(var src in sources) { 
    numImages++; 
    } 
    for(var src in sources) { 
    images[src] = new Image(); 
    images[src].onload = function() { 
     if(++loadedImages >= numImages) { 
     callback(images); 
     } 
    }; 
    images[src].src = sources[src]; 
    } 
} 

// Preload images into a source array 
var sources = {}; 
$.each(ObjectInstances.objects, function(index, value) { 
     sources[index]=this.svg; 
}) 

loadImages(sources, function(images) { 

$.each(ObjectInstances.objects, function (index, value) { 
    var x=$(this)[0].x, 
     y=$(this)[0].y, 
     w=$(this)[0].width, 
     h=$(this)[0].height; 
    attach(images[index], x, y, w, h); 

}); 

}); 


// Load Object Instances 

function attach(img, x, y, w, h) { 
    context.drawImage(img, x, y, w, h); 
} 

Может ли кто-нибудь направить меня сюда, чтобы получить лучший способ достичь этого?

ответ

1

Я бы не отделял элементы изображения от их метаобъекта. Я хотел бы сделать что-то вроде этого, используя один массив:

var ObjectInstances = { 
objects:[ 
    { 
    "ID": "1234", 
    "Name": "Backhoe", 
    "x": "0", 
    "y": "0", 
    "height": "150", 
    "width": "350", 
    "svg": "images/svgs/backhoe.svg", 
    image: null 
    }, 
    { 
    "ID": "5678", 
    "Name": "Crane", 
    "x": "350", 
    "y": "150", 
    "height": "200", 
    "width": "200", 
    "svg": "images/svgs/crane1.svg", 
    image: null 
    } 
] 
}; 

Тогда итерации по массиву, чтобы вызвать загрузку по его URL:

loadImage(ObjectInstances, myCallback); 

function loadImages(obj, callback) { 

    var i = 0, 
     o, 
     count = obj.objects.length; 

    for(; o = obj.objects[i]; i++) { 
     o.image = new Image(o.width, o.height); 
     o.image.onload = loader; 
     o.image.src = o.svg; 
    } 

    function loader() { 
     count--; 
     if (count === 0) callback({ 
      objectInstances: obj 
     }); 
    } 
} 

Теперь, когда вы перебирать исходный массив вы будете иметь действительные элементы изображения, непосредственно привязанные к самому объекту (если, конечно, не возникла ошибка, и в этом случае обратный вызов никогда не вызывается, поскольку код стоит здесь - добавьте обработчики событий onerror/onabort, чтобы справиться с этой ситуацией).

Обратите внимание, что я устанавливаю ширину и высоту, используя необязательные аргументы Image, поскольку мы имеем дело с SVG (не обязательно, но может помочь в процессе растеризации). Этот размер считывается свойствами с теми же именами, в то время как исходное измерение считывается с использованием naturalWidth и naturalHeight.

Измените, при необходимости. Надеюсь это поможет.

+0

Это было очень полезно. Я поместил версию в скрипт JS: http://jsfiddle.net/sPHjd/ с моей функцией drawToCanvas в обратном вызове. Кажется, он работает отлично - каждый раз. В моем более крупном решении я все еще получаю различные визуализации, но по крайней мере я знаю, что это не вызвано этой частью кода. –

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