Skip to content

Commit

Permalink
Fixed loops with paperclip 3.4.0
Browse files Browse the repository at this point in the history
Jcrop updated to work with jQuery 1.9.0
  • Loading branch information
rsantamaria committed Jan 22, 2013
1 parent dd298e2 commit b454896
Show file tree
Hide file tree
Showing 14 changed files with 385 additions and 413 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

v0.1.0
- Upgraded dependencies
- Paperclip >= 3.4
- Using assign instead of reprocess! to avoid loops with Paperclip on callbacks
- Including this file!
- Now compatible with jQuery 1.9.0
- Jcrop upgraded to v0.9.10 (build:20130117)
- Added support for attachments on S3

v0.0.7
- Ajax support

v0.0.5
- Initial commit
262 changes: 19 additions & 243 deletions lib/assets/javascripts/jquery.jcrop.js

Large diffs are not rendered by default.

82 changes: 43 additions & 39 deletions lib/assets/javascripts/papercrop.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,50 @@
var jcrop_api;

var init_papercrop = function() {
$(document).ready(function() {
$('div[id$=_cropbox]').each(function() {
var aspect, attachment, preview, update_crop;

attachment = $(this).attr('id').replace('_cropbox', '');
preview = !!$("#" + attachment + "_crop_preview").length;
aspect = $("input#" + attachment + "_aspect").val();

update_crop = function(coords) {
var preview_width, rx, ry;

if (preview) {
preview_width = $("#" + attachment + "_crop_preview_wrapper").width();
rx = preview_width / coords.w;
ry = preview_width / coords.h;

$("img#" + attachment + "_crop_preview").css({
width : Math.round(rx * $("input[id$='_" + attachment + "_original_w']").val()) + "px",
height : Math.round((ry * $("input[id$='_" + attachment + "_original_h']").val()) / aspect) + "px",
marginLeft : "-" + Math.round(rx * coords.x) + "px",
marginTop : "-" + Math.round((ry * coords.y) / aspect) + "px"
});
}

$("#" + attachment + "_crop_x").val(Math.round(coords.x));
$("#" + attachment + "_crop_y").val(Math.round(coords.y));
$("#" + attachment + "_crop_w").val(Math.round(coords.w));
$("#" + attachment + "_crop_h").val(Math.round(coords.h));
};

$(this).find('img').Jcrop({
onChange : update_crop,
onSelect : update_crop,
setSelect : [0, 0, 500, 500],
aspectRatio : aspect,
boxWidth : $("input[id$='_" + attachment + "_box_w']").val()
}, function(){ jcrop_api = this; });
window.init_papercrop = function() {
$("div[id$=_cropbox]").each(function() {

var attachment = $(this).attr("id").replace("_cropbox", "");
var preview = !!$("#" + attachment + "_crop_preview").length;
var aspect = $("input#" + attachment + "_aspect").val();
var width = $(this).width();

console.log($(this));

update_crop = function(coords) {
var preview_width, rx, ry;

if (preview) {
preview_width = $("#" + attachment + "_crop_preview_wrapper").width();

rx = preview_width / coords.w;
ry = preview_width / coords.h;

$("img#" + attachment + "_crop_preview").css({
width : Math.round(rx * $("input[id$='_" + attachment + "_original_w']").val()) + "px",
height : Math.round((ry * $("input[id$='_" + attachment + "_original_h']").val()) / aspect) + "px",
marginLeft : "-" + Math.round(rx * coords.x) + "px",
marginTop : "-" + Math.round((ry * coords.y) / aspect) + "px"
});
}

$("#" + attachment + "_crop_x").val(Math.round(coords.x));
$("#" + attachment + "_crop_y").val(Math.round(coords.y));
$("#" + attachment + "_crop_w").val(Math.round(coords.w));
$("#" + attachment + "_crop_h").val(Math.round(coords.h));
};

$(this).find("img").Jcrop({
onChange : update_crop,
onSelect : update_crop,
setSelect : [0, 0, 250, 250],
aspectRatio : aspect,
boxWidth : $("input[id$='_" + attachment + "_box_w']").val()
}, function() {
jcrop_api = this;
});
});
}
};


$(document).ready(function() {
init_papercrop();
Expand Down
103 changes: 77 additions & 26 deletions lib/assets/stylesheets/jquery.jcrop.css
Original file line number Diff line number Diff line change
@@ -1,35 +1,86 @@
/* Fixes issue here http://code.google.com/p/jcrop/issues/detail?id=1 */
.jcrop-holder { text-align: left; }
/* jquery.Jcrop.css v0.9.10 - MIT License */

.jcrop-vline, .jcrop-hline
{
font-size: 0px;
position: absolute;
background: white url('Jcrop.gif') top left repeat;
/*
The outer-most container in a typical Jcrop instance
If you are having difficulty with formatting related to styles
on a parent element, place any fixes here or in a like selector
You can also style this element if you want to add a border, etc
A better method for styling can be seen below with .jcrop-light
(Add a class to the holder and style elements for that extended class)
*/
.jcrop-holder {
direction: ltr;
text-align: left;
}
.jcrop-vline { height: 100%; width: 1px !important; }
.jcrop-hline { width: 100%; height: 1px !important; }
.jcrop-vline.right { right: 0px; }
.jcrop-hline.bottom { bottom: 0px; }
.jcrop-handle {
font-size: 1px;
width: 7px !important;
height: 7px !important;
border: 1px #eee solid;
background-color: #333;

/* These styles define the border lines */
.jcrop-vline,.jcrop-hline{background:#FFF url(Jcrop.gif) top left repeat;font-size:0;position:absolute;}
.jcrop-vline{height:100%;width:1px!important;}
.jcrop-hline{height:1px!important;width:100%;}
.jcrop-vline.right{right:0;}
.jcrop-hline.bottom{bottom:0;}

/* Handle style - size is set by Jcrop handleSize option (currently) */
.jcrop-handle{background-color:#333;border:1px #eee solid;font-size:1px;}

/* This style is used for invisible click targets */
.jcrop-tracker
{
height: 100%;
width: 100%;
-webkit-tap-highlight-color: transparent; /* "turn off" link highlight */
-webkit-touch-callout: none; /* disable callout, image save panel */
-webkit-user-select: none; /* disable cut copy paste */
}

.jcrop-tracker { width: 100%; height: 100%; }
/* Positioning of handles and drag bars */
.jcrop-handle.ord-n{left:50%;margin-left:-4px;margin-top:-4px;top:0;}
.jcrop-handle.ord-s{bottom:0;left:50%;margin-bottom:-4px;margin-left:-4px;}
.jcrop-handle.ord-e{margin-right:-4px;margin-top:-4px;right:0;top:50%;}
.jcrop-handle.ord-w{left:0;margin-left:-4px;margin-top:-4px;top:50%;}
.jcrop-handle.ord-nw{left:0;margin-left:-4px;margin-top:-4px;top:0;}
.jcrop-handle.ord-ne{margin-right:-4px;margin-top:-4px;right:0;top:0;}
.jcrop-handle.ord-se{bottom:0;margin-bottom:-4px;margin-right:-4px;right:0;}
.jcrop-handle.ord-sw{bottom:0;left:0;margin-bottom:-4px;margin-left:-4px;}
.jcrop-dragbar.ord-n,.jcrop-dragbar.ord-s{height:7px;width:100%;}
.jcrop-dragbar.ord-e,.jcrop-dragbar.ord-w{height:100%;width:7px;}
.jcrop-dragbar.ord-n{margin-top:-4px;}
.jcrop-dragbar.ord-s{bottom:0;margin-bottom:-4px;}
.jcrop-dragbar.ord-e{margin-right:-4px;right:0;}
.jcrop-dragbar.ord-w{margin-left:-4px;}

.custom .jcrop-vline,
.custom .jcrop-hline
/* The "jcrop-light" class/extension */
.jcrop-light .jcrop-vline,.jcrop-light .jcrop-hline
{
background: yellow;
background:#FFF;
filter:Alpha(opacity=70)!important;
opacity:.70!important;
}
.custom .jcrop-handle
.jcrop-light .jcrop-handle
{
border-color: black;
background-color: #C7BB00;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
-moz-border-radius:3px;
-webkit-border-radius:3px;
background-color:#000;
border-color:#FFF;
border-radius:3px;
}

/* The "jcrop-dark" class/extension */
.jcrop-dark .jcrop-vline,.jcrop-dark .jcrop-hline
{
background:#000;
filter:Alpha(opacity=70)!important;
opacity:.7!important;
}
.jcrop-dark .jcrop-handle
{
-moz-border-radius:3px;
-webkit-border-radius:3px;
background-color:#FFF;
border-color:#000;
border-radius:3px;
}

/* Fix for twitter bootstrap et al. */
.jcrop-holder img,img.jcrop-preview{ max-width: none; }
1 change: 1 addition & 0 deletions lib/papercrop.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'papercrop/engine'
require 'papercrop/reg_exp'
require 'papercrop/active_record_extension'
require 'papercrop/helpers'
require 'paperclip_processors/cropper'
51 changes: 32 additions & 19 deletions lib/papercrop/active_record_extension.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ module ClassMethods
#
# crop_attached_file :avatar, :aspect => "4:3"
#
# @param attachment_name [Symbol] The name of the desired attachment to crop
# @param attachment_name [Symbol] Name of the desired attachment to crop
# @param opts [Hash]
def crop_attached_file(attachment_name, opts = {})
[:crop_x, :crop_y, :crop_w, :crop_h, :original_w, :original_h, :box_w, :aspect].each do |a|
[:crop_x, :crop_y, :crop_w, :crop_h, :original_w, :original_h, :box_w, :aspect, :cropped_geometries].each do |a|
attr_accessor :"#{attachment_name}_#{a}"
end

if opts[:aspect].kind_of?(String) && opts[:aspect] =~ /^(\d{1,2}):(\d{1,2})$/
if opts[:aspect].kind_of?(String) && opts[:aspect] =~ Papercrop::RegExp::ASPECT
opts[:aspect] = Range.new *opts[:aspect].split(':').map(&:to_i)
end

Expand All @@ -46,6 +46,9 @@ def crop_attached_file(attachment_name, opts = {})
module InstanceMethods

# Asks if the attachment received a crop process
# @param attachment_name [Symbol]
#
# @return [Boolean]
def cropping?(attachment_name)
!self.send(:"#{attachment_name}_crop_x").blank? &&
!self.send(:"#{attachment_name}_crop_y").blank? &&
Expand All @@ -54,40 +57,50 @@ def cropping?(attachment_name)
end


# Returns a Paperclip::Geometry object from a named attachment
# Returns a Paperclip::Geometry object of a given attachment
#
# @param attachment_name [Symbol]
# @param style [Symbol] attachment style, :original by default
# @return Paperclip::Geometry

# def image_geometry(attachment_name, style = :original)
# @geometry ||= {}
# @geometry[style] ||= Paperclip::Geometry.from_file(self.send(attachment_name).path(style))
# end

# @param attachment_name [Symbol]
# @param style = :original [Symbol] attachment style
# @return [Paperclip::Geometry]
def image_geometry(attachment_name, style = :original)
@geometry ||= {}
path = (self.send(attachment_name).options[:storage]==:s3) ? self.send(attachment_name).url(style) : self.send(attachment_name).path(style)
path = (self.send(attachment_name).options[:storage] == :s3) ? self.send(attachment_name).url(style) : self.send(attachment_name).path(style)
@geometry[style] ||= Paperclip::Geometry.from_file(path)
end


# Uses method missing to reprocess the attachment callback
# Uses method missing to responding the model callback
def method_missing(method, *args)
if method.to_s =~ /(reprocess_to_crop_)(\S{1,})(_attachment)/
if method.to_s =~ Papercrop::RegExp::CALLBACK
reprocess_cropped_attachment(
method.to_s.scan(/(reprocess_to_crop_)(\S{1,})(_attachment)/).flatten.second.to_sym
method.to_s.scan(Papercrop::RegExp::CALLBACK).flatten.first.to_sym
)
else
super
end
end


# Sets all cropping attributes to nil
# @param attachment_name [Symbol]
def reset_crop_attributes_of(attachment_name)
[:crop_x, :crop_y, :crop_w, :crop_h].each do |a|
self.send :"#{attachment_name}_#{a}=", nil
end
end

private

# Reprocess the attachment after cropping
# Saves the attachment if the crop attributes are present
# @param attachment_name [Symbol]
def reprocess_cropped_attachment(attachment_name)
self.send(attachment_name.to_sym).reprocess! if cropping?(attachment_name)
if cropping?(attachment_name)
attachment_instance = send(attachment_name)
attachment_instance.assign(attachment_instance)
attachment_instance.save

reset_crop_attributes_of(attachment_name)
end
end

end
Expand Down
6 changes: 6 additions & 0 deletions lib/papercrop/reg_exp.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Papercrop
module RegExp
ASPECT = /^([1-9]{1}\d*):([1-9]{1}\d*)$/
CALLBACK = /reprocess_to_crop_(\S{1,})_attachment/
end
end
7 changes: 4 additions & 3 deletions papercrop.gemspec
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@

Gem::Specification.new do |s|
s.name = 'papercrop'
s.version = '0.0.7'
s.date = '2012-10-12'
s.version = '0.1.0'
s.date = '2013-01-22'
s.summary = "Paperclip extension for cropping images"
s.description = "An easy extension for Paperclip to crop your image uploads using jCrop"
s.authors = ["Ruben Santamaria"]
Expand All @@ -15,10 +15,11 @@ Gem::Specification.new do |s|

s.add_dependency "rails", ">= 3.1"
s.add_dependency "jquery-rails"
s.add_dependency "paperclip", ">= 3.1"
s.add_dependency "paperclip", ">= 3.4"

s.add_development_dependency "rspec-rails", "~> 2.0"
s.add_development_dependency "capybara", ">= 1.1.1"
s.add_development_dependency "mocha"
s.add_development_dependency "rmagick"
s.add_development_dependency "sass"
s.add_development_dependency "sqlite3"
Expand Down
Loading

2 comments on commit b454896

@jgarber
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really wish I knew what part was "Fixed loops with paperclip 3.4.0". Can't tell with a squashed commit like this.

@jgarber
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found it. Thanks #5 (comment)

Please sign in to comment.