jcropper 0.1.0 → 0.3.0
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.
- 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
|