image_cropper 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,199 @@
1
+
2
+ .image-cropper-container{
3
+ display: block;
4
+ width: 100%;
5
+ }
6
+
7
+
8
+ .image-cropper-container .image-cropper-crop-container{
9
+ position: relative;
10
+ }
11
+
12
+
13
+
14
+
15
+
16
+
17
+ .image-cropper-container .image-cropper-crop-container .image-cropper-crop-controls{
18
+ position: absolute;
19
+ right: 2%;
20
+ top: 2%;
21
+ bottom: 2%;
22
+ background-color: #0006;
23
+ padding: 10px;
24
+ border-radius: 8px;
25
+ -webkit-transition: background-color 0.5s ease;
26
+ -moz-transition: background-color 0.5s ease;
27
+ transition: background-color 0.5s ease;
28
+ z-index: 1;
29
+ display: flex;
30
+ flex-direction: column;
31
+ justify-content: space-around;
32
+ }
33
+
34
+
35
+
36
+ .image-cropper-container .image-cropper-crop-container .image-cropper-crop-controls .image-cropper-crop-control,
37
+ .image-cropper-container .image-cropper-crop-container .image-cropper-crop-controls .image-cropper-crop-control:hover,
38
+ .image-cropper-container .image-cropper-crop-container .image-cropper-crop-controls .image-cropper-crop-control:active,
39
+ .image-cropper-container .image-cropper-crop-container .image-cropper-crop-controls .image-cropper-crop-control:focus{
40
+ color: #FFF;
41
+ font-size: 32px;
42
+ width: 100%;
43
+ text-align: center;
44
+ text-decoration: none;
45
+ display: flex;
46
+ align-items: center;
47
+ justify-content: center;
48
+ opacity: 1;
49
+ outline: 0;
50
+ background-color: transparent;
51
+ }
52
+
53
+
54
+ .image-cropper-container .image-cropper-crop-container .image-cropper-crop-controls .image-cropper-crop-control:first-child{
55
+ margin-top: 0;
56
+ }
57
+
58
+ .image-cropper-container .image-cropper-crop-container .image-cropper-crop-controls .image-cropper-crop-control:hover i.fa{
59
+ color: #9F9;
60
+ -webkit-animation-iteration-count: 1;
61
+ animation-iteration-count: 1;
62
+ -webkit-animation-duration: 1s;
63
+ animation-duration: 1s;
64
+ -webkit-animation-fill-mode: forwards;
65
+ animation-fill-mode: forwards;
66
+ -webkit-animation-name: pulse;
67
+ animation-name: pulse;
68
+ }
69
+
70
+ .image-cropper-container .image-cropper-crop-container img.image-cropper-crop{
71
+ max-width: 100%;
72
+ }
73
+
74
+
75
+
76
+ .image-cropper-container .image-cropper-file{
77
+ position: absolute;
78
+ width: 0;
79
+ height: 0;
80
+ opacity: 0;
81
+ margin-left: -500px;
82
+ }
83
+
84
+
85
+ .image-cropper-container.circle .image-cropper-img,
86
+ .image-cropper-container.circle .image-cropper-img-controls,
87
+ .image-cropper-container.circle .image-cropper-img-background,
88
+ .image-cropper-container.circle .guillotine-window{
89
+ border-radius: 50%;
90
+ }
91
+
92
+
93
+
94
+ .image-cropper-crop-container.disable .guillotine-window {
95
+ cursor: not-allowed;
96
+ cursor: -webkit-not-allowed;
97
+ cursor: -moz-not-allowed;
98
+ }
99
+
100
+ .image-cropper-container .image-cropper-crop-container.disable .image-cropper-crop-controls .image-cropper-crop-control.image-cropper-zoom-in,
101
+ .image-cropper-container .image-cropper-crop-container.disable .image-cropper-crop-controls .image-cropper-crop-control.image-cropper-zoom-out{
102
+ display: none;
103
+ }
104
+
105
+
106
+
107
+
108
+
109
+
110
+ @-webkit-keyframes pulse {
111
+ from {
112
+ -webkit-transform: scale3d(1, 1, 1);
113
+ transform: scale3d(1, 1, 1);
114
+ }
115
+
116
+ to {
117
+ -webkit-transform: scale3d(1.3, 1.3, 1.3);
118
+ transform: scale3d(1.3, 1.3, 1.3);
119
+ }
120
+ }
121
+
122
+ @keyframes pulse {
123
+ from {
124
+ -webkit-transform: scale3d(1, 1, 1);
125
+ transform: scale3d(1, 1, 1);
126
+ }
127
+
128
+ to {
129
+ -webkit-transform: scale3d(1.3, 1.3, 1.3);
130
+ transform: scale3d(1.3, 1.3, 1.3);
131
+ }
132
+ }
133
+
134
+
135
+
136
+ img.image-cropper{
137
+ max-width: 100%;
138
+ background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');
139
+ }
140
+
141
+
142
+
143
+
144
+
145
+
146
+
147
+ /* --------------- GUILLOTINE STYLE -----------------*/
148
+
149
+
150
+ body.guillotine-dragging, body.guillotine-dragging * {
151
+ cursor: move !important;
152
+ cursor: -webkit-grabbing !important;
153
+ cursor: -moz-grabbing !important;
154
+ cursor: grabbing !important;
155
+ cursor: grabbing, move; /* IE hack */
156
+ }
157
+
158
+ .guillotine-window {
159
+ display: block;
160
+ position: relative;
161
+ overflow: hidden;
162
+ cursor: move;
163
+ cursor: -webkit-grab;
164
+ cursor: -moz-grab;
165
+ cursor: grab;
166
+ cursor: grab, move; /* IE hack */
167
+ background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');
168
+ }
169
+
170
+ .guillotine-canvas {
171
+ position: absolute;
172
+ top: 0;
173
+ left: 0;
174
+ text-align: center;
175
+ margin: 0 !important;
176
+ padding: 0 !important;
177
+ border: none !important;
178
+ }
179
+
180
+ .guillotine-canvas > * {
181
+ position: absolute;
182
+ top: 0;
183
+ left: 0;
184
+ max-width: none;
185
+ max-height: none;
186
+ width: 100%;
187
+ height: 100%;
188
+ margin: 0 !important;
189
+ padding: 0 !important;
190
+ border: none !important;
191
+ }
192
+
193
+ .guillotine-sample {
194
+ position: absolute !important;
195
+ top: -100000px !important;
196
+ left: -100000px !important;
197
+ width: auto !important;
198
+ height: auto !important;
199
+ }
@@ -0,0 +1,14 @@
1
+ require 'rails/generators'
2
+
3
+ module ImageCropper
4
+ class InstallGenerator < ::Rails::Generators::Base
5
+ source_root File.expand_path("../templates", __FILE__)
6
+
7
+
8
+ def install
9
+ copy_file 'images/default.png', 'app/assets/images/image_cropper/default.png'
10
+ end
11
+ end
12
+ end
13
+
14
+
@@ -0,0 +1,27 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+
4
+ module ImageCropper
5
+ class MigrateGenerator < ::Rails::Generators::Base
6
+ include ::Rails::Generators::Migration
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ desc "add coords to model"
10
+
11
+ def self.next_migration_number(path)
12
+ unless @prev_migration_nr
13
+ @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
14
+ else
15
+ @prev_migration_nr += 1
16
+ end
17
+ @prev_migration_nr.to_s
18
+ end
19
+
20
+ def copy_migrations()
21
+ if self.args.count == 1
22
+ @tableize_name = self.args.first.tableize
23
+ migration_template "migration/migrate.rb", "db/migrate/image_cropper_add_fields_to_#{@tableize_name}.rb"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,11 @@
1
+ class ImageCropperAddFieldsTo<%= @tableize_name.camelize %> < ActiveRecord::Migration[5.1]
2
+ def change
3
+ #Used to crop file
4
+ add_column :<%= @tableize_name %>, :coord_x, :float, default: 0
5
+ add_column :<%= @tableize_name %>, :coord_y, :float, default: 0
6
+ add_column :<%= @tableize_name %>, :coord_w, :float, default: 0
7
+ add_column :<%= @tableize_name %>, :coord_h, :float, default: 0
8
+ add_column :<%= @tableize_name %>, :coord_z, :float, default: 1
9
+ add_column :<%= @tableize_name %>, :frame, :string, default: 'square'
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+
2
+ # requires all dependencies
3
+ Gem.loaded_specs['image_cropper'].dependencies.each do |d|
4
+ require d.name
5
+ end
6
+
7
+ require 'image_cropper/rails' if defined?(Rails)
8
+ require 'image_cropper/uploader.rb'
9
+ require 'image_cropper/model.rb'
10
+
11
+ module ImageCropper
12
+ end
13
+
@@ -0,0 +1,28 @@
1
+ module ImageCropper::Model
2
+
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+
7
+
8
+ after_update :crop_file
9
+
10
+ #If method not exist, default mount column is 'file'
11
+ unless self.methods(false).include?(:mount_uploader_columns)
12
+ def self.mount_uploader_columns
13
+ [:file]
14
+ end
15
+ end
16
+
17
+ def crop_file
18
+ self.class.mount_uploader_columns.each do |c|
19
+ #OLD VERSION of match:
20
+ #self.send("#{c}_was") == self.send(c)
21
+ self.send(c).recreate_versions! if self.send(c).present? && self.send("#{c}_before_last_save") == self.send(c).file.filename
22
+ end
23
+ end
24
+
25
+ end
26
+ end
27
+
28
+
@@ -0,0 +1,8 @@
1
+ require 'rails'
2
+ require 'rails/engine'
3
+ require 'image_cropper/rails/engine'
4
+
5
+ module ImageCropper
6
+ module Rails
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ module ImageCropper
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ initializer 'image_cropper.form_helpers' do |_app|
5
+ ActiveSupport.on_load(:action_view) { require 'image_cropper/rails/form_helper' }
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,89 @@
1
+ module ImageCropper
2
+ module Rails
3
+ module FormBuilder
4
+ include ActionView::Helpers::TagHelper
5
+ include ActionView::Helpers::FormTagHelper
6
+ include ActionView::Helpers::JavaScriptHelper
7
+ include ActionView::Context
8
+
9
+ def image_cropper_field(method, options = {})
10
+ aspect_ratio = options[:aspect_ratio] || '4:3'
11
+ frame = options[:frame] || 'square'
12
+ operation_object = options[:parent_object] || self
13
+ destroyable = options[:destroyable] || false
14
+ destroy_class = options[:destroy_class] || '.image-cropper-container'
15
+ destroy_confirm = options[:destroy_confirm] || 'Are you sure?'
16
+ image_cropper_id = operation_object.index || 'only'
17
+
18
+
19
+ content_tag(:div, id: "image-cropper-#{operation_object.object_id}-#{image_cropper_id}", class: "image-cropper-container #{frame}", data: { 'aspect-ratio' => aspect_ratio}) do
20
+
21
+ concat(
22
+ content_tag(:div, class: "image-cropper-crop-container") do
23
+ concat(
24
+ content_tag(:div, class: "image-cropper-crop-controls") do
25
+ concat(
26
+ link_to('javascript:;', class: "image-cropper-crop-control image-cropper-file-trigger") do
27
+ content_tag(:i, '', class: "fa fa-image")
28
+ end
29
+ )
30
+ concat(
31
+ link_to('javascript:;', class: "image-cropper-crop-control image-cropper-zoom-in") do
32
+ content_tag(:i, '', class: "fa fa-search-plus")
33
+ end
34
+ )
35
+ concat(
36
+ link_to('javascript:;', class: "image-cropper-crop-control image-cropper-zoom-out") do
37
+ content_tag(:i, '', class: "fa fa-search-minus")
38
+ end
39
+ )
40
+ if destroyable == true
41
+ concat(@template.hidden_field(operation_object.object_name, :_destroy, value: operation_object.object._destroy))
42
+ concat(
43
+ link_to('javascript:;', class: "image-cropper-crop-control image-cropper-remove", data: {destroy_confirm: destroy_confirm}) do
44
+ content_tag(:i, '', class: "fa fa-trash")
45
+ end
46
+ )
47
+ end
48
+ end
49
+ )
50
+ concat(
51
+ @template.image_tag(@object.send(method.to_sym).url, class: 'image-cropper-crop')
52
+ )
53
+ end
54
+ )
55
+ concat(@template.hidden_field(@object_name, :coord_x, class: 'coord-x', value: @object.coord_x))
56
+ concat(@template.hidden_field(@object_name, :coord_y, class: 'coord-y', value: @object.coord_y))
57
+ concat(@template.hidden_field(@object_name, :coord_w, class: 'coord-w', value: @object.coord_w))
58
+ concat(@template.hidden_field(@object_name, :coord_h, class: 'coord-h', value: @object.coord_h))
59
+ concat(@template.hidden_field(@object_name, :coord_z, class: 'coord-z', value: @object.coord_z))
60
+ concat(@template.hidden_field(@object_name, :frame, value: frame))
61
+
62
+ concat(@template.file_field(@object_name, method.to_sym, class: 'image-cropper-file', autoComplete: 'off'))
63
+ if @object.send("#{method}_cache".to_sym).present?
64
+ concat(@template.hidden_field(@object_name, "#{method}_cache".to_sym, class: 'image-cropper-file-cache', value: @object.send("#{method}_cache".to_sym)))
65
+ end
66
+ concat(@template.hidden_field(@object_name, "remote_#{method}_url".to_sym, class: 'image-cropper-file-url', value: @object.send("remote_#{method}_url".to_sym)))
67
+
68
+
69
+ concat(content_tag(:div, '', style: "clear:both;"))
70
+
71
+ concat(
72
+ if @object.send("#{method}".to_sym).file.present?
73
+ javascript_tag("$('\#image-cropper-#{operation_object.object_id}-#{image_cropper_id}').image_cropper({destroy_class: '#{destroy_class}'});")
74
+ else
75
+ javascript_tag("$('\#image-cropper-#{operation_object.object_id}-#{image_cropper_id}').image_cropper({enabled: false, destroy_class: '#{destroy_class}'});")
76
+ end
77
+ )
78
+
79
+ end
80
+
81
+ end
82
+
83
+
84
+
85
+ end
86
+ end
87
+ end
88
+
89
+ ImageCropper::FormBuilder = ImageCropper::Rails::FormBuilder
@@ -0,0 +1,16 @@
1
+ require 'action_view/helpers'
2
+ require 'image_cropper/rails/form_builder'
3
+
4
+ module ImageCropper
5
+ module Rails
6
+ module FormHelper
7
+ def self.included(_base)
8
+ ActionView::Helpers::FormBuilder.instance_eval do
9
+ include FormBuilder
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ ActionView::Base.send :include, ImageCropper::Rails::FormHelper
@@ -0,0 +1,89 @@
1
+ module ImageCropper::Uploader
2
+
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+
7
+ include CarrierWave::MiniMagick
8
+
9
+ def default_url(*args)
10
+ ActionController::Base.helpers.asset_path("image_cropper/default.png")
11
+ end
12
+
13
+
14
+ version :thumb do
15
+ process :crop
16
+ end
17
+
18
+
19
+ def crop
20
+
21
+ x = model.coord_x
22
+ y = model.coord_y
23
+ w = model.coord_w
24
+ h = model.coord_h
25
+ z = model.coord_z
26
+ w_z = self.width*z
27
+ h_z = self.height*z
28
+
29
+ manipulate! do |img|
30
+
31
+ #img.resize "#{w_z}x#{h_z}"
32
+ #img.coalesce
33
+ #img.repage "0x0"
34
+ #img.crop "#{w}x#{h}+#{x}+#{y}"
35
+ #img << "+repage"
36
+
37
+ img.combine_options do |c|
38
+ c.resize "#{w_z}x#{h_z}"
39
+ c.coalesce
40
+ c.repage("0x0")
41
+ c.crop "#{w}x#{h}+#{x}+#{y}"
42
+ c.args << '+repage'
43
+ end
44
+
45
+ if model.frame == 'circle'
46
+
47
+ mask = ::MiniMagick::Image.open img.path
48
+
49
+ mask.combine_options do |m|
50
+ m.alpha 'transparent'
51
+ m.background 'none'
52
+ m.fill 'white'
53
+ m.strokewidth 0
54
+ m.draw "ellipse #{w/2},#{h/2} #{w/2},#{h/2}, 0, 360"
55
+ end
56
+
57
+ overlay = ::MiniMagick::Image.open img.path
58
+
59
+ overlay.combine_options do |o|
60
+ o.alpha 'transparent'
61
+ o.background 'none'
62
+ o.fill 'none'
63
+ o.strokewidth 0
64
+ o.draw "ellipse #{w/2},#{h/2} #{w/2},#{h/2}, 0, 360"
65
+ end
66
+
67
+ masked = img.composite(mask) do |i|
68
+ i.alpha "set"
69
+ i.compose 'DstIn'
70
+ end
71
+
72
+ masked.composite(overlay) do |i|
73
+ i.compose 'Over'
74
+ end
75
+
76
+ else
77
+
78
+ img
79
+
80
+ end
81
+
82
+
83
+ end
84
+
85
+
86
+ end
87
+
88
+ end
89
+ end