Advertisement
  1. Code
  2. Web Development
Code

Создание плагина jQuery для обрезания изображения с нуля (Часть 1)

by
Difficulty:IntermediateLength:LongLanguages:

Russian (Pусский) translation by Nadia Gonzales (you can also view the original English article)

Веб-приложения должны предоставлять пользователям удобные для использования решения для закачивания и манипулирования мультимедиа (* форма информации, отличная от текста и статических изображений (аудио, видео). Обычно интерактивная. Здесь и далее прим. пер.). При этом у некоторых пользователей с минимальными навыками редактирования изображений могут возникнуть трудности. Обрезание изображений – одна из наиболее частых операций над изображениями, и в этом пошаговом руководстве будет рассмотрен процесс разработки плагина для обрезания изображений с нуля для библиотеки JavaScript jQuery.


Шаг 1: Настраиваем рабочую среду

Для начала мы настроим рабочую среду, необходимую для работы с данным руководством. Начните с создания дерева папок и пустых файлов, названных, как показано ниже на изображении:

Directory tree

Далее необходимо скачать библиотеку JavaScript jQuery и поместить ее в папку /resources/js/. Изображение, которое будем использовать в руководстве, необходимо назвать example.jpg и поместить его в папку /resources/images/. Вы можете использовать это изображение (поблагодарим gsso-stock), которое входит в состав исходных файлов для этого руководства, или свое собственное. И последний файл – outline.gif, который необходимо поместить в папку /resources/js/imageCrop/.


Шаг 2: Создаем страницу для тестирования

Для тестирования нашего плагина нам необходимо будет добавить его к изображению. Перед тем, как начать работу над плагином, мы создадим простую страницу с этим изображением.

Код HTML

Откройте ваш любимый текстовый редактор и напишите следующий код в файле index.html:

Здесь нет ничего необычного: простой код HTML. Мы добавили таблицу со стилями для страницы, jQuery, файлы нашего плагина (пока пусты) и разместили внутри документа изображение.

Код CSS

Теперь отредактируйте style.css, как показано ниже:

Мы настроили вид нашей страницы путем изменения цвета фона и добавления основного стилевого оформления для заголовка и изображения.


Шаг 3: Пишем базовую версию плагина jQuery

Давайте начнем с создания базовой версии плагина jQuery.

«Узнайте больше о создании своего собственного плагина в этом посте. В нем рассматриваются основные сведения, установившиеся практики и часто встречающиеся «подводные камни», о которых следует знать при разработке вашего плагина».

Откройте /resources/js/imageCrop/jquery.imagecrop.js и добавьте следующий код:

Мы только что расширили возможности jQuery за счет добавления нового метода к объекту jQuery.fn. Теперь у нас имеется простейший плагин, в котором к каждому объекту после его загрузки применяется метод imageCrop (* то есть плагин можно будет инициировать для нескольких изображений). Обратите внимание на то, что изображения из кэша иногда не генерируют событие load, поэтому для подстраховки мы переустанавливаем значение атрибута src.


Шаг 4: Добавляем опции для настройки плагина

За счет предоставления возможности добавления опций плагин становится намного гибче для пользователя.

Мы определили объект с опциями по умолчанию, затем объединили их с пользовательскими опциями при помощи вызова функции setOptions. Теперь давайте напишем тело этой функции.

$.extend() добавляет содержимое двух или более объектов к первому объекту.

Опции

Ниже разъясняется, для чего используется каждая опция плагина.

  • allowMove – при помощи этой опции указывается, может ли двигаться выделенная область изображения (значение по умолчанию – true).
  • allowResize – с помощью этой опции указывается, можно  ли изменять размер выделенной области изображения (значение по умолчанию – true).
  • allowSelect – при помощи этой опции указывается, можно ли пользователю задавать новую область выделения (значение по умолчанию – true).
  • minSelect – с помощью этой опции задается минимальный размер области, по достижении которого новая  выделенная область изображения будет принята (* а не сброшена) (значение по умолчанию – [0, 0]).
  • outlineOpacity – используется для задания прозрачности контура (значение по умолчанию – 0.5).
  • overlayOpacity – используется для задания прозрачности верхнего слоя (значение по умолчанию – 0.5).
  • selectionPosition – используется для задания расположения выделенной области изображения (значение по умолчанию – [0, 0]).
  • selectionWidth – используется для установления значения ширины выделенной области изображения (значение по умолчанию – 0).
  • selectionHeight – используется для установления значения высоты выделенной области изображения (значение по умолчанию – 0).

Шаг 5: Настраиваем слои

На данном этапе мы изменим DOM для подготовки к следующему шагу: созданию интерфейса плагина.

Layers overview

Для начала мы инициализируем слой изображения.

Теперь инициализируйте держатель изображения (* элемент, в котором будет располагаться изображение).

Как вы видите, его размеры такие же, как и у изображения, а также для него используется относительное позиционирование. Далее мы вызываем функцию .wrap() для помещения изображения внутрь держателя.

Поверх слоя с изображением будет находиться верхний.

Этот слой имеет те же самые размеры, что и изображение, однако для него задано абсолютное позиционирование. Мы получаем значение прозрачности из options.overlayOpacity и позволяем jQuery его использовать. Также у этого элемента есть id, так что мы можем менять его свойства при помощи таблицы со стилями плагина. В конце мы вызываем метод .insertAfter() для размещения верхнего слоя сразу после изображения.

Следующий слой – триггерный (* триггер – совокупность условий, инициирующих выполнение действия); мы разместим его после верхнего слоя также, как мы делали с предыдущими.

В целом значение background color не играет роли, однако оно должно быть отличным от прозрачного (значение по умолчанию). Этот слой невидим для пользователя, однако с его помощью будут обрабатываться некоторые события.

Поверх триггерного слоя мы разместим слой для контура.

И, наконец, переходим к последнему слою.

Метод .attr() возвращает значение переданного в него атрибута. Мы воспользовались им для получения значения src изображения и установления его в качестве значения background слоя для выделения области.

Использование абсолютного позиционирования для элементов, находящихся внутри элементов с относительным позиционированием.

Вполне возможно, вы уже в курсе об этом, но сообщу, что при помощи элемента с относительным позиционированием вы получаете контроль над элементом внутри него с абсолютным позиционированием. Именно поэтому для слоя держателя используется относительное позиционирование, а для всех дочерних слоев – абсолютное.

Отличное объяснение этой техники дается в этой статье.


Шаг 6: Обновляем интерфейс

Для начала мы инициализируем некоторые переменные.

При помощи selectionExists мы узнаем, имеется ли область выделения. В переменной selectionOffset будем хранить значение отступа по отношению к началу координат изображения, а в переменной selectionOrigin – значение начальных координат области выделения. Скоро станет намного понятнее.

Следующие условия необходимы для проверки наличия области выделения после загрузки плагина.

Далее мы вызываем функцию updateInterface() впервые для инициализации интерфейса.

Мы напишем тело этой функции очень скоро. А сейчас давайте поработаем над нашим первым событием.

Мы вызываем .mousedown(), если значение options.allowSelect true. За счет этого для события mousedown, возникающего на триггерном слое, будет назначен обработчик. Таким образом, если пользователь кликает изображение, то будет вызвана функция setSelection().

Первая функция – getElementOffset() – возвращает значения левой и правой координат переданного ей объекта по отношению к документу. Мы их получили при помощи вызова метода .offset(). Вторая функция – getMousePosition() – возвращает координаты текущего положения курсора (по отношению к позиции изображения). Таким образом, мы будем работать только со значениями в диапазоне от 0 до ширины/высоты изображения по осям х/у соответственно.

Давайте напишем функции для обновления наших слоев.

В этой функции на основании значения selectionExists определяется, необходимо ли показывать верхний слой.

При помощи функции updateTriggerLayer() изменяется форма курсора (перекрестие (crosshair) или форма по умолчанию (default)) на основании значения options.allowSelect.

Далее приступаем к функции updateSelection(). В ней обновляется как слой для выделения области, так и слой с контуром.

Сначала в этой функции устанавливаются значения свойств слоя с контуром: форма курсора, тип отображения, размеры и его позиция. Далее работаем со слоем для выделения области; за счет нового значения background-position изображения будут перекрываться незаметно.

Теперь нам необходимо написать функцию для обновления курсора при необходимости. Например, при выделении области нам необходимо, чтобы курсор оставался в форме перекрестия (crosshair)  независимо от того, на каком слое он находится.

Да, все именно так просто, как выглядит. Просто меняем форму курсора на указанную!

Теперь переходим к последней функции на этом этапе; она будем нам необходима для обновления интерфейса плагина при различных условиях – выделении области, изменении размеров, завершении выделения и даже при инициализации плагина.

Как вы видите, в функции updateInterface() происходит выбор одного из предложений case (* оператор множественного выбора) и вызов определенных функций, которые только что написали.


Шаг 7: Реализуем возможность создания области выделения изображения

На данный момент мы позаботились о пользовательских опциях и об интерфейсе, но не затрагивали вопрос взаимодействия пользователя с плагином. Давайте напишем функцию, при помощи которой будет происходить выделение новой области при клике по изображению.

Итак, сначала в функции setSelection происходит вызов двух методов: event.preventDefault() и event.stopPropagation(). Благодаря этому предотвращается выполнение действий  по умолчанию при возникновении событий и извещение обработчиков, назначенных для родительских элементов, о событиях. За счет .mousemove() для события mousemove регистрируется обработчик. При этом будет вызываться функция resizeSelection() каждый раз при перемещении пользователем курсора мыши. Для извещения о том, что область выделена, значением переменной selectionExists устанавливается true и размер области сбрасывается на 0. Далее мы получаем начальные координаты области выделения при помощи вызова ранее написанной функции, getMousePosition(), и передаем их options.selectionPosition. Наконец, мы вызываем функцию updateInterface() для обновления интерфейса плагина с учетом внесенных нами изменений.


Шаг 8: Реализуем возможность изменения размера области  выделения изображения

В предыдущем шаге мы написали функцию для реализации возможности выбора области. Теперь давайте напишем функцию для изменения размера этой области выделения.

Для этого нам необходимо будет получить текущие координаты мыши. Поскольку возвращенное значение вычислялось относительно размера изображения, нам необходимо позаботиться только о негативных значениях. Область выделения никогда не выйдет за границы изображения. Как вы знаете, значение свойства width или height не может быть отрицательными. Поэтому мы используем Math.abs() для получения абсолютного значения и затем изменяем положение выделенной области.


Шаг 9: Реализуем возможность прекращения выделения области изображения

И теперь переходим к последней функции.

После прекращения выделения области в  releaseSelection() удаляются ранее назначенные в функции setSelection() обработчики событий при помощи метода .unbind(). Далее происходит обновление начальных координат области выделения и проверка размера области выделения, достаточного для того, чтобы область выделения была принята.

Теперь почти все готово. Закройте файл и подготовьтесь к следующему шагу.


Шаг 10: Добавляем стилевое оформление для плагина

Откройте таблицу со стилями /resources/js/imageCrop/jquery.imagecrop.css и добавьте следующий код:

Ничего сложного: мы добавили несколько стилевых правил для верхнего слоя и слоя с контуром.


Шаг 11: Тестируем конечный результат

Для тестирования нашего плагина нам необходимо подключить его к изображению. Давайте это сделаем,  отредактировав наш файл index.html.

Откройте тег script ...

... и напишите следующий код JavaScript.

Мы подключили наш плагин к элементу изображения с id example и задали значения некоторых пользовательских опций. Мы воспользовались методом .ready() для отслеживания момента, кода DOM полностью загружена.

Plug-in preview

Вот и все! Сохраните файл и откройте ваш браузер для тестирования плагина.


Следующие шаги

Теперь у нас имеется базовая версия плагина jQuery для обрезания изображений, при помощи которого мы можем выбрать определенную область изображения. В следующей части мы добавим дополнительные опции для настройки плагина, создадим панель для предварительного просмотра, напишем определенный код, который будет выполняться на сервере, для обрезания изображения... и много еще чего. Надеюсь, вы с пользой провели время и изложенный здесь материал вам пригодиться. Спасибо проявленный интерес!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.