imgix-rails 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 123b72f2be8e8d5a3d5a8170b386e1623d763010
4
- data.tar.gz: fdda3f207a947cd64dbef1d1a20f4558b0155deb
3
+ metadata.gz: 62c3df395875ff9ec0422abe8b6b5ab60ddc8a0c
4
+ data.tar.gz: 285cbe4283c1caad13a3266dfe150e1726a6977f
5
5
  SHA512:
6
- metadata.gz: 056412199a9166b00ece1946bb78d8399ba8e59bc3079bbe41598cf9774ec0b04d6657e1d0aba4ddd39ca179a70bf229a4f47d03d876d4411e66f69296936644
7
- data.tar.gz: 402a42b8784e40243dcee65aaca5a64b531caf629a15efaf78b305cbfb9e3a0f22dd8f40a970eb8fbc436cb29a0c1a9ce56a9a67c936a9e44b4c71fc3097361c
6
+ metadata.gz: c3ecb91c1f1452f5a026bf77590d56987ab2946d7875276a95784ab9dec52c89d245ae3b73a002199513addca758848ac4fcb588570440106b076519a32154da
7
+ data.tar.gz: 26927455ee9b481d06a6427176876d2f2ee5c45c28c5f96af2cada5c35eeae582de03da29ecb8649787785a855db001b7bf6387132d06c7ba65afaddb9759674
data/README.md CHANGED
@@ -12,12 +12,11 @@ We recommend using something like [Paperclip](https://github.com/thoughtbot/pape
12
12
  * [Usage](#usage)
13
13
  * [Configuration](#configuration)
14
14
  * [ix_image_tag](#ix_image_tag)
15
- * [ix_responsive_image_tag](#ix_responsive_image_tag)
16
15
  * [ix_picture_tag](#ix_picture_tag)
17
16
  * [ix_image_url](#ix_image_url)
18
17
  * [Hostname Removal](#hostname-removal)
19
18
  * [Using With Image Uploading Libraries](#using-with-image-uploading-libraries)
20
- * [Paperclip](#paperclip)
19
+ * [Paperclip and CarrierWave](#paperclip-and-carrierwave)
21
20
  * [Refile](#refile)
22
21
  * [Development](#development)
23
22
  * [Contributing](#contributing)
@@ -65,16 +64,28 @@ The following configuration flags will be respected:
65
64
  <a name="ix_image_tag"></a>
66
65
  ### ix_image_tag
67
66
 
68
- The simplest way of working with imgix-rails is to use the `ix_image_tag`, this allows you to pass parameters to imgix to handle things like resizing, cropping, etc.
67
+ The `ix_image_tag` helper method makes it easy to pass parameters to imgix to handle resizing, cropping, etc. It also simplifies adding responsive imagery to your Rails app by automatically generating a `srcset` based on the parameters you pass. We talk a bit about using the `srcset` attribute in an application in the following blog post: [“Responsive Images with `srcset` and imgix.”](http://blog.imgix.com/post/127012184664/responsive-images-with-srcset-imgix).
68
+
69
+ `ix_image_tag` generates `<img>` tags with a filled-out `srcset` attribute that leans on imgix to do the hard work. If you already know the minimum or maximum number of physical pixels that this image will need to be displayed at, you can pass the `min_width` and/or `max_width` options. This will result in a smaller, more tailored `srcset`.
69
70
 
70
71
  ```erb
71
- <%= ix_image_tag('/path/to/image.jpg', { w: 400, h: 300 }) %>
72
+ <%= ix_image_tag('/unsplash/hotairballoon.jpg', { w: 300, h: 500, fit: 'crop', crop: 'right', alt: 'A hot air balloon on a sunny day' }) %>
72
73
  ```
73
74
 
74
75
  Will render out HTML like the following:
75
76
 
76
77
  ```html
77
- <img src="https://assets.imgix.net/path/to/image?w=400&h=300" />
78
+ <img
79
+ alt="A hot air balloon on a sunny day"
80
+ sizes="100vw"
81
+ srcset="
82
+ https://assets.imgix.net/unsplash/hotairballoon.jpg?w=100&amp;h=167&amp;fit=crop&amp;crop=right 100w,
83
+ https://assets.imgix.net/unsplash/hotairballoon.jpg?w=200&amp;h=333&amp;fit=crop&amp;crop=right 200w,
84
+
85
+ https://assets.imgix.net/unsplash/hotairballoon.jpg?w=2560&amp;h=4267&amp;fit=crop&amp;crop=right 2560w
86
+ "
87
+ src="https://assets.imgix.net/unsplash/hotairballoon.jpg?w=300&amp;h=500&amp;fit=crop&amp;crop=right"
88
+ >
78
89
  ```
79
90
 
80
91
  We recommend leveraging this to generate powerful helpers within your application like the following:
@@ -91,51 +102,46 @@ Then rendering the portrait in your application is very easy:
91
102
  <%= profile_image_tag(@user) %>
92
103
  ```
93
104
 
94
- <a name="ix_responsive_image_tag"></a>
95
- ### ix_responsive_image_tag
96
-
97
- The `ix_responsive_image_tag` helper method makes it easy to bring responsive imagery to your Rails app. We talk a bit about using the `srcset` attribute in an application in the following blog post: [“Responsive Images with `srcset` and imgix.”](http://blog.imgix.com/post/127012184664/responsive-images-with-srcset-imgix)
98
-
99
- The `ix_responsive_image_tag` will generate an `<img>` element with a filled-out `srcset` attribute that leans on imgix to do the hard work.
100
-
101
- It will use the configured device-pixel-ratios in the `config.imgix[:responsive_resolutions]` value. It will default to `[1, 2]`.
102
-
103
- ```erb
104
- <%= ix_responsive_image_tag('/users/1/avatar.png', { w: 400, h: 300 }) %>
105
- ```
106
-
107
- This will generate the following HTML:
108
-
109
- ```html
110
- <img
111
- srcset="https://assets.imgix.net/users/1/avatar.png?w=400&h=300 1x,
112
- https://assets.imgix.net/users/1/avatar.png?w=400&h=300&dpr=2 2x"
113
- src="https://assets.imgix.net/users/1/avatar.png?w=400&h=300"
114
- />
115
- ```
116
105
 
117
106
  <a name="ix_picture_tag"></a>
118
107
  ### ix_picture_tag
119
108
 
120
- The `ix_picture_tag` helper method makes it easy to generate `<picture>` elements in your Rails app.
109
+ The `ix_picture_tag` helper method makes it easy to generate `picture` elements in your Rails app. `picture` elements are useful when an images needs to be art directed differently at different screen sizes.
121
110
 
122
- The `ix_picture_tag` method will generate a `<picture>` element with a single `<source>` element and a fallback `<img>` element. We are open for new directions to take this in.
111
+ `ix_picture_tag` takes four arguments:
123
112
 
124
- It will use the configured device-pixel-ratios in the `config.imgix[:responsive_resolutions]` value. It will default to `[1, 2]`.
113
+ * `source`: The path or URL of the image to display.
114
+ * `picture_tag_options`: Any options to apply to the parent `picture` element. This is useful for adding class names, etc.
115
+ * `imgix_default_options`: Default imgix options. These will be used to generate a fallback `img` tag for older browsers, and used in each `source` unless overridden by `breakpoints`.
116
+ * `breakpoints`: A hash describing the variants. Each key must be a media query (e.g. `(max-width: 880px)`), and each value must be a hash of param overrides for that media query. A `source` element will be generated for each breakpoint specified.
125
117
 
126
118
  ```erb
127
- <%= ix_picture_tag('/users/1/avatar.png', { w: 400, h: 300 }) %>
119
+ <%= ix_picture_tag('bertandernie.jpg',
120
+ picture_tag_options: {
121
+ class: 'a-picture-tag'
122
+ },
123
+ imgix_default_options: {
124
+ w: 300,
125
+ h: 300,
126
+ fit: 'crop',
127
+ },
128
+ breakpoints: {
129
+ '(max-width: 640px)' => {
130
+ h: 100,
131
+ sizes: 'calc(100vw - 20px)'
132
+ },
133
+ '(max-width: 880px)' => {
134
+ crop: 'right',
135
+ sizes: 'calc(100vw - 20px - 50%)'
136
+ },
137
+ '(min-width: 881px)' => {
138
+ crop: 'left',
139
+ sizes: '430px'
140
+ }
141
+ }
142
+ ) %>
128
143
  ```
129
144
 
130
- Will generate the following HTML:
131
-
132
- ```html
133
- <picture>
134
- <source srcset="https://assets.imgix.net/users/1/avatar.png?w=400&h=300 1x,
135
- https://assets.imgix.net/users/1/avatar.png?w=400&h=300&dpr=2 2x" />
136
- <img src="https://assets.imgix.net/users/1/avatar.png?w=400&h=300" />
137
- </picture>
138
- ```
139
145
 
140
146
  <a name="ix_image_url"></a>
141
147
  ### ix_image_url
@@ -201,10 +207,10 @@ Renders:
201
207
  imgix-rails plays well with image uploading libraries, because it just requires a URL and optional parameters as arguments. A good way to handle this interaction is by creating helpers that bridge between your uploading library of choice and imgix-rails. Below are examples of how this can work with some common libraries. Please submit an issue if you'd like to see specific examples for another!
202
208
 
203
209
 
204
- <a name="paperclip"></a>
205
- ### Paperclip
210
+ <a name="paperclip-and-carrierwave"></a>
211
+ ### Paperclip and CarrierWave
206
212
 
207
- Paperclip can directly provide paths to uploaded images, so we can use it with imgix-rails without a bridge.
213
+ Paperclip and CarrierWave can directly provide paths to uploaded images, so we can use them with imgix-rails without a bridge.
208
214
 
209
215
  ``` html
210
216
  <%= ix_image_tag(@user.avatar.path, { auto: 'format', fit: 'crop', w: 500}) %>
@@ -0,0 +1,13 @@
1
+ require "imgix/rails/tag"
2
+
3
+ class Imgix::Rails::ImageTag < Imgix::Rails::Tag
4
+ def render
5
+ @options[:srcset] = srcset
6
+ @options[:sizes] ||= '100vw'
7
+
8
+ @source = replace_hostname(@source)
9
+ normal_opts = @options.slice!(*self.class.available_parameters)
10
+
11
+ image_tag(ix_image_url(@source, @options), normal_opts)
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ require "imgix/rails/tag"
2
+ require "imgix/rails/image_tag"
3
+
4
+ class Imgix::Rails::PictureTag < Imgix::Rails::Tag
5
+ include ActionView::Context
6
+
7
+ def initialize(source, options, default_options, breakpoints)
8
+ @source = source
9
+ @options = options
10
+ @default_options = default_options
11
+ @breakpoints = breakpoints
12
+ end
13
+
14
+ def render
15
+ content_tag(:picture, @options) do
16
+ @breakpoints.each do |media, opts|
17
+ html_opts = opts.except(*self.class.available_parameters)
18
+ html_opts[:media] ||= media
19
+ html_opts[:srcset] ||= srcset(@default_options.clone.merge(opts))
20
+
21
+
22
+ concat(content_tag(:source, nil, html_opts))
23
+ end
24
+
25
+ concat Imgix::Rails::ImageTag.new(@source, @default_options).render
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,162 @@
1
+ require "imgix/rails/url_helper"
2
+
3
+ class Imgix::Rails::Tag
4
+ include Imgix::Rails::UrlHelper
5
+ include ActionView::Helpers
6
+
7
+ @@parameters = nil
8
+
9
+ # Store our parameter information on the class instance so that
10
+ # each instance of any this class or our subclasses doesn't have to
11
+ # go back to disk to get this configuration information
12
+ def self.available_parameters
13
+ @@available_parameters ||= parameters.keys
14
+ end
15
+
16
+ def self.parameters
17
+ return @@parameters if @@parameters
18
+
19
+ path = File.expand_path("../../../../vendor/parameters.json", __FILE__)
20
+ @@parameters ||= JSON.parse(File.read(path), symbolize_names: true)[:parameters]
21
+ end
22
+
23
+ def initialize(source, options={})
24
+ @source = source
25
+ @options = options
26
+ end
27
+
28
+ protected
29
+
30
+ def srcset(opts=@options)
31
+ @source = replace_hostname(@source)
32
+ target_widths.map do |target_width|
33
+ srcset_options = opts.slice(*self.class.available_parameters)
34
+ srcset_options[:w] = target_width
35
+
36
+ if opts[:w].present? && opts[:h].present?
37
+ srcset_options[:h] = (target_width * (opts[:h].to_f / opts[:w])).round
38
+ end
39
+
40
+ "#{ix_image_url(@source, srcset_options)} #{target_width}w"
41
+ end.join(', ')
42
+ end
43
+
44
+ private
45
+
46
+ MAXIMUM_SCREEN_WIDTH = 2560 * 2 # Physical resolution of 27" iMac (2016)
47
+ SCREEN_STEP = 100
48
+
49
+ # Taken from http://mydevice.io/devices/
50
+
51
+ # Phones
52
+ IPHONE = { css_width: 320, dpr: 1 }
53
+ IPHONE_4 = { css_width: 320, dpr: 2 }
54
+ IPHONE_6 = { css_width: 375, dpr: 2 }
55
+ LG_G3 = { css_width: 360, dpr: 4 }
56
+
57
+ # Phablets
58
+ IPHONE_6_PLUS = { css_width: 414, dpr: 3 }
59
+ IPHONE_6_PLUS_LANDSCAPE = { css_width: 736, dpr: 3 }
60
+ MOTO_NEXUS_6 = { css_width: 412, dpr: 3.5 }
61
+ MOTO_NEXUS_6_LANDSCAPE = { css_width: 690, dpr: 3.5 }
62
+ LUMIA_1520 = { css_width: 432, dpr: 2.5 }
63
+ LUMIA_1520_LANDSCAPE = { css_width: 768, dpr: 2.5 }
64
+ GALAXY_NOTE_3 = { css_width: 360, dpr: 3 }
65
+ GALAXY_NOTE_3_LANDSCAPE = { css_width: 640, dpr: 3 }
66
+ GALAXY_NOTE_4 = { css_width: 360, dpr: 4 }
67
+ GALAXY_NOTE_4_LANDSCAPE = { css_width: 640, dpr: 4 }
68
+
69
+ # Tablets
70
+ IPAD = { css_width: 768, dpr: 1 };
71
+ IPAD_LANDSCAPE = { css_width: 1024, dpr: 1 };
72
+ IPAD_3 = { css_width: 768, dpr: 2 };
73
+ IPAD_3_LANDSCAPE = { css_width: 1024, dpr: 2 };
74
+ IPAD_PRO = { css_width: 1024, dpr: 2 };
75
+ IPAD_PRO_LANDSCAPE = { css_width: 1366, dpr: 2 };
76
+
77
+ BOOTSTRAP_SM = { css_width: 576, dpr: 1 }
78
+ BOOTSTRAP_MD = { css_width: 720, dpr: 1 }
79
+ BOOTSTRAP_LG = { css_width: 940, dpr: 1 }
80
+ BOOTSTRAP_XL = { css_width: 1140, dpr: 1 }
81
+
82
+ def devices
83
+ phones + phablets + tablets + bootstrap_breaks
84
+ end
85
+
86
+ def bootstrap_breaks
87
+ breaks = [
88
+ BOOTSTRAP_SM,
89
+ BOOTSTRAP_MD,
90
+ BOOTSTRAP_LG,
91
+ BOOTSTRAP_XL
92
+ ]
93
+
94
+ breaks + breaks.map { |b| b[:dpr] = 2; b }
95
+ end
96
+
97
+ def phones
98
+ [
99
+ IPHONE,
100
+ IPHONE_4,
101
+ IPHONE_6,
102
+ LG_G3
103
+ ]
104
+ end
105
+
106
+ def phablets
107
+ [
108
+ IPHONE_6_PLUS,
109
+ IPHONE_6_PLUS_LANDSCAPE,
110
+ MOTO_NEXUS_6,
111
+ MOTO_NEXUS_6_LANDSCAPE,
112
+ LUMIA_1520,
113
+ LUMIA_1520_LANDSCAPE,
114
+ GALAXY_NOTE_3,
115
+ GALAXY_NOTE_3_LANDSCAPE,
116
+ GALAXY_NOTE_4,
117
+ GALAXY_NOTE_4_LANDSCAPE
118
+ ]
119
+ end
120
+
121
+ def tablets
122
+ [
123
+ IPAD,
124
+ IPAD_LANDSCAPE,
125
+ IPAD_3,
126
+ IPAD_3_LANDSCAPE,
127
+ IPAD_PRO,
128
+ IPAD_PRO_LANDSCAPE
129
+ ]
130
+ end
131
+
132
+ # Return the widths to generate given the input `sizes`
133
+ # attribute.
134
+ #
135
+ # @return {Array} An array of {Fixnum} instances representing the unique `srcset` URLs to generate.
136
+ def target_widths
137
+ min_screen_width_required = @options[:min_width] || SCREEN_STEP
138
+ max_screen_width_required = @options[:max_width] || MAXIMUM_SCREEN_WIDTH
139
+
140
+ (device_widths + screen_widths).select do |w|
141
+ w <= max_screen_width_required && w >= min_screen_width_required
142
+ end.compact.uniq.sort
143
+ end
144
+
145
+ def device_widths
146
+ devices.map do |device|
147
+ (device[:css_width] * device[:dpr]).round
148
+ end
149
+ end
150
+
151
+ # Generates an array of physical screen widths to represent
152
+ # the different potential viewport sizes.
153
+ #
154
+ # We step by `SCREEN_STEP` to give some sanity to the amount
155
+ # of widths we output.
156
+ #
157
+ # The upper bound is the widest known screen on the planet.
158
+ # @return {Array} An array of {Fixnum} instances
159
+ def screen_widths
160
+ (0..MAXIMUM_SCREEN_WIDTH).step(SCREEN_STEP).to_a + [MAXIMUM_SCREEN_WIDTH]
161
+ end
162
+ end
@@ -1,5 +1,5 @@
1
1
  module Imgix
2
2
  module Rails
3
- VERSION = "1.1.0"
3
+ VERSION = '2.0.0'
4
4
  end
5
5
  end
@@ -1,55 +1,18 @@
1
1
  require "imgix"
2
- require "imgix/rails/url_helper"
2
+ require "imgix/rails/image_tag"
3
+ require "imgix/rails/picture_tag"
3
4
 
4
5
  module Imgix
5
6
  module Rails
6
- module ViewHelper
7
+ module ViewHelper
7
8
  include UrlHelper
8
9
 
9
10
  def ix_image_tag(source, options={})
10
- source = replace_hostname(source)
11
- normal_opts = options.slice!(*available_parameters)
12
-
13
- image_tag(ix_image_url(source, options), normal_opts)
14
- end
15
-
16
- def ix_responsive_image_tag(source, options={})
17
- options.merge!({
18
- srcset: srcset_for(source, options)
19
- })
20
-
21
- ix_image_tag(source, options)
22
- end
23
-
24
- def ix_picture_tag(source, options={})
25
- content_tag(:picture) do
26
- concat(tag(:source, srcset: srcset_for(source, options)))
27
- concat(ix_image_tag(source, options))
28
- end
29
- end
30
-
31
- private
32
-
33
- def available_parameters
34
- @available_parameters ||= parameters.keys
35
- end
36
-
37
- def parameters
38
- path = File.expand_path("../../../../vendor/parameters.json", __FILE__)
39
- @parameters ||= JSON.parse(File.read(path), symbolize_names: true)[:parameters]
40
- end
41
-
42
- def srcset_for(source, options={})
43
- source = replace_hostname(source)
44
- configured_resolutions.map do |resolution|
45
- srcset_options = options.slice(*available_parameters)
46
- srcset_options[:dpr] = resolution unless resolution == 1
47
- "#{ix_image_url(source, srcset_options)} #{resolution}x"
48
- end.join(', ')
11
+ Imgix::Rails::ImageTag.new(source, options).render
49
12
  end
50
13
 
51
- def configured_resolutions
52
- ::Imgix::Rails.config.imgix[:responsive_resolutions] || [1, 2]
14
+ def ix_picture_tag(source, picture_tag_options:, imgix_default_options:, breakpoints:)
15
+ Imgix::Rails::PictureTag.new(source, picture_tag_options, imgix_default_options, breakpoints).render
53
16
  end
54
17
  end
55
18
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imgix-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kelly Sutton
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2016-02-25 00:00:00.000000000 Z
12
+ date: 2016-05-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: imgix
@@ -107,6 +107,9 @@ files:
107
107
  - bin/setup
108
108
  - imgix-rails.gemspec
109
109
  - lib/imgix/rails.rb
110
+ - lib/imgix/rails/image_tag.rb
111
+ - lib/imgix/rails/picture_tag.rb
112
+ - lib/imgix/rails/tag.rb
110
113
  - lib/imgix/rails/url_helper.rb
111
114
  - lib/imgix/rails/version.rb
112
115
  - lib/imgix/rails/view_helper.rb