jcropper 0.1.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +19 -3
- data/VERSION +1 -1
- data/generators/jcropper/USAGE +3 -3
- data/generators/jcropper/jcropper_generator.rb +3 -2
- data/generators/jcropper/templates/jcropper_migration.rb.erb +8 -8
- data/lib/jcropper.rb +3 -1
- data/lib/jcropper/cropped_image.rb +33 -0
- data/lib/jcropper/helpers.rb +64 -114
- data/lib/jcropper/jcropper.rb +28 -19
- data/lib/paperclip_processors/jcropper.rb +1 -1
- data/public/javascripts/jcropper.js +104 -0
- data/public/stylesheets/jquery.Jcrop.css +1 -1
- data/rails/init.rb +15 -1
- data/tasks/{js_cropper.rake → jcropper.rake} +1 -0
- metadata +12 -5
data/README.rdoc
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
= Overview
|
2
2
|
|
3
|
-
jcropper wraps jcrop 0.98, http://deepliquid.com/content/Jcrop.html,
|
3
|
+
jcropper wraps jcrop 0.98, http://deepliquid.com/content/Jcrop.html, an in-browser cropping tool, to allow users to crop attached images. It currently only works with paperclip.
|
4
4
|
|
5
|
-
|
5
|
+
(note, there is also another jcrop plugin, http://github.com/jschwindt/rjcrop)
|
6
6
|
|
7
7
|
= Installation
|
8
8
|
|
9
|
+
Install as a plugin (gem to come soon)
|
10
|
+
|
11
|
+
script/plugin install git://github.com/syfo/jcropper.git
|
12
|
+
|
9
13
|
Include the jcropper processor in the paperclip style.
|
10
14
|
|
11
15
|
class User < ActiveRecord::Base
|
@@ -24,12 +28,24 @@ Generate and install your migration
|
|
24
28
|
|
25
29
|
Install js/css/images for jcropper
|
26
30
|
|
27
|
-
rake
|
31
|
+
rake jcropper:install
|
32
|
+
|
33
|
+
Add the headers to your view or layout (jquery required)
|
34
|
+
<%= javascript_include_tag 'jquery.Jcrop.min.js' %>
|
35
|
+
<%= javascript_include_tag 'jcropper.js' %>
|
36
|
+
<%= stylesheet_link_tag 'jquery.Jcrop.css' %>
|
28
37
|
|
29
38
|
Add the helpers to your view:
|
30
39
|
|
31
40
|
<%= croppable_image @user, :avatar, :thumb -%>
|
32
41
|
<%= croppable_image_preview @user, :avatar, :thumb -%>
|
33
42
|
|
43
|
+
Helper Options:
|
44
|
+
:css_prefix => 'jcrop'
|
45
|
+
:width => 100, :height => 100
|
46
|
+
:js_object => 'MyGlobalJsObject',
|
47
|
+
:aspect_ratio => 2
|
48
|
+
:aspect_ratio => false
|
49
|
+
|
34
50
|
|
35
51
|
Copyright (c) 2010 Symbolforce, LLC., released under the MIT license
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/generators/jcropper/USAGE
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Description:
|
2
|
-
Generates a migration for jcropper one
|
2
|
+
Generates a migration for jcropper corresponding to one attachment and one style. Creates fields on the model to save the crop rectangle.
|
3
3
|
|
4
|
-
|
5
|
-
./script/generate jcropper
|
4
|
+
Usage:
|
5
|
+
./script/generate jcropper <model> <attachment> <style>
|
6
6
|
|
@@ -1,8 +1,9 @@
|
|
1
1
|
class JcropperGenerator < Rails::Generator::NamedBase
|
2
|
-
attr_accessor :attachment, :migration_name
|
2
|
+
attr_accessor :attachment, :migration_name, :style
|
3
3
|
|
4
4
|
def initialize(args, options = {})
|
5
5
|
super
|
6
|
+
raise "Incorrect usage!" unless args.length == 3
|
6
7
|
@class_name, @attachment, @style = args[0], args[1], args[2]
|
7
8
|
end
|
8
9
|
|
@@ -17,6 +18,6 @@ class JcropperGenerator < Rails::Generator::NamedBase
|
|
17
18
|
private
|
18
19
|
|
19
20
|
def generate_file_name
|
20
|
-
"add_crop_variables_for_#{@attachment}
|
21
|
+
"add_crop_variables_for_#{@attachment}_#{@style}_to_#{@class_name.underscore}"
|
21
22
|
end
|
22
23
|
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
class <%= migration_name %> < ActiveRecord::Migration
|
2
2
|
def self.up
|
3
|
-
add_column :<%= class_name.underscore.camelize.tableize %>, :<%= attachment
|
4
|
-
add_column :<%= class_name.underscore.camelize.tableize %>, :<%= attachment
|
5
|
-
add_column :<%= class_name.underscore.camelize.tableize %>, :<%= attachment
|
6
|
-
add_column :<%= class_name.underscore.camelize.tableize %>, :<%= attachment
|
3
|
+
add_column :<%= class_name.underscore.camelize.tableize %>, :<%= JCropper.jattr attachment, style, :x %>, :integer, :default => 0
|
4
|
+
add_column :<%= class_name.underscore.camelize.tableize %>, :<%= JCropper.jattr attachment, style, :y %>, :integer, :default => 0
|
5
|
+
add_column :<%= class_name.underscore.camelize.tableize %>, :<%= JCropper.jattr attachment, style, :w %>, :integer, :default => 0
|
6
|
+
add_column :<%= class_name.underscore.camelize.tableize %>, :<%= JCropper.jattr attachment, style, :h %>, :integer, :default => 0
|
7
7
|
end
|
8
8
|
|
9
9
|
def self.down
|
10
|
-
remove_column :<%= class_name.underscore.camelize.tableize %>, :<%= attachment
|
11
|
-
remove_column :<%= class_name.underscore.camelize.tableize %>, :<%= attachment
|
12
|
-
remove_column :<%= class_name.underscore.camelize.tableize %>, :<%= attachment
|
13
|
-
remove_column :<%= class_name.underscore.camelize.tableize %>, :<%= attachment
|
10
|
+
remove_column :<%= class_name.underscore.camelize.tableize %>, :<%= JCropper.jattr attachment, style, :x %>
|
11
|
+
remove_column :<%= class_name.underscore.camelize.tableize %>, :<%= JCropper.jattr attachment, style, :y %>
|
12
|
+
remove_column :<%= class_name.underscore.camelize.tableize %>, :<%= JCropper.jattr attachment, style, :w %>
|
13
|
+
remove_column :<%= class_name.underscore.camelize.tableize %>, :<%= JCropper.jattr attachment, style, :h %>
|
14
14
|
end
|
15
15
|
end
|
data/lib/jcropper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
1
|
ROOT = File.join(File.dirname(__FILE__), 'jcropper')
|
2
2
|
require File.join(ROOT, 'jcropper')
|
3
|
-
require File.join(ROOT, 'helpers')
|
3
|
+
require File.join(ROOT, 'helpers')
|
4
|
+
require File.join(ROOT, 'cropped_image')
|
5
|
+
Paperclip.autoload 'Jcropper', File.join(ROOT, '../paperclip_processors/jcropper.rb')
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module JCropper
|
2
|
+
class CroppedImage
|
3
|
+
attr_reader :original_geometry, :cropped_geometry, :attachment_name, :style_name, :coord_names, :starting_crop, :attachment
|
4
|
+
|
5
|
+
def initialize(object)
|
6
|
+
@object = object
|
7
|
+
@attachment_name = object.class.jcropper_defs[:attachment]
|
8
|
+
@style_name = object.jcropper_defs[:style]
|
9
|
+
@attachment = object.send(attachment_name)
|
10
|
+
@coord_names = {}
|
11
|
+
%w(x y w h).each{|v| @coord_names[v.to_sym] = JCropper.jattr(attachment_name, style_name, v)}
|
12
|
+
|
13
|
+
@starting_crop = @coord_names.inject({}) {|h,pair| h.merge({ pair[0] => object.send("#{pair[1].to_s}_was") }) }
|
14
|
+
end
|
15
|
+
|
16
|
+
###CRZ these two might get out of date...
|
17
|
+
def original_geometry
|
18
|
+
if attachment.to_file(:original) and File.exists? attachment.to_file(:original)
|
19
|
+
@original_geometry ||= Paperclip::Geometry.from_file(attachment.to_file(:original))
|
20
|
+
else
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def target_geometry
|
26
|
+
@target_geometry ||= Paperclip::Geometry.parse(@object.send(attachment_name).styles[style_name.to_sym][:geometry])
|
27
|
+
end
|
28
|
+
|
29
|
+
def max_crop
|
30
|
+
[0, 0, original_geometry.width, original_geometry.height]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/jcropper/helpers.rb
CHANGED
@@ -1,133 +1,83 @@
|
|
1
|
-
module JCropper
|
1
|
+
module JCropper
|
2
2
|
module Helpers
|
3
3
|
def croppable_image(object_name, attachment, style, options = {})
|
4
4
|
object = eval("@#{object_name.to_s}") unless object_name.is_a? ActiveRecord::Base
|
5
|
-
|
6
|
-
options = options
|
5
|
+
options[:view_size] = {:width => options.delete(:width), :height => options.delete(:height)}
|
6
|
+
return unless options = parse_options(object, options)
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
file_geometry = Paperclip::Geometry.from_file(object.send(attachment).path(:original))
|
12
|
-
options[:view_size] ||= {:width => file_geometry.width, :height => file_geometry.height}
|
13
|
-
|
14
|
-
resized_ratio = options[:view_size][:width] / file_geometry.width
|
15
|
-
|
16
|
-
s = "<div class='#{options[:css_prefix]}'>#{image_tag(object.send(attachment).url, options[:view_size])}</div>" + "\n"
|
17
|
-
s += hidden_field_tag("#{object_name}[#{x}]", object.send(x), :id => x) + "\n"
|
18
|
-
s += hidden_field_tag("#{object_name}[#{y}]", object.send(y), :id => y) + "\n"
|
19
|
-
s += hidden_field_tag("#{object_name}[#{w}]", object.send(w), :id => w) + "\n"
|
20
|
-
s += hidden_field_tag("#{object_name}[#{h}]", object.send(h), :id => h) + "\n"
|
21
|
-
s += <<-CSS
|
22
|
-
<style type="text/css">
|
23
|
-
/* Fixes issue here http://code.google.com/p/jcrop/issues/detail?id=1 */
|
24
|
-
.jcrop-holder { text-align: left; }
|
25
|
-
|
26
|
-
.jcrop-vline, .jcrop-hline
|
27
|
-
{
|
28
|
-
font-size: 0;
|
29
|
-
position: absolute;
|
30
|
-
background: white url('Jcrop.gif') top left repeat;
|
31
|
-
}
|
32
|
-
.jcrop-vline { height: 100%; width: 1px !important; }
|
33
|
-
.jcrop-hline { width: 100%; height: 1px !important; }
|
34
|
-
.jcrop-handle {
|
35
|
-
font-size: 1px;
|
36
|
-
width: 7px !important;
|
37
|
-
height: 7px !important;
|
38
|
-
border: 1px #eee solid;
|
39
|
-
background-color: #333;
|
40
|
-
*width: 9px;
|
41
|
-
*height: 9px;
|
42
|
-
}
|
43
|
-
|
44
|
-
.jcrop-tracker { width: 100%; height: 100%; }
|
45
|
-
|
46
|
-
.custom .jcrop-vline,
|
47
|
-
.custom .jcrop-hline
|
48
|
-
{
|
49
|
-
background: yellow;
|
50
|
-
}
|
51
|
-
.custom .jcrop-handle
|
52
|
-
{
|
53
|
-
border-color: black;
|
54
|
-
background-color: #C7BB00;
|
55
|
-
-moz-border-radius: 3px;
|
56
|
-
-webkit-border-radius: 3px;
|
57
|
-
}
|
58
|
-
</style>
|
59
|
-
CSS
|
60
|
-
|
61
|
-
s += <<-HTML
|
62
|
-
<script type='text/javascript'>
|
63
|
-
function findBoundingScale(img, container) {
|
64
|
-
imgAspect = img[0] / img[1]
|
65
|
-
containerAspect = container[0] / container[1]
|
66
|
-
|
67
|
-
if(imgAspect < containerAspect) {
|
68
|
-
return (container[0] / img[0]);
|
69
|
-
}
|
70
|
-
else {
|
71
|
-
return (container[1] / img[1]);
|
72
|
-
}
|
73
|
-
}
|
74
|
-
|
75
|
-
$('.#{options[:css_prefix]} img').load(function() {
|
76
|
-
var trueWidth = #{file_geometry.width};
|
77
|
-
var trueHeight = #{file_geometry.height};
|
78
|
-
|
79
|
-
var targetWidth = #{target_geometry.width};
|
80
|
-
var targetHeight = #{target_geometry.height};
|
81
|
-
|
82
|
-
function cropOnChange(coords) {
|
83
|
-
var rx = $('##{options[:css_prefix]}-preview').parent().width() / coords.w;
|
84
|
-
var ry = $('##{options[:css_prefix]}-preview').parent().height() / coords.h;
|
85
|
-
|
86
|
-
$('##{options[:css_prefix]}-preview').css({
|
87
|
-
width: Math.round(rx * trueWidth) + 'px',
|
88
|
-
height: Math.round(ry * trueHeight) + 'px',
|
89
|
-
marginLeft: '-' + Math.round(rx * coords.x) + 'px',
|
90
|
-
marginTop: '-' + Math.round(ry * coords.y) + 'px'
|
91
|
-
});
|
92
|
-
|
93
|
-
$('##{x}').val(coords.x);
|
94
|
-
$('##{y}').val(coords.y);
|
95
|
-
$('##{w}').val(coords.w);
|
96
|
-
$('##{h}').val(coords.h);
|
97
|
-
console.log(coords);
|
98
|
-
}
|
8
|
+
###CRZ - duplicated in JS!
|
9
|
+
view_scale = find_bounding_scale([options[:view_size][:width], options[:view_size][:height]],
|
10
|
+
[options[:original_geometry][:width], options[:original_geometry][:height]])
|
99
11
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
12
|
+
scaled_img_dims = {:width => options[:original_geometry][:width]*view_scale, :height => options[:original_geometry][:height]*view_scale}
|
13
|
+
s = "<div class='#{options[:css_prefix]}'>#{image_tag(object.send(attachment).url, scaled_img_dims.merge(:id => options[:id]))}</div>" + "\n"
|
14
|
+
s += hidden_field_tag("#{object_name}[#{@js_cropper_c_i.coord_names[:x]}]", @js_cropper_c_i.starting_crop[:x], :id => @js_cropper_c_i.coord_names[:x]) + "\n"
|
15
|
+
s += hidden_field_tag("#{object_name}[#{@js_cropper_c_i.coord_names[:y]}]", @js_cropper_c_i.starting_crop[:y], :id => @js_cropper_c_i.coord_names[:y]) + "\n"
|
16
|
+
s += hidden_field_tag("#{object_name}[#{@js_cropper_c_i.coord_names[:w]}]", @js_cropper_c_i.starting_crop[:w], :id => @js_cropper_c_i.coord_names[:w]) + "\n"
|
17
|
+
s += hidden_field_tag("#{object_name}[#{@js_cropper_c_i.coord_names[:h]}]", @js_cropper_c_i.starting_crop[:h], :id => @js_cropper_c_i.coord_names[:h]) + "\n"
|
18
|
+
s += <<-JS
|
19
|
+
<script type="text/javascript">
|
20
|
+
#{options[:js_object]} = new CroppedImage(jQuery('.#{options[:css_prefix]} img'),
|
21
|
+
$.extend(
|
22
|
+
#{camelize_keys(options).to_json},
|
23
|
+
{
|
24
|
+
originalGeometry: #{{:width => @js_cropper_c_i.original_geometry.width, :height => @js_cropper_c_i.original_geometry.height}.to_json},
|
25
|
+
targetGeometry: #{{:width => @js_cropper_c_i.target_geometry.width, :height => @js_cropper_c_i.target_geometry.height}.to_json},
|
26
|
+
coordNames: #{@js_cropper_c_i.coord_names.to_json}
|
27
|
+
})
|
28
|
+
);
|
110
29
|
</script>
|
111
|
-
|
30
|
+
JS
|
31
|
+
s
|
112
32
|
end
|
113
33
|
|
114
34
|
def croppable_image_preview(object_name, attachment, style, options = {})
|
115
35
|
object = eval("@#{object_name.to_s}") unless object_name.is_a? ActiveRecord::Base
|
116
|
-
options = options.
|
36
|
+
options[:preview_size] = {:width => options.delete(:width), :height => options.delete(:height)}
|
37
|
+
return unless options = parse_options(object, options)
|
117
38
|
|
118
|
-
<<-HTML
|
119
|
-
<div style="overflow:hidden;height:
|
120
|
-
#{image_tag(
|
39
|
+
s = <<-HTML
|
40
|
+
<div style="overflow:hidden;height:#{options[:preview_size][:height]}px;width:#{options[:preview_size][:width]}px;" class="#{options[:css_prefix]}-preview-mask">
|
41
|
+
#{image_tag(@js_cropper_c_i.attachment.url(:original), :class => "#{options[:css_prefix]}-preview")}
|
121
42
|
</div>
|
122
43
|
HTML
|
44
|
+
s
|
123
45
|
end
|
124
46
|
|
125
47
|
private
|
126
|
-
def
|
127
|
-
{
|
128
|
-
:
|
129
|
-
|
130
|
-
|
48
|
+
def camelize_keys(hash)
|
49
|
+
hash.inject({}) do |h, pair|
|
50
|
+
h.merge(pair[0].to_s.camelize(:lower) => pair[1])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def find_bounding_scale(container, to_contain)
|
55
|
+
to_contain_aspect = to_contain[0].to_f / to_contain[1]
|
56
|
+
container_aspect = container[0].to_f / container[1]
|
57
|
+
|
58
|
+
if to_contain_aspect > container_aspect
|
59
|
+
return (container[0].to_f / to_contain[0]);
|
60
|
+
else
|
61
|
+
return (container[1].to_f / to_contain[1]);
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def parse_options(object, options = {})
|
67
|
+
@js_cropper_c_i ||= object.cropped_image
|
68
|
+
|
69
|
+
return false unless @js_cropper_c_i.target_geometry and @js_cropper_c_i.original_geometry
|
70
|
+
|
71
|
+
@js_cropper_options ||= {}
|
72
|
+
@js_cropper_options = {
|
73
|
+
:css_prefix => 'jcrop',
|
74
|
+
:view_size => {:width => @js_cropper_c_i.target_geometry.width, :height => @js_cropper_c_i.target_geometry.height},
|
75
|
+
:preview_size => {:width => @js_cropper_c_i.target_geometry.width, :height => @js_cropper_c_i.target_geometry.height},
|
76
|
+
:aspect_ratio => @js_cropper_c_i.target_geometry.width / @js_cropper_c_i.target_geometry.height,
|
77
|
+
:original_geometry => {:width => @js_cropper_c_i.original_geometry.width, :height => @js_cropper_c_i.original_geometry.height},
|
78
|
+
:starting_crop => @js_cropper_c_i.starting_crop,
|
79
|
+
:js_object => 'croppedImage'
|
80
|
+
}.merge(@js_cropper_options.merge(options))
|
131
81
|
end
|
132
82
|
end
|
133
83
|
end
|
data/lib/jcropper/jcropper.rb
CHANGED
@@ -1,46 +1,55 @@
|
|
1
1
|
module JCropper
|
2
2
|
module ClassMethods
|
3
|
-
def jcrop(attachment, style
|
3
|
+
def jcrop(attachment, style)
|
4
4
|
raise "jcropper requires attachment to be of type Paperclip::Attachment" if self.attachment_definitions[attachment.to_sym].nil?
|
5
|
-
require File.join(ROOT, '../paperclip_processors/jcropper.rb')
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
class_exec(attachment, style) do |attachment, style|
|
7
|
+
attr_reader :cropped_image
|
8
|
+
write_inheritable_hash :jcropper_defs, {:attachment => attachment, :style => style}
|
9
|
+
class_inheritable_reader :jcropper_defs
|
11
10
|
|
12
|
-
class_exec(options) do |options|
|
13
|
-
write_inheritable_attribute :jcropper_options, options.dup
|
14
|
-
class_inheritable_reader :jcropper_options
|
15
|
-
|
16
11
|
attr_accessor :jcropper_should_reprocess
|
17
|
-
before_save :jcropper_check_for_reprocess
|
12
|
+
before_save :jcropper_normalize_crop, :jcropper_check_for_reprocess
|
18
13
|
after_save :jcropper_reprocess
|
19
14
|
|
15
|
+
###CRZ - alias chain this
|
16
|
+
def after_initialize
|
17
|
+
@cropped_image = CroppedImage.new(self)
|
18
|
+
end
|
19
|
+
|
20
20
|
def jcropper_reprocess
|
21
|
-
|
21
|
+
cropped_image.attachment.reprocess! if @jcropper_should_reprocess
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
x, y, w, h = [:x, :y, :w, :h].map{|coord| JCropper.jattr(attachment, style, coord) }
|
25
26
|
to_eval = <<-TO_EVAL
|
26
27
|
def jcropper_check_for_reprocess
|
27
28
|
@jcropper_should_reprocess ||= !(changed & %w(#{x} #{y} #{w} #{h})).empty?
|
28
|
-
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def jcropper_coords
|
33
|
+
[#{x}, #{y}, #{w}, #{h}]
|
34
|
+
end
|
35
|
+
|
36
|
+
def jcropper_needs_crop?
|
37
|
+
cropped_image and cropped_image.original_geometry and (#{w} == 0 or #{h} == 0)
|
38
|
+
end
|
39
|
+
|
40
|
+
def jcropper_normalize_crop
|
41
|
+
self.#{x}, self.#{y}, self.#{w}, self.#{h} = *cropped_image.max_crop if jcropper_needs_crop?
|
42
|
+
true
|
29
43
|
end
|
30
44
|
|
31
45
|
def jcropper_crop_string
|
32
|
-
|
33
|
-
"-crop \#{#{w}}x\#{#{h}}+\#{#{x}}+\#{#{y}}"
|
34
|
-
else
|
35
|
-
""
|
36
|
-
end
|
46
|
+
"-crop \#{#{w}}x\#{#{h}}+\#{#{x}}+\#{#{y}}"
|
37
47
|
end
|
38
48
|
TO_EVAL
|
39
49
|
class_eval to_eval
|
40
50
|
end
|
41
51
|
end
|
42
52
|
|
43
|
-
private
|
44
53
|
def self.jattr(attachment, style, coord)
|
45
54
|
"#{attachment}_#{style}_crop_#{coord}"
|
46
55
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
CroppedImage = function(image, properties) {
|
2
|
+
var t = this;
|
3
|
+
t.image = image;
|
4
|
+
|
5
|
+
t.init = function(properties) {
|
6
|
+
$(window).load(function() {
|
7
|
+
t.jcrop = jQuery.Jcrop(t.image, jQuery.extend(t.defaultJcropOptions(), t.jcropOptions));
|
8
|
+
});
|
9
|
+
}
|
10
|
+
|
11
|
+
t.defaultJcropOptions = function() {
|
12
|
+
return {
|
13
|
+
onChange: t.cropOnChange,
|
14
|
+
onSelect: t.cropOnChange,
|
15
|
+
trueSize: [t.originalGeometry.width, t.originalGeometry.height],
|
16
|
+
setSelect: [
|
17
|
+
t.startingCrop.x * t.viewScale(),
|
18
|
+
t.startingCrop.y * t.viewScale(),
|
19
|
+
(t.startingCrop.x + t.startingCrop.w) * t.viewScale(),
|
20
|
+
(t.startingCrop.y + t.startingCrop.h) * t.viewScale()
|
21
|
+
]
|
22
|
+
}
|
23
|
+
},
|
24
|
+
|
25
|
+
t.viewScale = function() {
|
26
|
+
return t.findBoundingScale([t.viewSize.width, t.viewSize.height],
|
27
|
+
[t.originalGeometry.width, t.originalGeometry.height]);
|
28
|
+
}
|
29
|
+
|
30
|
+
t.log = function() {
|
31
|
+
try {
|
32
|
+
if(typeof console == 'object' && typeof console.log == 'function') {
|
33
|
+
console.log.apply(this, arguments);
|
34
|
+
}
|
35
|
+
} catch(e) {;}
|
36
|
+
}
|
37
|
+
|
38
|
+
t.cropOnChange = function(coords) {
|
39
|
+
t.updatePreview(coords);
|
40
|
+
|
41
|
+
$('#' + t.coordNames.x).val(coords.x);
|
42
|
+
$('#' + t.coordNames.y).val(coords.y);
|
43
|
+
$('#' + t.coordNames.w).val(coords.w);
|
44
|
+
$('#' + t.coordNames.h).val(coords.h);
|
45
|
+
}
|
46
|
+
|
47
|
+
t.findBoundingScale = function(container, toContain) { /* [width, height] arrays */
|
48
|
+
toContainAspect = toContain[0] / toContain[1]
|
49
|
+
containerAspect = container[0] / container[1]
|
50
|
+
|
51
|
+
if(toContainAspect > containerAspect) {
|
52
|
+
return (container[0] / toContain[0]);
|
53
|
+
}
|
54
|
+
else {
|
55
|
+
return (container[1] / toContain[1]);
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
t.addProperties = function(properties) {
|
60
|
+
jQuery.extend(t, properties);
|
61
|
+
}
|
62
|
+
|
63
|
+
t.previewMask = function() {
|
64
|
+
return jQuery('.' + t.cssPrefix + '-preview').parent();
|
65
|
+
}
|
66
|
+
|
67
|
+
t.updatePreview = function(coords) {
|
68
|
+
if(coords.x == NaN || t.previewMask().length == null ) {
|
69
|
+
return;
|
70
|
+
}
|
71
|
+
|
72
|
+
var rx = t.previewMask().width() / coords.w;
|
73
|
+
var ry = t.previewMask().height() / coords.h;
|
74
|
+
var scale = t.findBoundingScale([t.previewSize.width, t.previewSize.height],
|
75
|
+
[coords.w, coords.h])
|
76
|
+
|
77
|
+
t.previewMask().css({
|
78
|
+
width: Math.round(scale * coords.w) + 'px',
|
79
|
+
height: Math.round(scale * coords.h) + 'px',
|
80
|
+
});
|
81
|
+
|
82
|
+
$('.' + t.cssPrefix + '-preview').css({
|
83
|
+
width: Math.round(scale * t.originalGeometry.width) + 'px',
|
84
|
+
height: Math.round(scale * t.originalGeometry.height) + 'px',
|
85
|
+
marginLeft: '-' + Math.round(scale * coords.x) + 'px',
|
86
|
+
marginTop: '-' + Math.round(scale * coords.y) + 'px'
|
87
|
+
});
|
88
|
+
}
|
89
|
+
|
90
|
+
t.resetCrop = function() {
|
91
|
+
t.jcrop.setSelect([t.startingCrop.x,
|
92
|
+
t.startingCrop.y,
|
93
|
+
t.startingCrop.x + t.startingCrop.w,
|
94
|
+
t.startingCrop.y + t.startingCrop.h]);
|
95
|
+
}
|
96
|
+
|
97
|
+
t.clearCrop = function() {
|
98
|
+
t.jcrop.setSelect([0, 0, t.originalGeometry.width, t.originalGeometry.height]);
|
99
|
+
}
|
100
|
+
|
101
|
+
t.init(properties);
|
102
|
+
t.addProperties(properties); //###CRZ - there are no defaults here
|
103
|
+
};
|
104
|
+
|
@@ -5,7 +5,7 @@
|
|
5
5
|
{
|
6
6
|
font-size: 0;
|
7
7
|
position: absolute;
|
8
|
-
background: white url('Jcrop.gif') top left repeat;
|
8
|
+
background: white url('/images/Jcrop.gif') top left repeat;
|
9
9
|
}
|
10
10
|
.jcrop-vline { height: 100%; width: 1px !important; }
|
11
11
|
.jcrop-hline { width: 100%; height: 1px !important; }
|
data/rails/init.rb
CHANGED
@@ -1 +1,15 @@
|
|
1
|
-
|
1
|
+
if false
|
2
|
+
#if RAILS_ENV == 'development'
|
3
|
+
require 'active_support' unless defined? ActiveSupport
|
4
|
+
require 'active_record' unless defined? ActiveRecord
|
5
|
+
|
6
|
+
ActiveSupport::Dependencies.explicitly_unloadable_constants += [ 'JCropper', 'JCropper::ClassMethods']
|
7
|
+
ActiveSupport::Dependencies.load_once_paths.delete lib_path
|
8
|
+
ActiveSupport::Dependencies.log_activity = true
|
9
|
+
|
10
|
+
puts "lib_path::", lib_path, "\n"
|
11
|
+
puts "load_paths::", ActiveSupport::Dependencies.load_paths, "\n"
|
12
|
+
puts "load_once_paths::", ActiveSupport::Dependencies.load_once_paths, "\n"
|
13
|
+
end
|
14
|
+
|
15
|
+
require 'jcropper.rb'
|
@@ -4,6 +4,7 @@ namespace :jcropper do
|
|
4
4
|
root = File.join(File.dirname(__FILE__), '..')
|
5
5
|
FileUtils.cp(File.join(root, 'public/images/Jcrop.gif'), File.join(Rails.root, 'public/images/Jcrop.gif'))
|
6
6
|
FileUtils.cp(File.join(root, 'public/javascripts/jquery.Jcrop.min.js'), File.join(Rails.root, 'public/javascripts/jquery.Jcrop.min.js'))
|
7
|
+
FileUtils.cp(File.join(root, 'public/javascripts/jcropper.js'), File.join(Rails.root, 'public/javascripts/jcropper.js'))
|
7
8
|
FileUtils.cp(File.join(root, 'public/stylesheets/jquery.Jcrop.css'), File.join(Rails.root, 'public/stylesheets/jquery.Jcrop.css'))
|
8
9
|
end
|
9
10
|
end
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jcropper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
|
-
-
|
8
|
+
- 3
|
8
9
|
- 0
|
9
|
-
version: 0.
|
10
|
+
version: 0.3.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Ryan Ziegler
|
@@ -14,7 +15,7 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-05-
|
18
|
+
date: 2010-05-27 00:00:00 -04:00
|
18
19
|
default_executable:
|
19
20
|
dependencies: []
|
20
21
|
|
@@ -38,14 +39,16 @@ files:
|
|
38
39
|
- generators/jcropper/templates/jcropper_migration.rb.erb
|
39
40
|
- install.rb
|
40
41
|
- lib/jcropper.rb
|
42
|
+
- lib/jcropper/cropped_image.rb
|
41
43
|
- lib/jcropper/helpers.rb
|
42
44
|
- lib/jcropper/jcropper.rb
|
43
45
|
- lib/paperclip_processors/jcropper.rb
|
44
46
|
- public/images/Jcrop.gif
|
47
|
+
- public/javascripts/jcropper.js
|
45
48
|
- public/javascripts/jquery.Jcrop.min.js
|
46
49
|
- public/stylesheets/jquery.Jcrop.css
|
47
50
|
- rails/init.rb
|
48
|
-
- tasks/
|
51
|
+
- tasks/jcropper.rake
|
49
52
|
- test/jcropper_test.rb
|
50
53
|
- test/test_helper.rb
|
51
54
|
- uninstall.rb
|
@@ -59,23 +62,27 @@ rdoc_options:
|
|
59
62
|
require_paths:
|
60
63
|
- lib
|
61
64
|
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
62
66
|
requirements:
|
63
67
|
- - ">="
|
64
68
|
- !ruby/object:Gem::Version
|
69
|
+
hash: 3
|
65
70
|
segments:
|
66
71
|
- 0
|
67
72
|
version: "0"
|
68
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
69
75
|
requirements:
|
70
76
|
- - ">="
|
71
77
|
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
72
79
|
segments:
|
73
80
|
- 0
|
74
81
|
version: "0"
|
75
82
|
requirements: []
|
76
83
|
|
77
84
|
rubyforge_project:
|
78
|
-
rubygems_version: 1.3.
|
85
|
+
rubygems_version: 1.3.7
|
79
86
|
signing_key:
|
80
87
|
specification_version: 3
|
81
88
|
summary: gem plugin wrapping jquery
|