Client-side sprinkler on canvas
At one of the projects, it was necessary to make a crop for avatars loaded by users. Standard solutions, such as Jcrop, after selecting the area, send the coordinates to the server, and the image crop itself must be implemented already on the server. Meanwhile, modern browsers have already reached the point where such actions can be carried out immediately on the client. This prompted me to write my own crop using canvas, which would perform all the actions on the client and send the finished image in the form of a base64 string to the server. In addition to speeding up the work and unloading the server, it will also allow us to immediately change the user avatar on the page, without loading it from the server.
Kropalka was written in CoffeeScript - a small language compiled in JavaScript. Decorated Kropalka as a plugin for jQuery. After loading the image, we set the crop on it - it will draw a canvas over the image with the possibility of highlighting the area. After each change of the selected area, a new picture is recorded in the image data and can be easily accessed from the outside. Kropalka should allow you to include previews, establish a fixed aspect ratio and set the selection immediately after activation. And, of course, cropping should work in all major browsers.
The selection area and the corners beyond which the area can be stretched are represented by the class
To save the resulting image a temporary element of the canvas, the coordinates are calculated based on the original image size, using the method of
In our case, the following code is used for saving on the server (Ruby):
When creating a sprinkler, you can pass the following parameters:
All parameters are optional. Demo .
The resulting tool works in all major browsers - Chrome, Firefox> 4, Safari, Opera> 11, IE 9. There are plans to write a fallback in flash for IE8. It was originally planned to use Google's excanvas , but it turned out that it does not provide such a method necessary for our task as
Kropalka is still damp, for example, the installation of the minimum and maximum sizes has not yet been implemented, but it lies on the github , works, and is slowly developing.
Technology and challenge
Kropalka was written in CoffeeScript - a small language compiled in JavaScript. Decorated Kropalka as a plugin for jQuery. After loading the image, we set the crop on it - it will draw a canvas over the image with the possibility of highlighting the area. After each change of the selected area, a new picture is recorded in the image data and can be easily accessed from the outside. Kropalka should allow you to include previews, establish a fixed aspect ratio and set the selection immediately after activation. And, of course, cropping should work in all major browsers.
Implementation
The selection area and the corners beyond which the area can be stretched are represented by the class
Rect
. There is nothing magical in it - properties with coordinates, methods for determining the hit of a point and updating coordinates. The class EvroneCrop
is responsible for creating the canvas, drawing it on top of the picture, hanging handlers and saving the cropped picture in data. To save the resulting image a temporary element of the canvas, the coordinates are calculated based on the original image size, using the method of
drawImage()
the selected area is drawn into a temporary the canvas, and using the method toDataURL()
of canvas
a resultant image that is in the form of base64 strings can be passed to the server and save.In our case, the following code is used for saving on the server (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
When creating a sprinkler, you can pass the following parameters:
$(this).evroneCrop({
preview: '#preview1', //селектор элемента img, в котором отображать превью
size: {w: 150, h: 150}, //размер результирующего изображения
ratio: 1, //отношение сторон области выделения, в данном случае - квадрат
setSelect: 'center', //установка выделения по умолчанию
log: true //вывод отладочной информации
});
All parameters are optional. Demo .
setSelect
can take a value center
by automatically calculating the center of the image and the size of the selection, or it can take an object {x:0, y: 0, w: 100, h: 100}
and set the selection to a given position. If you have the option set, you don’t need ratio
to setSelect
transmit the height in the object . ratio
takes a number greater than zero, and fixes the sides with a ratio of lengths equal to this number. For example, you can pass 1 for the square or 16/9 for the aspect ratio of 16 to 9.Browser Troubles
The resulting tool works in all major browsers - Chrome, Firefox> 4, Safari, Opera> 11, IE 9. There are plans to write a fallback in flash for IE8. It was originally planned to use Google's excanvas , but it turned out that it does not provide such a method necessary for our task as
toDataURL();
there is a way out with a flash implementation , but hands have not reached it yet. Kropalka is still damp, for example, the installation of the minimum and maximum sizes has not yet been implemented, but it lies on the github , works, and is slowly developing.