2013-04-21 2 views
0

Я новичок в работе с элементами холста и пытаюсь нарисовать полноэкранное изображение, а затем сделать некоторые пиксельные модификации. Я написал небольшой метод для этого, и загрузка изображения работает отлично, но изменение размера окна браузера ужасно медленное - даже с помощью дросселя.Обновление Canvas on Window Resize

Вот мой метод для рисования изображения на холст, и применить эффект изображения фильтра к нему:

drawCanvas:function(obj,src,onResize){ 
    var img=new Image(), 
     objData=$.data(obj), 
     canvas=Plugin.OBJ.$Canvas[0], 
     ctx=canvas.getContext("2d"), 
     win=$(window), 
     winW=win.width(), 
     winH=win.height();  

    img.src=src; 
    Plugin.CanvasSRC=src; 

    img.onload=function(){ 
    var imgW=img.width, 
      imgH=img.height, 
      ratio=imgW/imgH; 
     newH=(Math.round(winW/ratio)<winH)?winH:Math.round(winW/ratio), 
      winW=(newH<winH)?$win.width():Math.round(newH*ratio); 

     canvas.width=winW; canvas.height=newH; 
    ctx.drawImage(img,0,0,winW,newH); 

    var imgdata=ctx.getImageData(0,0,winW,winH), 
      pix=imgdata.data, 
      l=pix.length, 
      filter=objData.bg_pic_filter; 

    switch(filter){ ... this section does the pixel manipulation ...}; 

    // APPLY THE FILTER && FADE IN 
    ctx.putImageData(imgdata,0,0); 
    }; 
}, 

Надеюсь, я не слишком невероятно от этого, но мне интересно, если есть лучший способ просто нарисовать изображение на полноэкранном холсте, но сохраните его размеры, аналогичные размеру фона: обложка? Эти изображения также используют фильтры манипуляции с пикселями. Можно ли просто изменить размер холста при изменении размера окна, не переделывая его и повторно применяя фильтр каждый раз? Спасибо!

+2

Возможно, у вас может быть экранный холст фиксированного размера, где вы будете делать все ваши вычисления, а затем иметь еще один на экране и просто скопировать изображение с первого на размер? или даже создать изображение с первого холста и просто показать его? идея состоит в том, чтобы кэшировать результаты расчета и не переделывать работу при каждом изменении размера. – akonsu

+0

Спасибо :) Как бы я это сделал? – Aaron

+0

Я бы использовал 'document.createElement (" canvas ")'. Просто не присоединяйте его к DOM. – akonsu

ответ

0

Некоторые мысли о вашем вопросе:

Когда вы говорите, «даже с throttler» Я предполагаю, что вы держите ваш дорогой перерисовывать от того запускается повторно. Что-то вроде этого: JavaScript/JQuery: $(window).resize how to fire AFTER the resize is completed?

// on resizing, call for a delay 
// after the delay call your drawCanvas() 
$(window).resize(function() { 
    waitForFinalEvent(function(){ drawCanvas(); }, 500, randomID()); 
}); 

// wait for the specified delay time before doing callback 
// if this is called again before timeout, restart the timer 
var waitForFinalEvent = (function() { 
    var timers = {}; 
    return function (callback, ms, uniqueId) { 
    if (timers[uniqueId]) { 
     clearTimeout (timers[uniqueId]); 
    } 
    timers[uniqueId] = setTimeout(callback, ms); 
    }; 
})(); 

// generate a "good enough" unique id 
function randomID() { 
    return (((1+Math.random())*0x10000)|0).toString(16).substring(1); 
} 

Если оригинал отфильтрованного изображения переживет изменение размеров без неприемлемого pixelating, вы можете сохранить исходное изображение в dataURL, а затем просто масштабировать + перерисовывать, что сохраненное изображение на ваш измененный размерах холста, как это:

// save the canvas content as imageURL 
var data=canvas.toDataURL(); 

// resize the canvas 
canvas.width*=scaleFactor; 
canvas.height*=scaleFactor; 

// scale and redraw the canvas content 
var img=new Image(); 
img.onload=function(){ 
    ctx.drawImage(img,0,0,img.width,img.height,0,0,canvas.width,canvas.height); 
} 
img.src=data;