我正在尝试使用Carrierwave和Jcrop,就像Ryan Bates在RailsCasts第182集(修订版)中使用它一样,但我无法让Jcrop工作,我无法弄清楚原因。
当我到达crop.html.erb
时,它会按预期显示原始图片和预览,但我无法在原始图片上选择任何内容,而且预览没有响应。
我玩了一下,当我在()
后面添加.Jcrop
时,我至少可以在原始图片上选择一些内容,但预览仍然没有响应,所选区域也没有保持aspectRatio为1.所以我想由于某种原因,.Jcrop
之后的代码没有被执行。我不是CoffeeScript专家,所以我需要一些帮助来解决这个问题。
这是我的代码。非常感谢!
user.js.coffee
:
jQuery ->
new AvatarCropper()
class AvatarCropper
constructor: ->
$('#cropbox').Jcrop() ->
aspectRatio: 1
setSelect: [0, 0, 500, 500]
onSelect: @update
onChange: @update
update: (coords) =>
$('#user_crop_x').val(coords.x)
$('#user_crop_y').val(coords.y)
$('#user_crop_w').val(coords.w)
$('#user_crop_h').val(coords.h)
@updatePreview(coords)
updatePreview: (coords) =>
$('#preview').css
width: Math.round(100/coords.w * $('#cropbox').width()) + 'px'
height: Math.round(100/coords.h * $('#cropbox').height()) + 'px'
marginLeft: '-' + Math.round(100/coords.w * coords.x) + 'px'
marginTop: '-' + Math.round(100/coords.h * coords.y) + 'px'
users_controller.rb
:
def update
@user = User.find(params[:id])
if @user.update_attributes(params[:user])
if params[:user][:avatar].present?
render :crop
else
redirect_to @user, notice: "Successfully updated user."
end
else
render :new
end
end
def crop
@user = User.find(params[:id])
render view: "crop"
end
users/crop.html.erb
:
<h1>Crop Avatar</h1>
<%= image_tag @user.avatar_url(:pre_crop), id: "cropbox" %>
<h4>Preview</h4>
<div style="width:100px; height:100px; overflow:hidden;">
<%= image_tag @user.avatar.url(:pre_crop), :id => "preview" %>
</div>
<%= form_for @user do |f| %>
<div class="actions">
<% %w[x y w h].each do |attribute| %>
<%= f.hidden_field "crop_#{attribute}"%>
<% end %>
<%= f.submit "Crop" %>
</div>
<% end %>
答案 0 :(得分:4)
这不是你想要的:
$('#cropbox').Jcrop ->
aspectRatio: 1
setSelect: [0, 0, 500, 500]
onSelect: @update
onChange: @update
调用带有函数(->
)的Jcrop插件作为其参数,而Jcrop不知道如何处理函数。添加括号:
$('#cropbox').Jcrop() ->
aspectRatio: 1
setSelect: [0, 0, 500, 500]
onSelect: @update
onChange: @update
没有多大帮助;正确调用插件(.Jcrop()
),然后尝试将其返回值调用为另一个函数作为参数:
$('#cropbox').Jcrop()(-> ...)
那就是你让你使用裁剪器但你可能会收到一个错误,除非Jcrop插件返回一个函数;在任何情况下,这都不会让你的选项进入Jcrop插件,所以你的回调不会被调用,Jcrop也不会看到宽高比。
我认为您只想删除->
(并且不包括括号),以便使用选项对象调用Jcrop插件:
$('#cropbox').Jcrop
aspectRatio: 1
setSelect: [0, 0, 500, 500]
onSelect: @update
onChange: @update
如果圆括号可以帮助您查看分组,则可以这样做:
$('#cropbox').Jcrop(
aspectRatio: 1
setSelect: [0, 0, 500, 500]
onSelect: @update
onChange: @update
)
一旦完成,你需要仔细查看缩进,你的AvatarCropper没有update
和updatePreview
方法,因为它们缩进得太远了:
class AvatarCropper
constructor: ->
$('#cropbox').Jcrop
...
update: (coords) =>
...
updatePreview: (coords) =>
最终定义了一个像{update: ..., updatePreview: ...}
这样的匿名对象然后被抛弃了;更深层次的缩进(比如说4个空格)或者不同的编辑器,这个问题会更明显,但我不打算这么说,只要说你必须在CoffeeScript中非常仔细地观察你的空白;也许更好的编译器警告会对这个常见的错误有所帮助。修复你的缩进,你们都很好:
答案 1 :(得分:1)
如果你使用bootstrap,你必须添加
img.jcrop {max-width: none}
for your css .. somehow bootstrap is overriding img {max-width:100%}
答案 2 :(得分:0)
而不是使用js.coffee,将代码放在js文件中,而我已经放入application.js并像魅力一样工作
function showCoords(c) {
$('#user_crop_x').val(c.x);
$('#user_crop_y').val(c.y);
$('#user_crop_w').val(c.w);
$('#user_crop_h').val(c.h); };
jQuery(function($) {
$('#target').Jcrop({
onSelect: showCoords,
bgColor: 'magenta',
bgOpacity: .4,
setSelect: [ 0, 0, 600, 600 ],
aspectRatio: 1
});
});