avatars_for_rails 0.2.9 → 1.0.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.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/README.rdoc +20 -71
  4. data/app/assets/javascripts/avatars_for_rails.js +67 -11
  5. data/app/assets/stylesheets/avatars_for_rails.css +0 -117
  6. data/app/controllers/avatars_controller.rb +23 -82
  7. data/app/views/avatars/_crop.html.erb +10 -0
  8. data/app/views/avatars/_form.html.erb +8 -80
  9. data/avatars_for_rails.gemspec +10 -12
  10. data/config/locales/en.yml +1 -0
  11. data/config/locales/es.yml +1 -0
  12. data/config/routes.rb +1 -4
  13. data/lib/avatars_for_rails/active_record.rb +13 -0
  14. data/lib/avatars_for_rails/avatarable.rb +86 -0
  15. data/lib/avatars_for_rails/engine.rb +13 -0
  16. data/lib/avatars_for_rails/version.rb +3 -0
  17. data/lib/avatars_for_rails.rb +24 -23
  18. data/vendor/assets/javascripts/jquery.Jcrop.js +1694 -0
  19. data/vendor/assets/javascripts/jquery.fileupload-ui.js +747 -469
  20. data/vendor/assets/javascripts/jquery.fileupload.js +1060 -867
  21. data/vendor/assets/stylesheets/jquery.Jcrop.css +161 -31
  22. metadata +98 -63
  23. data/app/models/avatar.rb +0 -149
  24. data/app/views/avatars/_errors.html.erb +0 -5
  25. data/app/views/avatars/_list.html.erb +0 -30
  26. data/app/views/avatars/_new.html.erb +0 -7
  27. data/app/views/avatars/_precrop.html.erb +0 -38
  28. data/app/views/avatars/destroy.js.erb +0 -2
  29. data/app/views/avatars/edit.html.erb +0 -6
  30. data/app/views/avatars/index.html.erb +0 -2
  31. data/app/views/avatars/new.html.erb +0 -1
  32. data/app/views/avatars/show.html.erb +0 -5
  33. data/app/views/avatars/update.js.erb +0 -9
  34. data/lib/avatars_for_rails/avatars_controller_config.rb +0 -4
  35. data/vendor/assets/javascripts/jquery.Jcrop.min.js +0 -163
data/app/models/avatar.rb DELETED
@@ -1,149 +0,0 @@
1
- require 'RMagick'
2
-
3
- class Avatar < ActiveRecord::Base
4
-
5
- #Paperclip configuration.
6
- has_attached_file :logo,
7
- :styles => AvatarsForRails.avatarable_styles,
8
- :default_url => "/assets/logos/:style/:subtype_class.png"
9
-
10
- before_post_process :process_precrop
11
- attr_accessor :crop_x, :crop_y, :crop_w, :crop_h, :name,:updating_logo,:drag,:drag_name
12
- validates_attachment_presence :logo, :if => :uploading_file?, :message => I18n.t('avatar.error.no_file')
13
-
14
- after_validation :precrop_done
15
-
16
- belongs_to AvatarsForRails.avatarable_model
17
-
18
- scope :active, where(:active => true)
19
-
20
- before_create :make_active
21
- after_create :disable_old
22
-
23
- #This method helps when changing the active logo for a user.
24
- def make_active
25
- self.updating_logo = true
26
- self.active = true
27
- end
28
-
29
- #Disable all the user's logos except the actual.
30
- def disable_old
31
- self.avatarable.avatars.where("id != ?", self.id).each do |old_logo|
32
- old_logo.update_attribute :active, false
33
- end
34
- end
35
-
36
- def avatarable
37
- __send__ AvatarsForRails.avatarable_model
38
- end
39
-
40
- def uploading_file?
41
- return @name.blank?
42
- end
43
-
44
- #Process the seccond step. It makes the precrop of the image and create a new avatar with the croped image.
45
- def precrop_done
46
- return if @name.blank? || !@updating_logo.blank?
47
-
48
- precrop_path = File.join(Avatar.images_tmp_path, @name)
49
-
50
- make_precrop(precrop_path,@crop_x.to_i,@crop_y.to_i,@crop_w.to_i,@crop_h.to_i)
51
-
52
- self.name = @name
53
- precropped = File.open(precrop_path)
54
- self.logo = precropped
55
- precropped.close
56
-
57
- FileUtils.remove_file(precrop_path)
58
- end
59
-
60
- #Returns the avatars_for_rails temp directory.
61
- def self.images_tmp_path
62
- tmp_path = File.join(Rails.root, 'public', AvatarsForRails.tmp_path)
63
- FileUtils.mkdir_p(tmp_path)
64
- tmp_path
65
- end
66
-
67
- def self.image_tmp_path(tmp_image)
68
- File.join '/', AvatarsForRails.tmp_path, tmp_image
69
- end
70
-
71
- #This method copies a file to the avatars_for_rails temp directory.
72
- def self.copy_to_temp_file(path)
73
- FileUtils.cp(path,Avatar.images_tmp_path)
74
- end
75
-
76
- #Returns the height and widht of an image.
77
- def self.get_image_dimensions(name)
78
- img_orig = Magick::Image.read(name).first
79
- dimensions = {}
80
- dimensions[:width] = img_orig.columns
81
- dimensions[:height] = img_orig.rows
82
- dimensions
83
- end
84
-
85
- #Checks if a file is valid for being an avatar.
86
- def self.check_image_tmp_valid(path)
87
-
88
- begin
89
- path = File.join(Avatar.images_tmp_path,path)
90
- img_orig = Magick::Image.read(path).first
91
- return true
92
- rescue
93
- return false
94
- end
95
- end
96
-
97
- #Process the image in the first step of the process. It resizes the image and copy it to the avatars_for_rails temp directory.
98
- def process_precrop
99
-
100
- if @name.blank? && ( logo.content_type.present? && !logo.content_type.start_with?("image/"))
101
- logo.errors['invalid_type'] = I18n.t('avatar.error.no_image_file')
102
- return false
103
- end
104
-
105
- return if !@name.blank?
106
-
107
- if resize_image(logo.queued_for_write[:original].path,500,500)
108
- logo.errors['precrop'] = "You have to make precrop"
109
- Avatar.copy_to_temp_file(logo.queued_for_write[:original].path)
110
- else
111
-
112
- end
113
- end
114
-
115
- #Resizes an image with the options passed as arguments.
116
- def resize_image(path,width,height)
117
- begin
118
- img_orig = Magick::Image.read(path).first
119
- img_orig = img_orig.resize_to_fit(width, height)
120
- img_orig.write(path)
121
- return true
122
- rescue
123
- logo.errors['invalid_type'] = I18n.t('avatar.error.no_image_file')
124
- return false
125
- end
126
- end
127
-
128
- #Precrop an image with the options passed as arguments.
129
- def make_precrop(path,x,y,width,height)
130
- begin
131
- img_orig = Magick::Image.read(path).first
132
- rescue
133
- logo.errors['invalid_type'] = I18n.t('avatar.error.no_image_file')
134
- return false
135
- end
136
-
137
- dimensions = Avatar.get_image_dimensions(path)
138
-
139
- unless (width == 0) || (height == 0)
140
- crop_args = [x,y,width,height]
141
- img_orig = img_orig.crop(*crop_args)
142
- end
143
-
144
- img_orig = img_orig.resize_to_fill(500,500)
145
-
146
- img_orig.write(path)
147
- end
148
- end
149
-
@@ -1,5 +0,0 @@
1
- <br class="clearfloat" />
2
-
3
- <% unless @avatar.logo.errors["invalid_type"].blank?%>
4
- <%= @avatar.logo.errors["invalid_type"]%>
5
- <% end %>
@@ -1,30 +0,0 @@
1
- <br class="clearfloat" />
2
- <div class="space_center"></div>
3
- <div class="space_center"></div>
4
- <% unless(@avatars.empty? || (@avatars.first.present? && @avatars.first.id.blank?)) %>
5
- <h2><%=t('avatar.text.use') %></h2>
6
- <div class="space_center"></div>
7
- <div class="space_center"></div>
8
- <div class="avatars" id="all_avatars">
9
- <% @avatars.each do |avatar| %>
10
- <% unless avatar.id.blank? %>
11
- <%= div_for(avatar) do %>
12
- <div class="boxgrid captionfull">
13
- <%= image_tag(avatar.logo.url(:profile), :class => avatar.active ? 'default' : 'non_default', :size => '94x94', :id => "avatar_img_#{avatar.id}") %>
14
- <div class="cover boxcaption">
15
- <%= link_to t('avatar.set_default'), avatar, :confirm => t('avatar.set_default_sure'), :method => :put, :remote => true, :id => "avatar_link_#{avatar.id}", :style => avatar.active ? 'display:none;': 'display:solid;' %>
16
- <%= link_to t('avatar.destroy'), avatar, :confirm => t('avatar.destroy_sure'), :method => :delete, :remote => true %>
17
- </div>
18
- </div>
19
- <% end %>
20
- <% end %>
21
- <% end %>
22
- </div>
23
- <br />
24
- <br class="clearfloat" />
25
- <div class="space_center"></div>
26
- <div class="space_center"></div>
27
- <h2><%=t('avatar.text.new') %></h2>
28
- <% else %>
29
- <h2><%= t('avatar.new') %></h2>
30
- <% end %>
@@ -1,7 +0,0 @@
1
- <% if !@avatar.logo.errors['precrop'].blank? %>
2
- <%= render :partial => 'precrop' %>
3
- <% elsif !@avatar.errors.blank? %>
4
- <%= render :partial => 'errors' %>
5
- <% else %>
6
- <% end %>
7
-
@@ -1,38 +0,0 @@
1
- <% if params[:drag_name].blank? %>
2
- <% my_file_name = File.basename(@avatar.logo.queued_for_write[:original].path.to_s) %>
3
- <% else %>
4
- <% my_file_name = params[:drag_name].to_s %>
5
- <% end %>
6
-
7
- <% if Avatar.check_image_tmp_valid(my_file_name) %>
8
- <div class = "block">
9
- <div id="precropPrev" >
10
- <div class="form_row">
11
- <%= t('avatar.preview') %>
12
- </div>
13
- <div id="precropPrevImg" class="logo">
14
- <%= image_tag Avatar.image_tmp_path(my_file_name) ,:id=>"preview" %>
15
- </div>
16
- </div>
17
-
18
- <div class="form_row">
19
- <%= t('avatar.original') %>
20
- </div>
21
-
22
- <div id="precropDiv" class = "block title content">
23
- <%= image_tag Avatar.image_tmp_path(my_file_name) ,:id=>"cropImage" %>
24
- </div>
25
- </div>
26
-
27
- <%= form_for @avatar, :html => { :multipart => true } do |f| %>
28
- <div class= "block">
29
- <% for attribute in [:crop_x, :crop_y, :crop_w, :crop_h] %>
30
- <%= f.hidden_field attribute, :id => attribute %>
31
- <% end %>
32
- <%= f.hidden_field :name, :value => my_file_name %>
33
- <div class="form_row center">
34
- <%= f.submit t('avatar.crop_submit'), :class => "button" %>
35
- </div>
36
- </div>
37
- <% end %>
38
- <% end %>
@@ -1,2 +0,0 @@
1
- $("#avatar_<%= deleted_id %>").remove();
2
-
@@ -1,6 +0,0 @@
1
- <h1>Editing logo</h1>
2
-
3
- <%= render 'form' %>
4
-
5
- <%= link_to 'Show', @avatar %> |
6
- <%= link_to 'Back', avatars_path %>
@@ -1,2 +0,0 @@
1
- <%= render :partial => 'list' %>
2
- <%= render :partial => 'form' %>
@@ -1 +0,0 @@
1
- <%= render :partial => 'new' %>
@@ -1,5 +0,0 @@
1
- <p id="notice"><%= notice %></p>
2
-
3
-
4
- <%= link_to 'Edit', edit_avatar_path(@avatar) %> |
5
- <%= link_to 'Back', avatars_path %>
@@ -1,9 +0,0 @@
1
- $("#avatar_img_<%= old_id %>").removeClass("default");
2
- $("#avatar_img_<%= old_id %>").addClass("non_default");
3
- $("#avatar_link_<%= old_id %>").show();
4
-
5
- $("#avatar_img_<%= new_id %>").removeClass("non_default");
6
- $("#avatar_img_<%= new_id %>").addClass("default");
7
- $("#avatar_link_<%= new_id %>").hide();
8
-
9
- $("#current_avatar_img").attr('src', $("#avatar_img_<%= new_id %>").attr('src') );
@@ -1,4 +0,0 @@
1
- module AvatarsForRails::AvatarsControllerConfig
2
-
3
-
4
- end
@@ -1,163 +0,0 @@
1
- /**
2
- * Jcrop v.0.9.8 (minimized)
3
- * (c) 2008 Kelly Hallman and DeepLiquid.com
4
- * More information: http://deepliquid.com/content/Jcrop.html
5
- * Released under MIT License - this header must remain with code
6
- */
7
-
8
-
9
- (function($){$.Jcrop=function(obj,opt)
10
- {var obj=obj,opt=opt;if(typeof(obj)!=='object')obj=$(obj)[0];if(typeof(opt)!=='object')opt={};if(!('trackDocument'in opt))
11
- {opt.trackDocument=$.browser.msie?false:true;if($.browser.msie&&$.browser.version.split('.')[0]=='8')
12
- opt.trackDocument=true;}
13
- if(!('keySupport'in opt))
14
- opt.keySupport=$.browser.msie?false:true;var defaults={trackDocument:false,baseClass:'jcrop',addClass:null,bgColor:'black',bgOpacity:.6,borderOpacity:.4,handleOpacity:.5,handlePad:5,handleSize:9,handleOffset:5,edgeMargin:14,aspectRatio:0,keySupport:true,cornerHandles:true,sideHandles:true,drawBorders:true,dragEdges:true,boxWidth:0,boxHeight:0,boundary:8,animationDelay:20,swingSpeed:3,allowSelect:true,allowMove:true,allowResize:true,minSelect:[0,0],maxSize:[0,0],minSize:[0,0],onChange:function(){},onSelect:function(){}};var options=defaults;setOptions(opt);var $origimg=$(obj);var $img=$origimg.clone().removeAttr('id').css({position:'absolute'});$img.width($origimg.width());$img.height($origimg.height());$origimg.after($img).hide();presize($img,options.boxWidth,options.boxHeight);var boundx=$img.width(),boundy=$img.height(),$div=$('<div />').width(boundx).height(boundy).addClass(cssClass('holder')).css({position:'relative',backgroundColor:options.bgColor}).insertAfter($origimg).append($img);;if(options.addClass)$div.addClass(options.addClass);var $img2=$('<img />').attr('src',$img.attr('src')).css('position','absolute').width(boundx).height(boundy);var $img_holder=$('<div />').width(pct(100)).height(pct(100)).css({zIndex:310,position:'absolute',overflow:'hidden'}).append($img2);var $hdl_holder=$('<div />').width(pct(100)).height(pct(100)).css('zIndex',320);var $sel=$('<div />').css({position:'absolute',zIndex:300}).insertBefore($img).append($img_holder,$hdl_holder);var bound=options.boundary;var $trk=newTracker().width(boundx+(bound*2)).height(boundy+(bound*2)).css({position:'absolute',top:px(-bound),left:px(-bound),zIndex:290}).mousedown(newSelection);var xlimit,ylimit,xmin,ymin;var xscale,yscale,enabled=true;var docOffset=getPos($img),btndown,lastcurs,dimmed,animating,shift_down;var Coords=function()
15
- {var x1=0,y1=0,x2=0,y2=0,ox,oy;function setPressed(pos)
16
- {var pos=rebound(pos);x2=x1=pos[0];y2=y1=pos[1];};function setCurrent(pos)
17
- {var pos=rebound(pos);ox=pos[0]-x2;oy=pos[1]-y2;x2=pos[0];y2=pos[1];};function getOffset()
18
- {return[ox,oy];};function moveOffset(offset)
19
- {var ox=offset[0],oy=offset[1];if(0>x1+ox)ox-=ox+x1;if(0>y1+oy)oy-=oy+y1;if(boundy<y2+oy)oy+=boundy-(y2+oy);if(boundx<x2+ox)ox+=boundx-(x2+ox);x1+=ox;x2+=ox;y1+=oy;y2+=oy;};function getCorner(ord)
20
- {var c=getFixed();switch(ord)
21
- {case'ne':return[c.x2,c.y];case'nw':return[c.x,c.y];case'se':return[c.x2,c.y2];case'sw':return[c.x,c.y2];}};function getFixed()
22
- {if(!options.aspectRatio)return getRect();var aspect=options.aspectRatio,min_x=options.minSize[0]/xscale,min_y=options.minSize[1]/yscale,max_x=options.maxSize[0]/xscale,max_y=options.maxSize[1]/yscale,rw=x2-x1,rh=y2-y1,rwa=Math.abs(rw),rha=Math.abs(rh),real_ratio=rwa/rha,xx,yy;if(max_x==0){max_x=boundx*10}
23
- if(max_y==0){max_y=boundy*10}
24
- if(real_ratio<aspect)
25
- {yy=y2;w=rha*aspect;xx=rw<0?x1-w:w+x1;if(xx<0)
26
- {xx=0;h=Math.abs((xx-x1)/aspect);yy=rh<0?y1-h:h+y1;}
27
- else if(xx>boundx)
28
- {xx=boundx;h=Math.abs((xx-x1)/aspect);yy=rh<0?y1-h:h+y1;}}
29
- else
30
- {xx=x2;h=rwa/aspect;yy=rh<0?y1-h:y1+h;if(yy<0)
31
- {yy=0;w=Math.abs((yy-y1)*aspect);xx=rw<0?x1-w:w+x1;}
32
- else if(yy>boundy)
33
- {yy=boundy;w=Math.abs(yy-y1)*aspect;xx=rw<0?x1-w:w+x1;}}
34
- if(xx>x1){if(xx-x1<min_x){xx=x1+min_x;}else if(xx-x1>max_x){xx=x1+max_x;}
35
- if(yy>y1){yy=y1+(xx-x1)/aspect;}else{yy=y1-(xx-x1)/aspect;}}else if(xx<x1){if(x1-xx<min_x){xx=x1-min_x}else if(x1-xx>max_x){xx=x1-max_x;}
36
- if(yy>y1){yy=y1+(x1-xx)/aspect;}else{yy=y1-(x1-xx)/aspect;}}
37
- if(xx<0){x1-=xx;xx=0;}else if(xx>boundx){x1-=xx-boundx;xx=boundx;}
38
- if(yy<0){y1-=yy;yy=0;}else if(yy>boundy){y1-=yy-boundy;yy=boundy;}
39
- return last=makeObj(flipCoords(x1,y1,xx,yy));};function rebound(p)
40
- {if(p[0]<0)p[0]=0;if(p[1]<0)p[1]=0;if(p[0]>boundx)p[0]=boundx;if(p[1]>boundy)p[1]=boundy;return[p[0],p[1]];};function flipCoords(x1,y1,x2,y2)
41
- {var xa=x1,xb=x2,ya=y1,yb=y2;if(x2<x1)
42
- {xa=x2;xb=x1;}
43
- if(y2<y1)
44
- {ya=y2;yb=y1;}
45
- return[Math.round(xa),Math.round(ya),Math.round(xb),Math.round(yb)];};function getRect()
46
- {var xsize=x2-x1;var ysize=y2-y1;if(xlimit&&(Math.abs(xsize)>xlimit))
47
- x2=(xsize>0)?(x1+xlimit):(x1-xlimit);if(ylimit&&(Math.abs(ysize)>ylimit))
48
- y2=(ysize>0)?(y1+ylimit):(y1-ylimit);if(ymin&&(Math.abs(ysize)<ymin))
49
- y2=(ysize>0)?(y1+ymin):(y1-ymin);if(xmin&&(Math.abs(xsize)<xmin))
50
- x2=(xsize>0)?(x1+xmin):(x1-xmin);if(x1<0){x2-=x1;x1-=x1;}
51
- if(y1<0){y2-=y1;y1-=y1;}
52
- if(x2<0){x1-=x2;x2-=x2;}
53
- if(y2<0){y1-=y2;y2-=y2;}
54
- if(x2>boundx){var delta=x2-boundx;x1-=delta;x2-=delta;}
55
- if(y2>boundy){var delta=y2-boundy;y1-=delta;y2-=delta;}
56
- if(x1>boundx){var delta=x1-boundy;y2-=delta;y1-=delta;}
57
- if(y1>boundy){var delta=y1-boundy;y2-=delta;y1-=delta;}
58
- return makeObj(flipCoords(x1,y1,x2,y2));};function makeObj(a)
59
- {return{x:a[0],y:a[1],x2:a[2],y2:a[3],w:a[2]-a[0],h:a[3]-a[1]};};return{flipCoords:flipCoords,setPressed:setPressed,setCurrent:setCurrent,getOffset:getOffset,moveOffset:moveOffset,getCorner:getCorner,getFixed:getFixed};}();var Selection=function()
60
- {var start,end,dragmode,awake,hdep=370;var borders={};var handle={};var seehandles=false;var hhs=options.handleOffset;if(options.drawBorders){borders={top:insertBorder('hline').css('top',$.browser.msie?px(-1):px(0)),bottom:insertBorder('hline'),left:insertBorder('vline'),right:insertBorder('vline')};}
61
- if(options.dragEdges){handle.t=insertDragbar('n');handle.b=insertDragbar('s');handle.r=insertDragbar('e');handle.l=insertDragbar('w');}
62
- options.sideHandles&&createHandles(['n','s','e','w']);options.cornerHandles&&createHandles(['sw','nw','ne','se']);function insertBorder(type)
63
- {var jq=$('<div />').css({position:'absolute',opacity:options.borderOpacity}).addClass(cssClass(type));$img_holder.append(jq);return jq;};function dragDiv(ord,zi)
64
- {var jq=$('<div />').mousedown(createDragger(ord)).css({cursor:ord+'-resize',position:'absolute',zIndex:zi});$hdl_holder.append(jq);return jq;};function insertHandle(ord)
65
- {return dragDiv(ord,hdep++).css({top:px(-hhs+1),left:px(-hhs+1),opacity:options.handleOpacity}).addClass(cssClass('handle'));};function insertDragbar(ord)
66
- {var s=options.handleSize,o=hhs,h=s,w=s,t=o,l=o;switch(ord)
67
- {case'n':case's':w=pct(100);break;case'e':case'w':h=pct(100);break;}
68
- return dragDiv(ord,hdep++).width(w).height(h).css({top:px(-t+1),left:px(-l+1)});};function createHandles(li)
69
- {for(i in li)handle[li[i]]=insertHandle(li[i]);};function moveHandles(c)
70
- {var midvert=Math.round((c.h/2)-hhs),midhoriz=Math.round((c.w/2)-hhs),north=west=-hhs+1,east=c.w-hhs,south=c.h-hhs,x,y;'e'in handle&&handle.e.css({top:px(midvert),left:px(east)})&&handle.w.css({top:px(midvert)})&&handle.s.css({top:px(south),left:px(midhoriz)})&&handle.n.css({left:px(midhoriz)});'ne'in handle&&handle.ne.css({left:px(east)})&&handle.se.css({top:px(south),left:px(east)})&&handle.sw.css({top:px(south)});'b'in handle&&handle.b.css({top:px(south)})&&handle.r.css({left:px(east)});};function moveto(x,y)
71
- {$img2.css({top:px(-y),left:px(-x)});$sel.css({top:px(y),left:px(x)});};function resize(w,h)
72
- {$sel.width(w).height(h);};function refresh()
73
- {var c=Coords.getFixed();Coords.setPressed([c.x,c.y]);Coords.setCurrent([c.x2,c.y2]);updateVisible();};function updateVisible()
74
- {if(awake)return update();};function update()
75
- {var c=Coords.getFixed();resize(c.w,c.h);moveto(c.x,c.y);options.drawBorders&&borders['right'].css({left:px(c.w-1)})&&borders['bottom'].css({top:px(c.h-1)});seehandles&&moveHandles(c);awake||show();options.onChange(unscale(c));};function show()
76
- {$sel.show();$img.css('opacity',options.bgOpacity);awake=true;};function release()
77
- {disableHandles();$sel.hide();$img.css('opacity',1);awake=false;};function showHandles()
78
- {if(seehandles)
79
- {moveHandles(Coords.getFixed());$hdl_holder.show();}};function enableHandles()
80
- {seehandles=true;if(options.allowResize)
81
- {moveHandles(Coords.getFixed());$hdl_holder.show();return true;}};function disableHandles()
82
- {seehandles=false;$hdl_holder.hide();};function animMode(v)
83
- {(animating=v)?disableHandles():enableHandles();};function done()
84
- {animMode(false);refresh();};var $track=newTracker().mousedown(createDragger('move')).css({cursor:'move',position:'absolute',zIndex:360})
85
- $img_holder.append($track);disableHandles();return{updateVisible:updateVisible,update:update,release:release,refresh:refresh,setCursor:function(cursor){$track.css('cursor',cursor);},enableHandles:enableHandles,enableOnly:function(){seehandles=true;},showHandles:showHandles,disableHandles:disableHandles,animMode:animMode,done:done};}();var Tracker=function()
86
- {var onMove=function(){},onDone=function(){},trackDoc=options.trackDocument;if(!trackDoc)
87
- {$trk.mousemove(trackMove).mouseup(trackUp).mouseout(trackUp);}
88
- function toFront()
89
- {$trk.css({zIndex:450});if(trackDoc)
90
- {$(document).mousemove(trackMove).mouseup(trackUp);}}
91
- function toBack()
92
- {$trk.css({zIndex:290});if(trackDoc)
93
- {$(document).unbind('mousemove',trackMove).unbind('mouseup',trackUp);}}
94
- function trackMove(e)
95
- {onMove(mouseAbs(e));};function trackUp(e)
96
- {e.preventDefault();e.stopPropagation();if(btndown)
97
- {btndown=false;onDone(mouseAbs(e));options.onSelect(unscale(Coords.getFixed()));toBack();onMove=function(){};onDone=function(){};}
98
- return false;};function activateHandlers(move,done)
99
- {btndown=true;onMove=move;onDone=done;toFront();return false;};function setCursor(t){$trk.css('cursor',t);};$img.before($trk);return{activateHandlers:activateHandlers,setCursor:setCursor};}();var KeyManager=function()
100
- {var $keymgr=$('<input type="radio" />').css({position:'absolute',left:'-30px'}).keypress(parseKey).blur(onBlur),$keywrap=$('<div />').css({position:'absolute',overflow:'hidden'}).append($keymgr);function watchKeys()
101
- {if(options.keySupport)
102
- {$keymgr.show();$keymgr.focus();}};function onBlur(e)
103
- {$keymgr.hide();};function doNudge(e,x,y)
104
- {if(options.allowMove){Coords.moveOffset([x,y]);Selection.updateVisible();};e.preventDefault();e.stopPropagation();};function parseKey(e)
105
- {if(e.ctrlKey)return true;shift_down=e.shiftKey?true:false;var nudge=shift_down?10:1;switch(e.keyCode)
106
- {case 37:doNudge(e,-nudge,0);break;case 39:doNudge(e,nudge,0);break;case 38:doNudge(e,0,-nudge);break;case 40:doNudge(e,0,nudge);break;case 27:Selection.release();break;case 9:return true;}
107
- return nothing(e);};if(options.keySupport)$keywrap.insertBefore($img);return{watchKeys:watchKeys};}();function px(n){return''+parseInt(n)+'px';};function pct(n){return''+parseInt(n)+'%';};function cssClass(cl){return options.baseClass+'-'+cl;};function getPos(obj)
108
- {var pos=$(obj).offset();return[pos.left,pos.top];};function mouseAbs(e)
109
- {return[(e.pageX-docOffset[0]),(e.pageY-docOffset[1])];};function myCursor(type)
110
- {if(type!=lastcurs)
111
- {Tracker.setCursor(type);lastcurs=type;}};function startDragMode(mode,pos)
112
- {docOffset=getPos($img);Tracker.setCursor(mode=='move'?mode:mode+'-resize');if(mode=='move')
113
- return Tracker.activateHandlers(createMover(pos),doneSelect);var fc=Coords.getFixed();var opp=oppLockCorner(mode);var opc=Coords.getCorner(oppLockCorner(opp));Coords.setPressed(Coords.getCorner(opp));Coords.setCurrent(opc);Tracker.activateHandlers(dragmodeHandler(mode,fc),doneSelect);};function dragmodeHandler(mode,f)
114
- {return function(pos){if(!options.aspectRatio)switch(mode)
115
- {case'e':pos[1]=f.y2;break;case'w':pos[1]=f.y2;break;case'n':pos[0]=f.x2;break;case's':pos[0]=f.x2;break;}
116
- else switch(mode)
117
- {case'e':pos[1]=f.y+1;break;case'w':pos[1]=f.y+1;break;case'n':pos[0]=f.x+1;break;case's':pos[0]=f.x+1;break;}
118
- Coords.setCurrent(pos);Selection.update();};};function createMover(pos)
119
- {var lloc=pos;KeyManager.watchKeys();return function(pos)
120
- {Coords.moveOffset([pos[0]-lloc[0],pos[1]-lloc[1]]);lloc=pos;Selection.update();};};function oppLockCorner(ord)
121
- {switch(ord)
122
- {case'n':return'sw';case's':return'nw';case'e':return'nw';case'w':return'ne';case'ne':return'sw';case'nw':return'se';case'se':return'nw';case'sw':return'ne';};};function createDragger(ord)
123
- {return function(e){if(options.disabled)return false;if((ord=='move')&&!options.allowMove)return false;btndown=true;startDragMode(ord,mouseAbs(e));e.stopPropagation();e.preventDefault();return false;};};function presize($obj,w,h)
124
- {var nw=$obj.width(),nh=$obj.height();if((nw>w)&&w>0)
125
- {nw=w;nh=(w/$obj.width())*$obj.height();}
126
- if((nh>h)&&h>0)
127
- {nh=h;nw=(h/$obj.height())*$obj.width();}
128
- xscale=$obj.width()/nw;yscale=$obj.height()/nh;$obj.width(nw).height(nh);};function unscale(c)
129
- {return{x:parseInt(c.x*xscale),y:parseInt(c.y*yscale),x2:parseInt(c.x2*xscale),y2:parseInt(c.y2*yscale),w:parseInt(c.w*xscale),h:parseInt(c.h*yscale)};};function doneSelect(pos)
130
- {var c=Coords.getFixed();if(c.w>options.minSelect[0]&&c.h>options.minSelect[1])
131
- {Selection.enableHandles();Selection.done();}
132
- else
133
- {Selection.release();}
134
- Tracker.setCursor(options.allowSelect?'crosshair':'default');};function newSelection(e)
135
- {if(options.disabled)return false;if(!options.allowSelect)return false;btndown=true;docOffset=getPos($img);Selection.disableHandles();myCursor('crosshair');var pos=mouseAbs(e);Coords.setPressed(pos);Tracker.activateHandlers(selectDrag,doneSelect);KeyManager.watchKeys();Selection.update();e.stopPropagation();e.preventDefault();return false;};function selectDrag(pos)
136
- {Coords.setCurrent(pos);Selection.update();};function newTracker()
137
- {var trk=$('<div></div>').addClass(cssClass('tracker'));$.browser.msie&&trk.css({opacity:0,backgroundColor:'white'});return trk;};function animateTo(a)
138
- {var x1=a[0]/xscale,y1=a[1]/yscale,x2=a[2]/xscale,y2=a[3]/yscale;if(animating)return;var animto=Coords.flipCoords(x1,y1,x2,y2);var c=Coords.getFixed();var animat=initcr=[c.x,c.y,c.x2,c.y2];var interv=options.animationDelay;var x=animat[0];var y=animat[1];var x2=animat[2];var y2=animat[3];var ix1=animto[0]-initcr[0];var iy1=animto[1]-initcr[1];var ix2=animto[2]-initcr[2];var iy2=animto[3]-initcr[3];var pcent=0;var velocity=options.swingSpeed;Selection.animMode(true);var animator=function()
139
- {return function()
140
- {pcent+=(100-pcent)/velocity;animat[0]=x+((pcent/100)*ix1);animat[1]=y+((pcent/100)*iy1);animat[2]=x2+((pcent/100)*ix2);animat[3]=y2+((pcent/100)*iy2);if(pcent<100)animateStart();else Selection.done();if(pcent>=99.8)pcent=100;setSelectRaw(animat);};}();function animateStart()
141
- {window.setTimeout(animator,interv);};animateStart();};function setSelect(rect)
142
- {setSelectRaw([rect[0]/xscale,rect[1]/yscale,rect[2]/xscale,rect[3]/yscale]);};function setSelectRaw(l)
143
- {Coords.setPressed([l[0],l[1]]);Coords.setCurrent([l[2],l[3]]);Selection.update();};function setOptions(opt)
144
- {if(typeof(opt)!='object')opt={};options=$.extend(options,opt);if(typeof(options.onChange)!=='function')
145
- options.onChange=function(){};if(typeof(options.onSelect)!=='function')
146
- options.onSelect=function(){};};function tellSelect()
147
- {return unscale(Coords.getFixed());};function tellScaled()
148
- {return Coords.getFixed();};function setOptionsNew(opt)
149
- {setOptions(opt);interfaceUpdate();};function disableCrop()
150
- {options.disabled=true;Selection.disableHandles();Selection.setCursor('default');Tracker.setCursor('default');};function enableCrop()
151
- {options.disabled=false;interfaceUpdate();};function cancelCrop()
152
- {Selection.done();Tracker.activateHandlers(null,null);};function destroy()
153
- {$div.remove();$origimg.show();};function interfaceUpdate(alt)
154
- {options.allowResize?alt?Selection.enableOnly():Selection.enableHandles():Selection.disableHandles();Tracker.setCursor(options.allowSelect?'crosshair':'default');Selection.setCursor(options.allowMove?'move':'default');$div.css('backgroundColor',options.bgColor);if('setSelect'in options){setSelect(opt.setSelect);Selection.done();delete(options.setSelect);}
155
- if('trueSize'in options){xscale=options.trueSize[0]/boundx;yscale=options.trueSize[1]/boundy;}
156
- xlimit=options.maxSize[0]||0;ylimit=options.maxSize[1]||0;xmin=options.minSize[0]||0;ymin=options.minSize[1]||0;if('outerImage'in options)
157
- {$img.attr('src',options.outerImage);delete(options.outerImage);}
158
- Selection.refresh();};$hdl_holder.hide();interfaceUpdate(true);var api={animateTo:animateTo,setSelect:setSelect,setOptions:setOptionsNew,tellSelect:tellSelect,tellScaled:tellScaled,disable:disableCrop,enable:enableCrop,cancel:cancelCrop,focus:KeyManager.watchKeys,getBounds:function(){return[boundx*xscale,boundy*yscale];},getWidgetSize:function(){return[boundx,boundy];},release:Selection.release,destroy:destroy};$origimg.data('Jcrop',api);return api;};$.fn.Jcrop=function(options)
159
- {function attachWhenDone(from)
160
- {var loadsrc=options.useImg||from.src;var img=new Image();img.onload=function(){$.Jcrop(from,options);};img.src=loadsrc;};if(typeof(options)!=='object')options={};this.each(function()
161
- {if($(this).data('Jcrop'))
162
- {if(options=='api')return $(this).data('Jcrop');else $(this).data('Jcrop').setOptions(options);}
163
- else attachWhenDone(this);});return this;};})(jQuery);