RailsCast 182(修订版):Jcrop无法正常工作

时间:2012-05-03 19:23:43

标签: ruby-on-rails ruby-on-rails-3 coffeescript railscasts jcrop

我正在尝试使用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 %>

3 个答案:

答案 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没有updateupdatePreview方法,因为它们缩进得太远了:

class AvatarCropper
  constructor: ->
    $('#cropbox').Jcrop
    ...
    update: (coords) =>
    ...
    updatePreview: (coords) =>

最终定义了一个像{update: ..., updatePreview: ...}这样的匿名对象然后被抛弃了;更深层次的缩进(比如说4个空格)或者不同的编辑器,这个问题会更明显,但我不打算这么说,只要说你必须在CoffeeScript中非常仔细地观察你的空白;也许更好的编译器警告会对这个常见的错误有所帮助。修复你的缩进,你们都很好:

演示:http://jsfiddle.net/ambiguous/jTvV3/

答案 1 :(得分:1)

如果你使用bootstrap,你必须添加

img.jcrop {max-width: none}

for your css .. somehow bootstrap is overriding img {max-width:100%}

了解详情https://github.com/twbs/bootstrap/issues/1649

答案 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
    });
});

please refer the link if error persists