HTML5 web приложение с фильтрами как в Instagram. Часть 1.
В этой серии статей я расскажу как можно сделать простое HTML5 веб-приложение для обработки изображений. Пользователь может выбрать или перетащить фотографию на своём компьютере в окно браузера и применить к нему фильтры, похожие на фильтры Instagram. После применения подходящего фильтра полученное изображение может быть скачано на компьютер.
Посмотреть демо приложения Вы можете на моём аккаунте codepen: http://codepen.io/nikitakiselev/full/kXyBAP/.
- Техническое задание
- Введение
- Подготовка инструментов
- Добавление проекта на GitHub
- Написание HTML каркаса
- Написание Javascript кода
- Написание CSS кода
- Заключение
Определим краткое техническое задание для разработки.
Необходимо создать веб приложение, позволяющее накладывать фильтры на изображение. Изображение должно загружаться с компьютера с помощью перетягивания "Drag'n'Drop". Предусмотреть возможность загрузки изображения с помощью стандартного диаголового окна выбора файла.
Разрешённые форматы изображений: jpg и png. Если пользователь пытается загрузить файл или изображение другого формата, необходимо уведомить его о том, что данный тип файла не поддерживается. В целях экономии ресурсов, изображение для обработки фильтрами должно масштабироваться до 500x500 пикселей.
После выбора изображения пользователь должен увидеть список фильтров, которые он сможет применять на изображении. Фильтры не должны смешиваться.
После выбора подходящего фильтра необходимо дать возможность пользователю скачать изображение на свой компьютер. К имени скачиваемого файла должен добавлять суффикс с названием фильтра, которым он обработан. Например, если пользователь загружает файл изображения с именем avatar.jpg и применяет фильтр "vintage", то скачиваемое изображение должно быть с именем avatar-vintage.png.
Веб приложение должно быть интуитивно понятным, с ненагруженным тёмным дизайном.
Все остальные, неописанные в данном разделе нюансы, делаются на усмотрение разработчика.
Для написания приложения нам понадобятся средующие ресурсы:
Caman.js мощный инструмент для canvas, который позволяет применять различные эффекты и фильтры на изображение. Он поставляется с 18 предустановленными фильтрами, которые мы будем использовать в этом примере (но Вы можете создать больше, если хотите); jQuery: будем использовать версию 2.*; jQuery Mousewheel плагин для прокрутки списка эфеектов для изображений колесом мыши;
Разрабатывать приложение я буду на своей локальной машине, на которой установлена операционная система elementary OS 0.3.2 Freya (64-bit). Код я буду набирать в текстовом редакторе Sublime Text build 3114.
Для сборки проекта воспользуемся сборщиком Gulp. В качестве веб сервера будет выступать простой http сервер на node.js. В качестве препроцессора CSS будет использоваться SASS с синтаксисом SCSS. Так же, необходимо будет прогонять весь CSS код через autoprefixer, чтобы он автоматически добавлял префиксы к свойствам CSS.
Для написания javascript кода я буду использовать синтаксис ECMAScript 6. Компиляцией ECMA6 кода в ECMA5 будет заниматься Babel.
Создадим папку, в которой будет находиться наше приложение и перейдём в неё:
12
mkdir html5-insta-filters
cd html5-insta-filters
Создадим файл package.json коммандой
1
npm init -y
и установим все необходимые инструменты для работы:
1
npm install --save-dev gulp gulp-sourcemaps gulp-autoprefixer gulp-sass gulp-babel babel-preset-es2015 gulp-serve -y
Опишу подробнее, для чего нужен каждый из пакетов:
gulp лучший сборщик проектов на node.js. Поможет автоматизировать огромное количество рутинных задач, таких как компиляция из SASS в CSS, добавление преффиксов к CSS свойствам, компиляция ECMA6 и т.д. http://gulpjs.com/ gulp-sourcemaps генерирует css sourscemaps, что позволяет соотносить строки в файлах SCSS со строками уже откомпилированного CSS. Т.е. если в том же google chrome проинспектировать объект, то строки и файлы стилей будет показываться из SASS файлов, вместо откомпилированного CSS файла. https://www.npmjs.com/package/gulp-sourcemaps gulp-autoprefixer автоматически следит и добавляет необходимые префиксы к CSS свойствам. Можно писать CSS не задумываять о -webkit-, -moz и т.д. https://www.npmjs.com/package/gulp-autoprefixer gulp-sass обертка над node-sass, позволяет компилировать SASS код в CSS. https://www.npmjs.com/package/gulp-sass gulp-babel и babel-preset-es2015 gulp-babel это обёртка над Babel. А Babel с пресетами babel-preset-es2015 позволяет уже сейчас пользоваться преимуществами нового синтаксиса ECMA6, не задумываях о поддержке его браузерами, т.к. babel будет компилировать код с старый ECMA5. https://www.npmjs.com/package/gulp-babel gulp-serve простой http сервер, написанный на node.js. На нём мы будем запускать приложение. https://www.npmjs.com/package/gulp-serve
Теперь займёмся настройкой gulp со всеми, только что установленными, пакетами. Для начала создадим файл gulpfile.js:
1
touch gulpfile.js
В нём нужно описать всю логику сборки проекта gulp'ом.
Все SASS файлы приложения мы будем хранить в папке src/scss. Откомпилированные CSS файлы будут располагаться в папке css. Основным файлом будет являться файл src/scss/app.scss. Его и нужно будет компилировать. Создадим необходимые папки и файлы:
1
mkdir -p src/scss && touch src/scss/app.scss
Теперь напишем код для компиляции SCSS:
gulpfile.js
1234567891011121314
var gulp = require('gulp');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var autoprefixer = require('gulp-autoprefixer');
gulp.task('sass', function () {
return gulp.src('./src/scss/app.scss')
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(autoprefixer({browsers: ['last 3 versions']}))
.pipe(sourcemaps.write('maps'))
.pipe(gulp.dest('./css'));
});
Здесь берётся файл ./src/sass/app.scss, компилируется в css, далее по этому css "проходит" autoprefixer с поддержкой 3 последних браузеров, создаётся файл app.css.map с css sourcemap, откомпилированный SASS созраняется в папку ./css/app.css. Дальнейшие правки стилей должны проводиться в файле app.scss, а не app.css.
Теперь, если написать код в файле /src/sass/app.scss для примера:
123
.row {
display: flex;
}
и запустим команду для компиляции sass
1
gulp sass
мы увидим, что создалась папка ./css а в ней файл app.css со уже добаленными нужными префиксами и строкой sourceMappingURL, которая указывает на файл css sourcemap.
123456
.row {
display: -webkit-flex;
display: -ms-flexbox;
display: flex; }
Настройка компилятора SASS завершена.
Т.к. ещё не все браузеры поддерживают спецификацию ECMA6, а писать на новом удобном синтаксисе уже хочется, существует babel, который компилирует код в ECMA5, который уже поддерживают все браузеры. Другими словами ECMA5 это и есть обычный javascript, к которому мы все привыкли.
Исходные файлы javascript будут находиться с папке ./src/js и компилироваться в папку ./scripts.
Создадим папку с файлом app.js в котором будем писать весь javasctipt код приложения.
12
mkdir src/js
touch src/js/app.js
Для компиляции ECMA6 необходимо написать новую задачу в файле gulpfile.js.
gulpfile.js
123456789101112
var babel = require('gulp-babel');
gulp.task('babel', function() {
return gulp.src('./src/js/app.js')
.pipe(sourcemaps.init())
.pipe(babel({
presets: ['es2015']
}))
.pipe(sourcemaps.write('maps'))
.pipe(gulp.dest('./scripts'));
});
При компиляции так же будет создаваться source map. На этом настройка компилятора закончена.
Создадим точку входа в наше приложения - файл index.html и добавим в него содержимое:
1
echo "Web server works..." > index.html
Напишем задачу для запуска http сервера, всё так же в файле gulpfile.js:
gulpfile.js
123
var serve = require('gulp-serve');
gulp.task('serve', serve('./'));
Теперь, если запустить задачу gulp serve, и перейти по адресу http://127.0.0.1:3000/ можно увидеть текст "Web server works..." , который мы написали в файле index.html.
Сервер настроен и работает.
Каждый раз, когда мы будем изменять код проекта, необходимо запускать компиляцию gulp sass или gulp babel, что не очень удобно. Этот процесс можно автоматизировать и сделать так, чтобы задачи запускались автоматически, при изменении файлов. Для этого и существует watcher (наблюдатель), и он уже встроен в gulp.
Добавим новую задачу в gulpfile.js, котороя будет называться watch:
gulpfile.js
123456789
gulp.task('watch', function() {
gulp.watch('src/js/**/*.js', function(event) {
gulp.run('babel');
});
gulp.watch('src/scss/**/*.scss', function(event) {
gulp.run('sass');
});
});
Перед выполнением задачи watch запускается наш http сервер. Далее я создаю наблюдателей для всех файлов js в папке src/js, включая подпапки, и при их изменении будет запускаться задача "babel". То же самои и для файлов scss.
Теперь, перед тем как работать с проектом необходимо запустить watcher gulp watch, и спокойно писать код.
1
gulp watch
У стандартного watchera есть некоторые недостатки, например после запуска gulp watch он не "видит" новые файлы, нужно каждый раз после создания файла перезапускать watcher. Но для наших задач подойдёт и такой вариант, т.к. целью статьи является разработка именно приложения, а не инструкцию по продвитой настройке gulp.
Если в консоли выполнить команду gulp, то ничего не произойдёт, т.к. мы не объявили действие умолчанию. Такая задача должна называться default. Давайте создадим её, чтобы при запуске этой команды проект компилировался:
gulpfile.js
1
gulp.task('default', ['sass', 'babel']);
Эта команда просто вызывает другие: sass и babel.
Как обычно, добавим в проект систему контроля версий git и добавим весь проект на github. Перед добавлением необходимо создать файл .gitignore и прописать в нём папки и файлы, которые будут исключены при добавлении в репозиторий.
1
touch .gitignore
.gitignore
123
/css
/scripts
/node_modules
Теперь инициализируем git, добавляем проект и делаем первый коммит.
123
git init
git add .
git commit -m 'Init project'
Я создам на своём github аккаунте удалённый репозиторий, на котором размещу проект, чтобы читатели статьи могли посмотреть исходный код статьи и состояние проекта на каждой из стадий.
12
git remote add origin git@github.com:mblog-repository/html5-insta-filters.git
git push -u origin master
На этом первая часть статьи "HTML5 web приложение с фильтрами как в Instagram" завершена. Здесь я размещу ссылку на удалённый репозиторий с текущим состоянием проекта 0d2b24a. Если у вас есть какие либо вопросы, задавайте их в комментариях. Если вы сочли статью полезной, поделитесь ею с друзьями с соц сетях, ссылки даны ниже.
Продолжение HTML5 web приложение с фильтрами как в Instagram. Часть 2.