Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #21 (permalink)  
Старый 25.02.2013, 14:01
Аспирант
Отправить личное сообщение для master_alf Посмотреть профиль Найти все сообщения от master_alf
 
Регистрация: 08.04.2010
Сообщений: 34

Сообщение от Deff Посмотреть сообщение
Лучше имхо отдельным расширением, связанным плагином
На хабре видал статейку, как реализуемо для свежих версий браузеров => http://habrahabr.ru/post/120917/
Спасибо, погляжу.
Ответить с цитированием
  #22 (permalink)  
Старый 25.02.2013, 14:19
без статуса
Отправить личное сообщение для Deff Посмотреть профиль Найти все сообщения от Deff
 
Регистрация: 25.05.2012
Сообщений: 8,219

Сообщение от master_alf
Как сказал выше - в JS слаб, jQuery умею использовать, но не писать под него плагины... погляжу ну другие обязательно.
Простейший Вариант

<script type="text/javascript" src="http://yandex.st/jquery/1.8.1/jquery.min.js"></script>
<script type="text/javascript">

//Плагин выдачи списка img, отмеченных неким классом ( в данном случае передаём в вызове класс .imgGray
$.fn.makeGray = function() {

    var imgArray = this; //this - переданый объект из jQuery ( При ниже вызове плагина это $(".imgGray")
    var arrOut = [];
    imgArray.each(function() {
         arrOut.push(this.src)
    });
  alert(arrOut.join(",\n"))
}

$(document).ready(function(){
   $(".imgGray").makeGray (); //Вызов и запуск плагина
});
</script>

<img class="imgGray" src="s2.png" />
<img class="imgGray" src="s1.png" />
Ответить с цитированием
  #23 (permalink)  
Старый 25.02.2013, 15:20
Аспирант
Отправить личное сообщение для master_alf Посмотреть профиль Найти все сообщения от master_alf
 
Регистрация: 08.04.2010
Сообщений: 34

Deff,
Спасибо, но уже бессмысленно нашел объяснение на сайте jQuery
переделал.
Пока без кроссдоменных картинок. Просто навел порядок во всем, на что указали. Вот код.

(function( $ ){
    $.fn.grayScale = function() {
        $(this).each(function() {
            this.onload = function() makeCopy(this);
        });

        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);
            $(newImg).offset(offset);
            $(newImg).hover(hoverIn, hoverOut);
        }

        function makeIMGCopy(imgObj) {
                var newImg = document.createElement('img');
                newImg.src = imgObj.src
                $(newImg).addClass('grayScaleGray');
                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).addClass('grayScaleGray');
            return newImg;
        }

        function hoverIn(obj) {
         $(this).stop().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 + ')');
                    $(fx.elem).css('ms-filter', 'progid:DXImageTransform.Microsoft.Alpha(Opacity=' + opacity + ')');
                    }
                  });
        }
        function hoverOut() {
            $(this).stop().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 + ')');
                    $(fx.elem).css('ms-filter', 'progid:DXImageTransform.Microsoft.Alpha(Opacity=' + opacity + ')');
                    }
                  });
        }
    };
})( jQuery );


Вот вызов.
<script type="text/javascript">
        $(document).ready(function() {
            $('div > img').grayScale();
        });
    </script>

Теперь работает как плагин 8)
Но снова появился баг в хроме.
Он ругается, что не может определить высоту для создаваемого canvasa, т.к. функция выполняется ДО полной загрузки картинки.
Как я понимаю, я где-то неправильно вызываю функцию. Как раз эти самые анонимные функции где-то и должны использоваться? Но смаху решения найти не смог. Объясните, пожалуйста, как правильно вызывать функции из событий (в моем случае image.onload), или же функцию из функции таким образом, что бы они исполнялись только в нужный момент, а не в момент загрузки?
Ответить с цитированием
  #24 (permalink)  
Старый 25.02.2013, 15:21
Аспирант
Отправить личное сообщение для master_alf Посмотреть профиль Найти все сообщения от master_alf
 
Регистрация: 08.04.2010
Сообщений: 34

$(this).each(function() {
            this.onload = function() makeCopy(this);
        });

Мне кажется, косяк где-то вот тут... но как правильно сделать - не пойму.
Ответить с цитированием
  #25 (permalink)  
Старый 25.02.2013, 15:49
без статуса
Отправить личное сообщение для Deff Посмотреть профиль Найти все сообщения от Deff
 
Регистрация: 25.05.2012
Сообщений: 8,219

Сообщение от master_alf
Он ругается, что не может определить высоту для создаваемого canvasa, т.к. функция выполняется ДО полной загрузки картинки
тут нужно ставить отслеживатель всех загрузок картинок,
1. Картинка после вызова

$(document).ready(function() {
           $('div > img').grayScale();


может уже быть загружена(и onload не будет вызываться, поэтому скорее всего вызов нужно делать без обертки в $(document).ready(function() {
а обернуть вызов и движение по функции до тега <body>
$(this).each(function() {
this.onload = function() makeCopy(this); //А тут уже можно парсить и не ждать DOM загрузки
});

Последний раз редактировалось Deff, 25.02.2013 в 15:51.
Ответить с цитированием
  #26 (permalink)  
Старый 25.02.2013, 15:55
Аспирант
Отправить личное сообщение для master_alf Посмотреть профиль Найти все сообщения от master_alf
 
Регистрация: 08.04.2010
Сообщений: 34

Прежде чем переносить реализацию на img.onload = func() я потестировал работу данного метода.
Просто цепляя на кнопку регистрацию обработчика события.
Т.е.
$('a').click(function() {
    var img = document.getElementById('myImage');
    img.onload = alert('work!');
});

И такое работало... Судя по тому, что я вижу в хроме, там проблема именно в том, что функция пытается выполниться не после загрузки картинки, а перед этим. Я где-то натыкался на пояснение, что по-разному оформленный вызов функций по-разному отрабатывается. Т.е. что-то пытается отработать сразу, в момент инициализации, а что-то просто загружается, и не покажет багу до момента вызова... Мне кажется, что у меня косяк именно тут. Или я не прав, и говорю не том вообще?
Ответить с цитированием
  #27 (permalink)  
Старый 25.02.2013, 16:06
без статуса
Отправить личное сообщение для Deff Посмотреть профиль Найти все сообщения от Deff
 
Регистрация: 25.05.2012
Сообщений: 8,219

Нун гуглить , тут пару дней назад на этом форуме разбирали загрузку-подгрузку ожидание картинок
Ответить с цитированием
  #28 (permalink)  
Старый 25.02.2013, 16:09
Аспирант
Отправить личное сообщение для master_alf Посмотреть профиль Найти все сообщения от master_alf
 
Регистрация: 08.04.2010
Сообщений: 34

Deff,
Я понял о чем ты говоришь. Но это не работает. Проверил все варианты - убрал документ.реди(), переместил вызов в head. Все эти варианты не помогают. Да и не могут. Ведь проблема не в том, что onload Не срабатывает - он срабатывает даже когда всё давно загрузилось, о чем я и говорил своим примером с кликом по ссылке.
Дело как раз в том, что скрипт загружаясь До картинки, почему-то инициализируется на выполнение, и пытается получить данные о размерах еще не загруженного изображения. И только в Хроме и Сафари получается баг - т.к. скрипт срабатывает ДО загрузки изображения. Ишак, опера и ФФ - без проблем ожидают загрузки изображений.
Ответить с цитированием
  #29 (permalink)  
Старый 25.02.2013, 16:45
Аспирант
Отправить личное сообщение для master_alf Посмотреть профиль Найти все сообщения от master_alf
 
Регистрация: 08.04.2010
Сообщений: 34

Блин! Разобрался...
Хром, зараза... в общем, дело вот в чем.
Если вызов делать вида
this.onload = makeCopy(this);

Будет ошибка. А если вида
this.onload = function() {makeCopy(this)};

Всё нормально! НО! Хром, останавливаясь на ошибке, игнорирует изменения кода если страницу тупо перезапускать, не нажимая "продолжить отладку". Уж не знаю почему так... может это какой-то глюк конкретно моего хрома... в общем - я нашел способ правильной записи. Завтра добавлю поддержку картинок со сторонних сайтов, и, если у спецов замечаний по коду больше не будет - то плагин готов

Спасибо всем за помощь.
Ответить с цитированием
  #30 (permalink)  
Старый 25.02.2013, 16:53
без статуса
Отправить личное сообщение для Deff Посмотреть профиль Найти все сообщения от Deff
 
Регистрация: 25.05.2012
Сообщений: 8,219

master_alf,
Может делать иной алгоритм
1. Дожидаемся загрузки страницы,
2. далее создаём - перебираем массив всех картинок
3. Смотрим подгружена картинка или нет
Если нет, -вынимаем её из очереди обработки и вешаем onload
Ответить с цитированием
Ответ



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

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