Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Canvas и jQuery (https://javascript.ru/forum/jquery/51704-canvas-i-jquery.html)

Makkssimka 16.11.2014 17:35

Canvas и jQuery
 
Есть скрипт который делает ресайз изображения через canvas:
$('#image').change(function(){
			var files = $(this)[0].files;
			for(var i = 0; i < files.length; i++){
				var file = $(this)[0].files[i];
				var fileURL = getBlobURL(file);
				
				$("#canvasList").append('<canvas id="canvas'+i+'" width="0" height="0"></canvas>')
				
				var canvas = $("#canvas"+i+"")[0];
				var context = canvas.getContext("2d");
				
				var img = new Image();
				img.src = fileURL;
				console.log(img);
				
				img.onload = function(){
					var width = img.width;
					var height = img.height;
					
					if(height>width){
						heightRe = 1080;
						widthRe = (heightRe*width)/height;
						}
					else{
						widthRe = 1920;
						heightRe = (height*widthRe)/width;
						}
						
					canvas.width = widthRe;
					canvas.height = heightRe;
					context.drawImage(img,0,0,widthRe,heightRe);
				};
			}

Выводится Только последнее изображение, все остальные canvas'ы имеют высоту и ширину 0. Почему так?

danik.js 16.11.2014 17:56

Потому что в js когда ты пишешь
for (..) {
    var canvas = ..;
}


на самом деле получается
var canvas;
for (..) {
    canvas = ..;
}


То есть у тебя не создается на каждой итерации новая переменная canvas, понимаешь? У тебя всего одна переменная, и именно последнее присвоенное значение в ней и остается. А функция img.onload ссылается именно на нее. Тоже самое и с переменной img и context

Переменные в js через var объявляются на уровне функции, а не блока.

Эту проблему в будущем решит let. Ну а пока нужно использовать замыкания или любой другой способ, главное чтобы для каждого img.onload была своя переменная canvas.


Кстати, почему нельзя сразу отображать <img> и ресайзить его. Какую роль играет canvas?

Makkssimka 16.11.2014 17:59

В дальнейшем, есть кнопочка сохранить, которая отправляет изображение на сервер (измененное). Т.е. получается ресайз на стороне клиента!

danik.js 16.11.2014 18:01

То есть в других языках цикл порождает блок, в котором можно объявлять переменные. В JS переменная объявляется не на уровне блока, а на уровне функции. То есть тебе нужно обернуть в функцию твой код, использующий переменные, чтобы создать "блок для переменных" (замыкание)

Makkssimka 16.11.2014 18:02

а если в функции img.onload удалять переменную?

Makkssimka 16.11.2014 18:09

Т.е. я создаю функцию с этой всей белибердой которая в конце вызывает сама себя, здесь ее вызываю
$('#image').change(function(){
......
});


А как прекратить это?

danik.js 16.11.2014 18:18

Цитата:

Сообщение от Makkssimka
а если в функции img.onload удалять переменную?

И как это поможет? В js не надо ничего удалять - сборщик мусора сам разберется.

Лучше всего вынести все в функцию:

function createCanvas(src) {
    var canvas = $('<canvas/>', {width: 0, height: 0}).get(0);
    var context = canvas.getContext("2d");

    var image = new Image();
    image.onload = function(){
        var width = image.width;
        var height = image.height;
         
        if (height > width){
            heightRe = 1080;
            widthRe = (heightRe*width) / height;
        }
        else {
            widthRe = 1920;
            heightRe = (height*widthRe) / width;
        }

        canvas.width = widthRe;
        canvas.height = heightRe;
        context.drawImage(image, 0, 0, widthRe, heightRe);
    };
    image.src = src;

    return canvas;
}

$('#image').change(function(){
    var files = this.files;
    for (var i = 0; i < files.length; i++){
        var fileURL = getBlobURL(files[i]);
        var canvas = createCanvas(fileURL);
        $("#canvasList").append(canvas);
    }
});


Цитата:

Сообщение от Makkssimka
$(this)[0].files

Как можно было до такой хуйни додуматься??
А почему не так тогда уж: $($($(this)[0])[0])[0] - так посолидней смотрится ведь, правда?

danik.js 16.11.2014 18:19

Тут от jQuery рожки да ножки остались. Если это - все ради чего подключена была библиотека - можно и остатки выпилить.


Часовой пояс GMT +3, время: 14:44.