Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 16.11.2014, 16:35
Аспирант
Отправить личное сообщение для Makkssimka Посмотреть профиль Найти все сообщения от Makkssimka
 
Регистрация: 13.11.2012
Сообщений: 51

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. Почему так?
Ответить с цитированием
  #2 (permalink)  
Старый 16.11.2014, 16:56
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 11.09.2010
Сообщений: 8,804

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


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


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

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

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


Кстати, почему нельзя сразу отображать <img> и ресайзить его. Какую роль играет canvas?
__________________
В личку только с интересными предложениями
Ответить с цитированием
  #3 (permalink)  
Старый 16.11.2014, 16:59
Аспирант
Отправить личное сообщение для Makkssimka Посмотреть профиль Найти все сообщения от Makkssimka
 
Регистрация: 13.11.2012
Сообщений: 51

В дальнейшем, есть кнопочка сохранить, которая отправляет изображение на сервер (измененное). Т.е. получается ресайз на стороне клиента!
Ответить с цитированием
  #4 (permalink)  
Старый 16.11.2014, 17:01
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 11.09.2010
Сообщений: 8,804

То есть в других языках цикл порождает блок, в котором можно объявлять переменные. В JS переменная объявляется не на уровне блока, а на уровне функции. То есть тебе нужно обернуть в функцию твой код, использующий переменные, чтобы создать "блок для переменных" (замыкание)
__________________
В личку только с интересными предложениями
Ответить с цитированием
  #5 (permalink)  
Старый 16.11.2014, 17:02
Аспирант
Отправить личное сообщение для Makkssimka Посмотреть профиль Найти все сообщения от Makkssimka
 
Регистрация: 13.11.2012
Сообщений: 51

а если в функции img.onload удалять переменную?
Ответить с цитированием
  #6 (permalink)  
Старый 16.11.2014, 17:09
Аспирант
Отправить личное сообщение для Makkssimka Посмотреть профиль Найти все сообщения от Makkssimka
 
Регистрация: 13.11.2012
Сообщений: 51

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


А как прекратить это?
Ответить с цитированием
  #7 (permalink)  
Старый 16.11.2014, 17:18
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 11.09.2010
Сообщений: 8,804

Сообщение от 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] - так посолидней смотрится ведь, правда?
__________________
В личку только с интересными предложениями
Ответить с цитированием
  #8 (permalink)  
Старый 16.11.2014, 17:19
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 11.09.2010
Сообщений: 8,804

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



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Динамический подсчет в таблице muraig jQuery 5 11.10.2014 15:54
хочу инвайт на хабр macdack Оффтопик 45 28.07.2013 22:18
Вопрос поддержки старых методов jQuery antonM jQuery 1 03.10.2012 23:08
jQuery и canvas ArmagedDance jQuery 6 18.07.2011 02:56
Добавить на canvas еще один елемент greengarlic Общие вопросы Javascript 5 22.09.2010 09:16