
Технологии и задача
Кропалка была написана на CoffeeScript — небольшом языке, компилируемом в JavaScript. Оформлена кропалка в виде плагина для jQuery. После загрузки изображения натравливаем на него кропалку — она отрисует поверх изображения канвас с возможностю выделения области. После каждого изменения выделенной области новая картинка записывается в data изображения и к ней можно легко получить доступ извне. Кропалка должна позволять включать превью, устанавливать фиксированное отношение сторон и устанавливать выделение сразу после активации. И, конечно же, кропалка должна работать во всех мажорных браузерах.
Реализация
Область выделения и уголки, за которые область можно растягивать, представлены классом
Rect
. Ничего волшебного в нем нет — свойства с координатами, методы для определения попадания точки и обновления координат. Класс EvroneCrop
отвечает за создание канваса, отрисовку его поверх картинки, навешивание обработчиков и сохранение обрезанной картинки в data.Для сохранения получившейся картинки создается временный элемент canvas, рассчитываются координаты с учетом оригинального размера изображения, при помощи метода
drawImage()
выделенная область отрисовывается во временный canvas, и при помощи метода toDataURL()
из canvas
получаем результирующее изображение, которое в виде строки base64 можно передать на сервер и сохранить.В нашем случае для сохранения на сервере используется следующий код (Ruby):
encoded_image = params[:image].sub('data:image/png;base64,', '')
avatar_io = FilelessIO.new(Base64.decode64(encoded_image))
avatar_io.original_filename = "avatar.png" # любое значение, обязательный параметр для CarrierWave
Rails.logger.info "IO: #{avatar_io.inspect}"
@user.avatar = avatar_io
@user.save
При создании кропалке можно передать следующие параметры:
$(this).evroneCrop({
preview: '#preview1', //селектор элемента img, в котором отображать превью
size: {w: 150, h: 150}, //размер результирующего изображения
ratio: 1, //отношение сторон области выделения, в данном случае - квадрат
setSelect: 'center', //установка выделения по умолчанию
log: true //вывод отладочной информации
});
Все параметры опциональны. Демо.
setSelect
может принимать значение center
, автоматически рассчитывая центр изображения и размер выделения, или может принимать объект {x:0, y: 0, w: 100, h: 100}
и устанавливать выделение в заданную позицию. Если у вас установлен параметр ratio
— высоту в объекте для setSelect
передавать не нужно.ratio
принимает число, больше нуля, и фиксирует стороны с отношением длин, равным этому числу. Например, можно передать 1 для квадрата или 16/9 для отношения сторон 16 к 9.Браузерные заморочки
Получившийся инструмент работает во всех мажорных браузерах — Chrome, Firefox > 4, Safari, Opera >11, IE 9. В планах есть написание fallback'а во флэш для IE8. Изначально планировалось использовать гугловый excanvas, но тот, как оказалось, не предоставляет такого необходимого для нашей задачи метода, как
toDataURL();
Есть выход с реализацией на флеше, но до него руки пока не дошли.Кропалка еще сыровата, например, до сих пор не реализована установка минимального и максимального размера, но она лежит на гитхабе, работает, и потихоньку развивается.