artwork 0.3.2 → 0.4.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.
- checksums.yaml +4 -4
- data/README.md +33 -0
- data/lib/artwork/model.rb +7 -3
- data/lib/artwork/thumbnail.rb +16 -3
- data/lib/artwork/version.rb +1 -1
- data/spec/artwork/model_spec.rb +32 -7
- data/spec/artwork/thumbnail_spec.rb +55 -16
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eea1f0b27e394aabf472e48645693cb62f95df54
|
4
|
+
data.tar.gz: 493fdce70015ab3c194a9502542e43f08f3f8da8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 939897e270a6b5f0354763b544be4d9bd991c96021c3d0bc8921f749f9eb42e9830bf54cff7e31086dbedabf8b151a1dd59ff677c9607c8016ae63c20f803aed
|
7
|
+
data.tar.gz: 097fd8418344ae6ee63f5bc49e20e81b92d805381b57f8a484fd2f51b958e07733303b7ad1997490b8d7ecfcf9ae816f7c10b19468eaf85f80878a63f50658cc
|
data/README.md
CHANGED
@@ -101,6 +101,39 @@ the `artwork_tag` view helper. Example:
|
|
101
101
|
<%= artwork_tag @film, :board, :'1440x', :image => {:class => 'poster'} %>
|
102
102
|
<%= artwork_tag @gallery, :cover, :'900x' %>
|
103
103
|
|
104
|
+
## Thumb Selection Algorithm
|
105
|
+
|
106
|
+
The following criteria are taken into account for picking up the appropriate
|
107
|
+
thumb name:
|
108
|
+
|
109
|
+
- The `default_resolution` specified in the Artwork configuration file.
|
110
|
+
- The current resolition, approximated to the nearest largest supported
|
111
|
+
resolution.
|
112
|
+
- Whether or not the screen is retina.
|
113
|
+
- The width of the requested thumb size (e.g. `400` for `400x300_crop`).
|
114
|
+
- The label of the requested thumb (e.g. `crop` for `400x300_crop`); the label
|
115
|
+
will be ignored, if it is not specified, e.g. for `400x300` or `400x`. The
|
116
|
+
label will be locked to a blank one if the request is for a thumb like this:
|
117
|
+
`400x300_`.
|
118
|
+
- The aspect ratio of the requested thumb (e.g. `4/3` for `400x300_crop`); the
|
119
|
+
aspect ratio will be ignored if there is no height specified in the requested
|
120
|
+
thumb, e.g. for a request like `400x_crop`.
|
121
|
+
|
122
|
+
For a thumb to be returned as matching, all of the following must be true:
|
123
|
+
|
124
|
+
- It must me the smallest thumb which is still larger than the requested width,
|
125
|
+
scaled for the current resolution.
|
126
|
+
- If the requested thumb has a label (including a blank one, like in `400x_`),
|
127
|
+
the thumb must match the requested label.
|
128
|
+
- If the requested thumb specifies an aspect ratio, the matching thumb must
|
129
|
+
have the same aspect ratio, rounded to the second decimal. If no aspect ratio
|
130
|
+
is specified in the request, aspect ratio checks will not be performed.
|
131
|
+
- If the current device is a retina device, a retina thumb will be preferred.
|
132
|
+
If no retuna thumb exists, a non-retina one will be selected.
|
133
|
+
|
134
|
+
If no such thumb exist, the largest one will match.
|
135
|
+
|
136
|
+
|
104
137
|
## Contributing
|
105
138
|
|
106
139
|
1. [Fork it](https://github.com/mitio/artwork/fork)
|
data/lib/artwork/model.rb
CHANGED
@@ -9,14 +9,17 @@ module Artwork
|
|
9
9
|
if desired_thumb.compatible?
|
10
10
|
desired_size = desired_thumb.width / ratio_for_current_resolution
|
11
11
|
|
12
|
-
thumbs = attachment_styles_for(attachment_name)
|
13
|
-
|
12
|
+
thumbs = attachment_styles_for(attachment_name).map { |thumb_name| Thumbnail.new(thumb_name) }
|
13
|
+
|
14
|
+
thumbs = thumbs \
|
14
15
|
.select(&:compatible?) \
|
15
16
|
.reject(&:retina?) \
|
17
|
+
.select { |thumb| desired_thumb.label.nil? or desired_thumb.label == thumb.label.to_s } \
|
18
|
+
.select { |thumb| desired_thumb.aspect_ratio.nil? or desired_thumb.same_aspect_ratio_with?(thumb) } \
|
16
19
|
.sort
|
17
20
|
|
18
21
|
thumbs.each do |thumb|
|
19
|
-
if desired_size <= thumb.width
|
22
|
+
if desired_size <= thumb.width
|
20
23
|
matching_thumb_name = thumb.name
|
21
24
|
break
|
22
25
|
end
|
@@ -25,6 +28,7 @@ module Artwork
|
|
25
28
|
# If we did not find any matching attachment definitions,
|
26
29
|
# the desired size is probably larger than all of our thumb widths,
|
27
30
|
# So pick the last (largest) one we have.
|
31
|
+
return nil if thumbs.empty?
|
28
32
|
matching_thumb_name ||= thumbs.last.name
|
29
33
|
end
|
30
34
|
|
data/lib/artwork/thumbnail.rb
CHANGED
@@ -2,20 +2,26 @@ module Artwork
|
|
2
2
|
class Thumbnail
|
3
3
|
include Comparable
|
4
4
|
|
5
|
-
NAME_PATTERN = /^(\d+)x(\w*?)(_2x)?$/i.freeze
|
5
|
+
NAME_PATTERN = /^(\d+)x(\d+)?((?!_2x)_\w*?)?(_2x)?$/i.freeze
|
6
6
|
|
7
7
|
attr :name
|
8
8
|
attr :width
|
9
|
+
attr :height
|
9
10
|
attr :label
|
11
|
+
attr :aspect_ratio
|
10
12
|
|
11
13
|
def initialize(name)
|
12
14
|
@name = name.to_s
|
13
15
|
|
14
16
|
if match = @name.match(NAME_PATTERN)
|
15
17
|
@width = match[1].to_i
|
16
|
-
@
|
17
|
-
@
|
18
|
+
@height = match[2].to_i
|
19
|
+
@label = match[3] ? match[3].gsub(/^_|_$/, '') : nil
|
20
|
+
@retina_flag = match[4]
|
18
21
|
end
|
22
|
+
|
23
|
+
@height = nil if @height == 0
|
24
|
+
@aspect_ratio = @width.to_f / @height if @height
|
19
25
|
end
|
20
26
|
|
21
27
|
def compatible?
|
@@ -26,6 +32,12 @@ module Artwork
|
|
26
32
|
@retina_flag == '_2x'
|
27
33
|
end
|
28
34
|
|
35
|
+
def same_aspect_ratio_with?(other_thumb)
|
36
|
+
return unless aspect_ratio and other_thumb.aspect_ratio
|
37
|
+
|
38
|
+
(0.0..0.1).include? (aspect_ratio - other_thumb.aspect_ratio).abs
|
39
|
+
end
|
40
|
+
|
29
41
|
def <=>(other_thumb)
|
30
42
|
width <=> other_thumb.width
|
31
43
|
end
|
@@ -33,6 +45,7 @@ module Artwork
|
|
33
45
|
def eq(other)
|
34
46
|
name == other.name and \
|
35
47
|
width == other.width and \
|
48
|
+
height == other.height and \
|
36
49
|
label == other.label and \
|
37
50
|
retina? == other.retina?
|
38
51
|
end
|
data/lib/artwork/version.rb
CHANGED
data/spec/artwork/model_spec.rb
CHANGED
@@ -23,6 +23,9 @@ module Artwork
|
|
23
23
|
:'320x500_2x' => '640x1000>',
|
24
24
|
:'320x500_crop' => '320x500#',
|
25
25
|
:'320x500_crop_2x' => '640x1000#',
|
26
|
+
:'400x500' => '400x500>',
|
27
|
+
:'400x500_2x' => '800x1000>',
|
28
|
+
:'320x_' => '320x>',
|
26
29
|
:unsupported => '100x100>'
|
27
30
|
},
|
28
31
|
},
|
@@ -46,6 +49,9 @@ module Artwork
|
|
46
49
|
:'320x500_2x',
|
47
50
|
:'320x500_crop',
|
48
51
|
:'320x500_crop_2x',
|
52
|
+
:'400x500',
|
53
|
+
:'400x500_2x',
|
54
|
+
:'320x_',
|
49
55
|
:unsupported,
|
50
56
|
]
|
51
57
|
end
|
@@ -137,7 +143,8 @@ module Artwork
|
|
137
143
|
end
|
138
144
|
|
139
145
|
it 'picks the nearest non-retina size to our desizred size' do
|
140
|
-
expect_thumb '
|
146
|
+
expect_thumb '390x', :'400x500'
|
147
|
+
expect_thumb '420x', :'640x'
|
141
148
|
end
|
142
149
|
|
143
150
|
it 'picks the largest available size if requesting a too large thumb' do
|
@@ -154,16 +161,34 @@ module Artwork
|
|
154
161
|
expect_thumb '200x_some_label', :'320x_some_label'
|
155
162
|
end
|
156
163
|
|
157
|
-
it '
|
158
|
-
expect_thumb
|
164
|
+
it 'considers the aspect ratio of the desired thumb' do
|
165
|
+
expect_thumb '320x499', :'320x500'
|
166
|
+
expect_thumb '319x498', :'320x500'
|
159
167
|
Artwork.load_2x_images = true
|
160
|
-
expect_thumb
|
168
|
+
expect_thumb '319x498', :'320x500_2x'
|
169
|
+
expect_thumb '319x498_crop', :'320x500_crop_2x'
|
170
|
+
Artwork.load_2x_images = false
|
171
|
+
expect_thumb '319x498_crop', :'320x500_crop'
|
161
172
|
end
|
162
173
|
|
163
|
-
it '
|
164
|
-
expect_thumb
|
174
|
+
it 'returns the largest thumb with the requested label if no other suitable sizes are found' do
|
175
|
+
expect_thumb '20000x_crop', :'320x500_crop'
|
165
176
|
Artwork.load_2x_images = true
|
166
|
-
expect_thumb
|
177
|
+
expect_thumb '20000x_crop', :'320x500_crop_2x'
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'returns the largest thumb with the requested aspect ratio if no other suitable sizes are found' do
|
181
|
+
expect_thumb '8000x10000', :'400x500'
|
182
|
+
Artwork.load_2x_images = true
|
183
|
+
expect_thumb '8000x10000', :'400x500_2x'
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'returns nil if no thumbnail matches the requested aspect ratio' do
|
187
|
+
expect_thumb '319x200', nil
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'returns nil if no thumbnail matches the requested label' do
|
191
|
+
expect_thumb '319x_nonexistant_label', nil
|
167
192
|
end
|
168
193
|
end
|
169
194
|
end
|
@@ -5,20 +5,23 @@ module Artwork
|
|
5
5
|
expected_defaults = {:compatible? => true}
|
6
6
|
|
7
7
|
examples = {
|
8
|
-
:'320x' => {:width => 320, :retina? => false, :label =>
|
9
|
-
:'320x_2x' => {:width => 320, :retina? => true, :label =>
|
10
|
-
:'640x_2x' => {:width => 640, :retina? => true, :label =>
|
11
|
-
:'640x' => {:width => 640, :retina? => false, :label =>
|
12
|
-
:'1280x' => {:width => 1280, :retina? => false, :label =>
|
13
|
-
:'1280x_2x' => {:width => 1280, :retina? => true, :label =>
|
14
|
-
:'2000x' => {:width => 2000, :retina? => false, :label =>
|
15
|
-
:'1500x_2x' => {:width => 1500, :retina? => true, :label =>
|
16
|
-
:'320x_some_label' => {:width => 320, :retina? => false, :label => 'some_label'},
|
17
|
-
:'320x_some_label_2x' => {:width => 320, :retina? => true, :label => 'some_label'},
|
18
|
-
:'320x500' => {:width => 320, :retina? => false, :label =>
|
19
|
-
:'320x500_2x' => {:width => 320, :retina? => true, :label =>
|
20
|
-
:'320x500_crop' => {:width => 320, :retina? => false, :label => '
|
21
|
-
:'320x500_crop_2x' => {:width => 320, :retina? => true, :label => '
|
8
|
+
:'320x' => {:width => 320, :height => nil, :retina? => false, :label => nil},
|
9
|
+
:'320x_2x' => {:width => 320, :height => nil, :retina? => true, :label => nil},
|
10
|
+
:'640x_2x' => {:width => 640, :height => nil, :retina? => true, :label => nil},
|
11
|
+
:'640x' => {:width => 640, :height => nil, :retina? => false, :label => nil},
|
12
|
+
:'1280x' => {:width => 1280, :height => nil, :retina? => false, :label => nil},
|
13
|
+
:'1280x_2x' => {:width => 1280, :height => nil, :retina? => true, :label => nil},
|
14
|
+
:'2000x' => {:width => 2000, :height => nil, :retina? => false, :label => nil},
|
15
|
+
:'1500x_2x' => {:width => 1500, :height => nil, :retina? => true, :label => nil},
|
16
|
+
:'320x_some_label' => {:width => 320, :height => nil, :retina? => false, :label => 'some_label'},
|
17
|
+
:'320x_some_label_2x' => {:width => 320, :height => nil, :retina? => true, :label => 'some_label'},
|
18
|
+
:'320x500' => {:width => 320, :height => 500, :retina? => false, :label => nil},
|
19
|
+
:'320x500_2x' => {:width => 320, :height => 500, :retina? => true, :label => nil},
|
20
|
+
:'320x500_crop' => {:width => 320, :height => 500, :retina? => false, :label => 'crop'},
|
21
|
+
:'320x500_crop_2x' => {:width => 320, :height => 500, :retina? => true, :label => 'crop'},
|
22
|
+
:'320x_' => {:width => 320, :height => nil, :retina? => false, :label => ''},
|
23
|
+
:'320x500_' => {:width => 320, :height => 500, :retina? => false, :label => ''},
|
24
|
+
:'320x500__2x' => {:width => 320, :height => 500, :retina? => true, :label => ''},
|
22
25
|
:unsupported => {:compatible? => false},
|
23
26
|
'unsupported_thumb' => {:compatible? => false},
|
24
27
|
}
|
@@ -39,18 +42,54 @@ module Artwork
|
|
39
42
|
end
|
40
43
|
|
41
44
|
describe '#eq' do
|
42
|
-
it 'is true for different objects with the same width, label and retina flag' do
|
45
|
+
it 'is true for different objects with the same width, height, label and retina flag' do
|
43
46
|
expect(Thumbnail.new(:'1200x500_crop_2x')).to eq Thumbnail.new('1200x500_crop_2x')
|
44
47
|
expect(Thumbnail.new(:'1200x_2x')).to eq Thumbnail.new('1200x_2x')
|
45
48
|
expect(Thumbnail.new(:'1200x')).to eq Thumbnail.new('1200x')
|
46
49
|
expect(Thumbnail.new(:'1200x_black_and_white')).to eq Thumbnail.new('1200x_black_and_white')
|
47
50
|
end
|
48
51
|
|
49
|
-
it 'is false for different objects if any of the width, label or retina flag differ' do
|
52
|
+
it 'is false for different objects if any of the width, height, label or retina flag differ' do
|
50
53
|
expect(Thumbnail.new(:'1200x500_crop_2x')).not_to eq Thumbnail.new('1200x500_crop')
|
51
54
|
expect(Thumbnail.new(:'1200x500_crop_2x')).not_to eq Thumbnail.new('1200x500crop_2x')
|
52
55
|
expect(Thumbnail.new(:'1200x500_crop_2x')).not_to eq Thumbnail.new('1201x500_crop_2x')
|
53
56
|
expect(Thumbnail.new(:'1200x500_crop_2x')).not_to eq Thumbnail.new('1500x')
|
57
|
+
expect(Thumbnail.new(:'1200x500_crop_2x')).not_to eq Thumbnail.new('1200x400_crop_2x')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#aspect_ratio' do
|
62
|
+
it 'is nil if height is not present or is zero' do
|
63
|
+
expect(Thumbnail.new('400x_label_2x').aspect_ratio).to be_nil
|
64
|
+
expect(Thumbnail.new('400x_2x').aspect_ratio).to be_nil
|
65
|
+
expect(Thumbnail.new('400x_').aspect_ratio).to be_nil
|
66
|
+
expect(Thumbnail.new('400x').aspect_ratio).to be_nil
|
67
|
+
expect(Thumbnail.new('400x0').aspect_ratio).to be_nil
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'is calculated as a decimal when both a width and a height are present' do
|
71
|
+
expect(Thumbnail.new('400x300').aspect_ratio).to be_within(0.1).of(1.33)
|
72
|
+
expect(Thumbnail.new('1600x900').aspect_ratio).to be_within(0.1).of(1.78)
|
73
|
+
expect(Thumbnail.new('1600x900_with_label').aspect_ratio).to be_within(0.1).of(1.78)
|
74
|
+
expect(Thumbnail.new('1600x900_with_label_2x').aspect_ratio).to be_within(0.1).of(1.78)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#same_aspect_ratio_with?' do
|
79
|
+
it 'returns nil if either thumbs have no clear height' do
|
80
|
+
expect(Thumbnail.new('400x300').same_aspect_ratio_with?(Thumbnail.new('400x'))).to be_nil
|
81
|
+
expect(Thumbnail.new('400x0').same_aspect_ratio_with?(Thumbnail.new('400x300'))).to be_nil
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'returns true if thumbs have aspect ratios within 0.1 of one another' do
|
85
|
+
expect(Thumbnail.new('400x300').same_aspect_ratio_with?(Thumbnail.new('400x300'))).to be true
|
86
|
+
expect(Thumbnail.new('400x300').same_aspect_ratio_with?(Thumbnail.new('1600x1200_with_label_2x'))).to be true
|
87
|
+
expect(Thumbnail.new('400x300').same_aspect_ratio_with?(Thumbnail.new('400x301'))).to be true
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'returns false if thumbs have different aspect ratios not within 0.1 of one another' do
|
91
|
+
expect(Thumbnail.new('400x300').same_aspect_ratio_with?(Thumbnail.new('400x200'))).to be false
|
92
|
+
expect(Thumbnail.new('400x300').same_aspect_ratio_with?(Thumbnail.new('5x10'))).to be false
|
54
93
|
end
|
55
94
|
end
|
56
95
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: artwork
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitar Dimitrov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|