27
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

画像を好みの位置でトリミングする / Rails + jQuery UI draggable

Last updated at Posted at 2014-06-02

ブログを更新しました。元の記事はコチラ


画像を投稿させるサービスで、ユーザーが推奨サイズ比率ではない画像をアップロードした場合、好みの位置でトリミングさせるやつを考えてみた。TwitterとかFacebookのカバー写真をアップロードした時のアレです。今回はズームとか無しで、縦方向のみの位置調整にしてみました。(画像のwidthは100%)

  
画像をトリミングして保存するわけでなく、単に画像位置を動かして、表示範囲以外は見えなくする方法を取っています。切り取ってしまうと、他のレイアウトで使う時に困ることもあるので、個人的にはこの方法が好みです。
  

###準備

自分はRailsを使っているので、こんな感じ。

Gemfile

gem 'jquery-ui-rails'

  

assets/javascripts/application.js

//= require jquery
//= require jquery.ui.widget
//= require jquery.ui.droppable

  
###考え方

drag-and-drop

Rails側はこんな感じ。
PostモデルとImageモデルがあって、Postはサムネイル画像を1枚持ちます。
(Post belongs to image)
画像の位置はimage_posでpostsテーブルに保存します。

models/post.rb

class Post < ActiveRecord::Base
	belongs_to :image
end

  
見た目の例は、こんなのです。
CSSは適当なので、環境に合わせて変更してください。

views/posts/edit.html.erb


	<div class="image_attach">
		<%= f.hidden_field :image_id, id: "thumb", data: { draggable: true } %>
		<%= f.hidden_field :image_pos %>
		<% if post.image.present? %>
			<%= image_tag "http://workabroad.jp/image.jpg", style: "top: #{post.image_pos}%" %>
		<% end %>
	</div>

  
assets/stylesheets/posts.css.scss

.image_attach {
  height: 300px;
  overflow: hidden;
  position: relative;
  img {
    width: 100%;
    position: absolute;
    top: 0;
  }
}

  

###Javascriptで実装する

使い回しが効くように、外部ファイルにしました。

assets/javascripts/common.js.coffee


class window.Image

	# Draggable
	@enable_drag: ->
		img = $('.image_attach img')
		box = $('.image_attach')
		pos = $('#post_image_pos')

		$('.image_attach img').draggable({
			axis: "y"
			stop: (event, obj) ->
				# Set position
				range = img.height() - box.outerHeight()
				moved = obj.position.top / box.height() * 100 
				# Top max
				if img.position().top > 0
					img.css('top', '0px')
					moved = 0
				# Bottom max
				if Math.abs($(this).position().top) > range
					img.css('top', '-' + range + 'px')
					moved = -range / box.height() * 100 

				pos.val(moved)
		})

  
assets/javascripts/posts.js.coffee


ready = ->
	# Draggable
	if $('#thumb').data('draggable') == true
		Image.enable_drag()

# For turbolinks
$(document).ready(ready)
$(document).on('page:load', ready)

ドラッグが終了するタイミング(ドロップ)で、f.hidden_field :image_pos の値を変更しているだけです。今回はレスポンシブデザインを想定しているので、保存する値はpxでなくて、%にしました。

あとはViewで画像を表示する時に、 image_pos の値を style="top: #{post.image_pos}%" のように挿入すればいいかと。
  

http://workabroad.jp/posts/2095

27
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?