 
			
				25.02.2013, 11:02
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 Аспирант 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 08.04.2010 
					
					
					
						Сообщений: 34
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		Учебный вариант заработал во всех нужных браузерах IE 7+ (6го нет что бы проверить, но и там должно работать), FF, Opera, Chrome, Safari. Посмотреть можно  здесь, а скачать  здесь (не нашел как файл к сообщению прикрепить).
 
Господа спецы, прошу, по-возможности, глянуть как оно работает. Если есть какие-то кривости в коде, опасные места - подскажите, пожалуйста. Если можно - с общими советами как это исправить (работать вместо меня не прошу, но полезные советы - это хорошо).  
Я бы хотел выложить данный плагин для свободного использования, но для этого его нужно довести до совершенства. А в JS я весьма слаб... потому рассчитываю на вашу помощь    
		
	
		
		
		
		
		
		
		
						  
				
				Последний раз редактировалось master_alf, 25.02.2013 в 11:16.
				
				
			
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				25.02.2013, 12:01
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Профессор 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 11.09.2010 
					
					
					
						Сообщений: 8,804
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	| 
	
	
		
		
		
		
		 Давай сюды код тогда. 
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				25.02.2013, 12:35
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 Аспирант 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 08.04.2010 
					
					
					
						Сообщений: 34
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		Вызов плагина, параметром передается селектор, для которого нужно применить grayScale. 
$(document).ready(function() {
            makeGray('body div img');
        });
Подключаемый файл, где собственно описана вся логика работы.
 
var grayTryCount = 0;
var timerID = false;
function makeGray(selector) {
    if (grayTryCount <= 3) {
        grayTryCount +=1;
        $(selector).each(function(){
            if ((this.complete) && (!$(this).hasClass('makeGrayDone')) && (!$(this).hasClass('gray'))){
                makeCopy(this);
            } else {
                if (!timerID) {
                    timerID = setTimeout(function() {makeGray('body div img')}, 1000);
                }
            }
        });
    }
}
        
        function makeCopy(img) {
            var canvas2DSupported = !!window.CanvasRenderingContext2D;
            if (canvas2DSupported) {
                var newImg = makeCanvasCopy(img);
            } else { 
                var newImg = makeIMGCopy(img); 
            }
            var offset = $(img).offset();
            $(img).parent().append(newImg);
            $(img).addClass('makeGrayDone');
            $(newImg).offset(offset);
            $(newImg).hover(hoverIn, hoverOut);
        }
        
        function makeIMGCopy(imgObj) {
                var newImg = document.createElement('img');
                newImg.src = $(imgObj).attr('src');
                $(newImg).attr('class', 'gray');
                newImg.style.filter ='progid:DXImageTransform.Microsoft.BasicImage(grayScale=1)';
                
                return newImg;
        }
        
        function makeCanvasCopy(imgObj) {
            var newImg = document.createElement('img');
            var canvas = document.createElement('canvas');
            var canvasContext = canvas.getContext('2d');
            var imgW = imgObj.width;
            var imgH = imgObj.height;
            canvas.width = imgW;
            canvas.height = imgH;
            canvasContext.drawImage(imgObj, 0, 0);
            var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);
            
            for(var y = 0; y < imgPixels.height; y++){
                for(var x = 0; x < imgPixels.width; x++){
                    var i = (y * 4) * imgPixels.width + x * 4;
                    var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
                    imgPixels.data[i] = avg;
                    imgPixels.data[i + 1] = avg;
                    imgPixels.data[i + 2] = avg;
                }
            }
            canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
            newImg.src = canvas.toDataURL();
            
            $(newImg).attr('class', 'gray');
            return newImg;
        }
        function createCanvas(imgObj) {
            var canvas = document.createElement('canvas');
            var canvasContext = canvas.getContext('2d');
            var imgW = imgObj.width;
            var imgH = imgObj.height;
            canvas.width = imgW;
            canvas.height = imgH;
            canvasContext.drawImage(imgObj, 0, 0);
            var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);
            for(var y = 0; y < imgPixels.height; y++){
                for(var x = 0; x < imgPixels.width; x++){
                    var i = (y * 4) * imgPixels.width + x * 4;
                    var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
                    imgPixels.data[i] = avg;
                    imgPixels.data[i + 1] = avg;
                    imgPixels.data[i + 2] = avg;
                }
            }
            canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
            imgObj.src = canvas.toDataURL();
            //return canvas.toDataURL();
        }
        
        function hoverIn(obj) {
         $(this).animate({
                opacity: 0
                }, 
                {duration: 500, step: function(now, fx) {
                    // Every step of the opacity animation we'll get the current 
                    // opacity as the 'now' argument.
                    var opacity = Math.round(now * 100);
                    $(fx.elem).css('-ms-filter', 'progid:DXImageTransform.Microsoft.Alpha(Opacity=' + opacity + ')');
                    }
                  });
        }
        function hoverOut() {
            $(this).animate({
                opacity: 1
                }, 
                {duration: 500, step: function(now, fx) {
                    var opacity = Math.round(now * 100);
                    $(fx.elem).css('-ms-filter', 'progid:DXImageTransform.Microsoft.Alpha(Opacity=' + opacity + ')');
                    }
                  });
        }
 
		
	
		
		
		
		
		
		
	
		
			
			
	
			
			
			
			
			
				 
			
			
			
			
			
			
				
			
			
			
		 
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				25.02.2013, 12:52
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 без статуса 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 25.05.2012 
					
					
					
						Сообщений: 8,219
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	| 
	
	
		
		
		
		
		 master_alf, 
 А картинка пока только с того же домена ? 
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				25.02.2013, 12:57
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 Аспирант 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 08.04.2010 
					
					
					
						Сообщений: 34
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		Да, только с этого же домена. 
Я, если честно, слабо представляю зачем нужно грузить картинки с других доменов и обрабатывать их подобным образом... но может это дело в слабой фантазии?   
В принципе, если в готовом плагине лучше, что бы оно было - погуглю как делается. Встречал рецепты.  
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				25.02.2013, 12:59
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 без статуса 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 25.05.2012 
					
					
					
						Сообщений: 8,219
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	| 
	
	
		
		
		
		
		 master_alf, 
 На большинстве халявных сайтах и форумов, нет загрузки изо на текущий домен 
Пример Укоз, mybb.ru 
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				25.02.2013, 13:01
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 без статуса 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 25.05.2012 
					
					
					
						Сообщений: 8,219
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		
	
 
	| 
		
			Сообщение от master_alf
			
		
	 | 
 
	| 
		В принципе, если в готовом плагине лучше, что бы оно было - погуглю как делается. Встречал рецепты.
	 | 
 
	
 
 Лучше имхо отдельным расширением, связанным плагином 
На хабре видал статейку, как реализуемо для свежих версий браузеров =>  http://habrahabr.ru/post/120917/ 
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				25.02.2013, 13:05
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Профессор 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 11.09.2010 
					
					
					
						Сообщений: 8,804
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		
	
 
	| 
		
			Сообщение от master_alf
			
		
	 | 
 
	| 
		makeGray('body div img');
	 | 
 
	
 
 1) body в селекторе ни к селу ни к городу. Бывают картинки вне body чтоли? 
2) Раз jQuery, то и оформи как плагин к jQuery. Чтобы вызов был через  $('div img').makeGray()
	
 
	| 
		
			Сообщение от master_alf
			
		
	 | 
 
	
		var grayTryCount = 0; 
var timerID = false;
	 | 
 
	
 
 Срём в глобал? Не канает для публичного плагина. Срочно обернуть в анонимную функцию.
 
	
 
	| 
		
			Сообщение от master_alf
			
		
	 | 
 
	| 
		$(selector)
	 | 
 
	
 
 А что если у юзера был вызван jQuery.noConflict() ? 
Передать в анонимную функцию - обертку ссылку на jQuery, а внутри уже использовать знак доллара. Смотри как это сделано в других плагинах. Вообще, раз ты делаешь плагин, хоть бы не поленился и изучил как их делают другие.
 
	
 
	| 
		
			Сообщение от master_alf
			
		
	 | 
 
	| 
		setTimeout(
	 | 
 
	
 
 Это самый последний вариант решения, когда подругому - ну никак. В данном же случае можно просто навесить обработчик onload на картинки и ждать их загрузки.
 
	
 
	| 
		
			Сообщение от master_alf
			
		
	 | 
 
	| 
		$(imgObj).attr('src');
	 | 
 
	
 
 Может просто  imgObj.src ?
 
	
 
	| 
		
			Сообщение от master_alf
			
		
	 | 
 
	| 
		$(newImg).attr('class', 'gray');
	 | 
 
	
 
 
	
 
	| 
		
			Сообщение от master_alf
			
		
	 | 
 
	| 
		$(img).addClass('makeGrayDone');
	 | 
 
	
 
 Как будто два разных человека писали код. addClass предпочтительней.
 
Где используется функция createCanvas ?
 
	
 
	| 
		
			Сообщение от master_alf
			
		
	 | 
 
	
		$(fx.elem).css('-ms-filter', 'progid XImageTransform.Microsoft.Alpha(Opacity=' + opacity + ')');
	 | 
 
	
 
 Зачем это? jQuery сама фиксит opacity в старых ишаках.
 
Перед .animate() нужно делать .stop() чтоб не образовывалось очереди.  
		
	
		
		
		
		
		
		
	
		
			
			
	
			
			
			
			
			
				 
			
			
			
			
			
			
				
			
			
			
		 
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				25.02.2013, 13:09
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Профессор 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 11.09.2010 
					
					
					
						Сообщений: 8,804
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		В WebKit и вроде 10м ишаке (не уверен) есть поддержка css mask, нужно проверять поддержку и по возможности использовать. Это в тыщу раз быстрее чем работа с пикселями. 
$(newImg).attr('class', 'gray')
Слишком общий css-класс. Он может быть определен у юзера. Вообще, зачем тут css-классы назначать?  
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				25.02.2013, 13:58
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 Аспирант 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 08.04.2010 
					
					
					
						Сообщений: 34
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		
	
 
	
		
			Сообщение от danik.js
			 
		
	 | 
 
	| 
		1) body в селекторе ни к селу ни к городу. Бывают картинки вне body чтоли?
	 | 
 
	
 
 Согласен, fail.
 
	
 
	
		
			Сообщение от danik.js
			 
		
	 | 
 
	| 
		2) Раз jQuery, то и оформи как плагин к jQuery. Чтобы вызов был через $('div img').makeGray()
	 | 
 
	
 
 Погляжу как такое делается.
 
	
 
	
		
			Сообщение от danik.js
			 
		
	 | 
 
	| 
		Срём в глобал? Не канает для публичного плагина. Срочно обернуть в анонимную функцию.
	 | 
 
	
 
 Как только прочту, что такое анонимная функция - поправлю как рекомендвано. с JS сталкиваюсь постольку-поскольку... 
 
	
 
	
		
			Сообщение от danik.js
			 
		
	 | 
 
	
		А что если у юзера был вызван jQuery.noConflict() ? 
Передать в анонимную функцию - обертку ссылку на jQuery, а внутри уже использовать знак доллара. Смотри как это сделано в других плагинах. Вообще, раз ты делаешь плагин, хоть бы не поленился и изучил как их делают другие.
	 | 
 
	
 
 Как сказал выше - в JS слаб, jQuery умею использовать, но не писать под него плагины... погляжу ну другие обязательно.
 
	
 
	
		
			Сообщение от danik.js
			 
		
	 | 
 
	| 
		Это самый последний вариант решения, когда подругому - ну никак. В данном же случае можно просто навесить обработчик onload на картинки и ждать их загрузки.
	 | 
 
	
 
 Согласен, такой вариант в голову не приходил. Перепишу.
 
	
 
	
		
			Сообщение от danik.js
			 
		
	 | 
 
	| 
		Как будто два разных человека писали код. addClass предпочтительней.
	 | 
 
	
 
 За исключением пересчета цвета для канваса - всё писал я. А разные методы т.к. по-разному думал в эти моменты. Что вспомнил, то и использовал... 
 
	
 
	
		
			Сообщение от danik.js
			 
		
	 | 
 
	| 
		Где используется функция createCanvas ?
	 | 
 
	
 
 Fail    осталась не вычещенной с момента сборки всего воедино.
 
	
 
	
		
			Сообщение от danik.js
			 
		
	 | 
 
	| 
		Зачем это? jQuery сама фиксит opacity в старых ишаках.
	 | 
 
	
 
 Это не фикс прозрачности, а её динамическое изменение. Этим и достигатся плавность перехода в IE.
 
	
 
	
		
			Сообщение от danik.js
			 
		
	 | 
 
	| 
		Перед .animate() нужно делать .stop() чтоб не образовывалось очереди.
	 | 
 
	
 
 Забыл    добавлю.
 
	
 
	
		
			Сообщение от Deff
			 
		
	 | 
 
	
		 На большинстве халявных сайтах и форумов, нет загрузки изо на текущий домен 
Пример Укоз, mybb.ru
	 | 
 
	
 
 Не подумал - добавлю.
 
	
 
	
		
			Сообщение от danik.js
			 
		
	 | 
 
	| 
		В WebKit и вроде 10м ишаке (не уверен) есть поддержка css mask, нужно проверять поддержку и по возможности использовать.
	 | 
 
	
 
 Почитаю что такое css mask. Пока я не понял о чем ты сказал.
 
	
 
	
		
			Сообщение от danik.js
			 
		
	 | 
 
	
		
$(newImg).attr('class', 'gray')
 
Слишком общий css-класс. Он может быть определен у юзера. Вообще, зачем тут css-классы назначать?
	 | 
 
	
 
 С названием класса согласен. Хотел изменить на уникальные... но, опять же, забыл. А классы назначал как признак того, что данное изображение - серое. Что бы с него не делать копий. Т.к. при моем способе вызова функции grayScale() - были возможны дубликаты и уже серых картинок. Но с img.onload - проблема уйдет.  
		
	
		
		
		
		
		
		
	
		
			
			
	
			
			
			
			
			
				 
			
			
			
			
			
			
				
			
			
			
		 
		
	
	
	 | 
 
 
	 
		 | 
 
 
 
 
 
 
	 | 
 
 
 |