2014-01-15 98 views
1

我有一組svg圖像和一些我想要加載到HTML Canvas上的屬性。目標是將圖像加載到給定的大小,並加載到給定的x,y座標上。這是我的例子中的物體:將圖像加載到HTML Canvas中

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(不是必需的,但可能有助於柵格化過程)。通過使用naturalWidthnaturalHeight來讀取具有相同名稱的屬性讀取此維度,同時讀取原始維度。

根據需要進行修改。希望這可以幫助。

+0

這非常有幫助。我把一個版本放到JS小提琴中:http://jsfiddle.net/sPHjd/在回調中使用我的drawToCanvas函數。它似乎每次都完美地工作。在我的更大的解決方案中,我仍然得到各種渲染,但至少我知道它不是由這部分代碼造成的。 –