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', 'progidXImageTransform.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 - проблема уйдет.
|
|
|
|