image_cropper 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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