В этом руководстве мы разберем, как создать простое веб-приложение, с помощью которого можно будет перетаскивать фотографии с вашего компьютера в браузер и применять на них фильтры, как в Instagram.
Для приложения будем использовать следующие JavaScript библиотеки и плагины:
- Caman.js — это мощная графическая библиотека, которая работает с канвой. Она поставляется с 18 предустановленными фильтрами, которые мы будем использовать в нашем проекте (также вы сможете создавать свои фильтры);
Filereader.js – это легкая надстройка над HTML5 событиями drag/drop, что сделает работу с ними гораздо проще;jQuery Mousewheel будем использовать для прокрутки фильтров в контейнере;- Ядром будет самая последняя версия библиотеки jQuery.
HTML
Первым шагом пишем HTML каркас приложения:
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Instagram-like Filters with jQuery | Tutorialzine Demo</title> <link href="assets/css/style.css" rel="stylesheet" /> <!-- Включаем шрифт Yanone Kaffeesatz --> <link href="http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz:400,200" rel="stylesheet" /> </head> <body> <h1>Instagram <b>Filters</b></h1> <div id="photo"></div> <div id="filterContainer"> <ul id="filters"> <li> <a href="#" id="normal">Normal</a> </li> <li> <a href="#" id="vintage">Vintage</a> </li> <li> <a href="#" id="lomo">Lomo</a> </li> <li> <a href="#" id="clarity">Clarity</a> </li> <li> <a href="#" id="sinCity">Sin City</a> </li> <!-- 14 More filters go here --> </ul> </div> <!-- Библиотеки --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <script src="assets/js/filereader.min.js"></script> <script src="assets/js/caman.full.js"></script> <script src="assets/js/jquery.mousewheel.min.js"></script> <script src="assets/js/script.js"></script> </body> </html> |
Еще стоит добавить, что мы включили в проект файл script.js. О нем речь пойдет позже. И добавили шрифт Yanone Kaffeesatz из Google Web Fonts.
JavaScript/jQuery
Для того, чтобы приложение заработало, проделаем следующие вещи:
- Примем изображение через drag&drop;
- Создадим новый элемент канвы (оригинал), с максимальным размером 500x500px (настраиваемо) и сохраним его в памяти;
- Будем наблюдать за кликами на фильтрах, когда один из них будет выбран:
- Создадим копию канвы оригинала;
- Удалим любой элемент канвы на странице;
- Применим копию на элемент
div
сid
равнымphoto
- Если выбранный фильтр будет отличатся от “Normal”, тогда вызовем библиотеку Caman. Иначе ничего вызывать не будем;
- Пометим выбранный фильтр классом “active”.
- Запустим фильтр “Normal”.
Приступим к созданию кода!
assets/js/script.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
$(function() { var maxWidth = 500, maxHeight = 500, photo = $('#photo'), originalCanvas = null, filters = $('#filters li a'), filterContainer = $('#filterContainer'); // Используем плагин fileReader для прослушки событий // drag&drop на элементе div с #photo: photo.fileReaderJS({ on:{ load: function(e, file){ // Изображение "упало". var img = $('<img>').appendTo(photo), imgWidth, newWidth, imgHeight, newHeight, ratio; // Удаляем элемент канвы со страницы photo.find('canvas').remove(); filters.removeClass('active'); // После того, как изображение будет загружено, // мы определим его высоту и ширину: img.load(function() { imgWidth = this.width; imgHeight = this.height; // Вычисляем новые размеры изображения, чтобы вместить его в // maxWidth x maxHeight контейнер if (imgWidth >= maxWidth || imgHeight >= maxHeight) { // Если изображение слишком велико, // изменяем его размер до 500x500! if (imgWidth > imgHeight) { // Широкое ratio = imgWidth / maxWidth; newWidth = maxWidth; newHeight = imgHeight / ratio; } else { // Длинное или квадратное ratio = imgHeight / maxHeight; newHeight = maxHeight; newWidth = imgWidth / ratio; } } else { newHeight = imgHeight; newWidth = imgWidth; } // Создадим элемент канвы. originalCanvas = $('<canvas>'); var originalContext = originalCanvas[0].getContext('2d'); // Центрируем originalCanvas.attr({ width: newWidth, height: newHeight }).css({ marginTop: -newHeight/2, marginLeft: -newWidth/2 }); // Отрисовываем изображение на канве // с новыми размерами originalContext.drawImage(this, 0, 0, newWidth, newHeight); // Больше не нужно img.remove(); filterContainer.fadeIn(); // Запускаем фильтр "normal" filters.first().click(); }); // Устанавливаем src изображения, для последующих // манипуляций: img.attr('src', e.target.result); }, beforestart: function(file){ // Принимаем только файлы изображений. return /^image/.test(file.type); } } }); // Наблюдаем за кликами на фильтрах filters.click(function(e){ e.preventDefault(); var f = $(this); if(f.is('.active')){ return false; } filters.removeClass('active'); f.addClass('active'); // Копируем канву var clone = originalCanvas.clone(); // Копируем изображение в канве clone[0].getContext('2d').drawImage(originalCanvas[0],0,0); // Добавляем копию на страницу и запускаем на ней // библиотеку Caman photo.html(clone); var effect = $.trim(f[0].id); Caman(clone[0], function () { // Если такой эффект есть, применяем его: if( effect in this){ this[effect](); this.render(); } }); }); // Используем плагин mousewheel для прокрутки filterContainer.find('ul').on('mousewheel',function(e, delta){ this.scrollLeft -= (delta * 50); e.preventDefault(); }); }); |
Этот пример будет работать во всех браузерах, поддерживающих технологию drag/drop. Некоторые из фильтров могут нагружать процессор компьютера, поэтому могут быть отставания в прорисовке изображения при выборе фильтра. Чтобы ускорить процесс, мы ограничили ширину и высоту получаемых изображений, но вы можете поставить свои ограничения.