sprite-factory-custom 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/Gemfile +12 -0
- data/LICENSE +20 -0
- data/README.md +351 -0
- data/RELEASE_NOTES.md +60 -0
- data/Rakefile +73 -0
- data/bin/sf +57 -0
- data/lib/sprite_factory/layout/horizontal.rb +44 -0
- data/lib/sprite_factory/layout/packed.rb +118 -0
- data/lib/sprite_factory/layout/vertical.rb +44 -0
- data/lib/sprite_factory/library/chunky_png.rb +31 -0
- data/lib/sprite_factory/library/image_magick.rb +74 -0
- data/lib/sprite_factory/library/rmagick.rb +32 -0
- data/lib/sprite_factory/runner.rb +287 -0
- data/lib/sprite_factory/style.rb +74 -0
- data/lib/sprite_factory.rb +85 -0
- data/sprite_factory.gemspec +27 -0
- data/test/images/custom/custom.css +4 -0
- data/test/images/custom/running.png +0 -0
- data/test/images/custom/stopped.png +0 -0
- data/test/images/empty/readme.txt +1 -0
- data/test/images/formats/alice.gif +0 -0
- data/test/images/formats/codeincomplete.ico +0 -0
- data/test/images/formats/github.ico +0 -0
- data/test/images/formats/monkey.gif +0 -0
- data/test/images/formats/spies.jpg +0 -0
- data/test/images/formats/stackoverflow.ico +0 -0
- data/test/images/formats/thief.png +0 -0
- data/test/images/hover/div.bar__img.icon--active.png +0 -0
- data/test/images/hover/div.bar__img.icon--focus.png +0 -0
- data/test/images/hover/div.bar__img.icon--hover.png +0 -0
- data/test/images/hover/div.bar__img.icon--link.png +0 -0
- data/test/images/hover/div.bar__img.icon--visited.png +0 -0
- data/test/images/hover/div.bar__img.icon.png +0 -0
- data/test/images/hover/div.foo__img.icon--active.png +0 -0
- data/test/images/hover/div.foo__img.icon--focus.png +0 -0
- data/test/images/hover/div.foo__img.icon--hover.png +0 -0
- data/test/images/hover/div.foo__img.icon--link.png +0 -0
- data/test/images/hover/div.foo__img.icon--visited.png +0 -0
- data/test/images/hover/div.foo__img.icon.png +0 -0
- data/test/images/irregular/irregular1.png +0 -0
- data/test/images/irregular/irregular2.png +0 -0
- data/test/images/irregular/irregular3.png +0 -0
- data/test/images/irregular/irregular4.png +0 -0
- data/test/images/irregular/irregular5.png +0 -0
- data/test/images/irregular/readme.txt +2 -0
- data/test/images/reference/custom.css +22 -0
- data/test/images/reference/custom.png +0 -0
- data/test/images/reference/formats.css +28 -0
- data/test/images/reference/formats.png +0 -0
- data/test/images/reference/hover.css +38 -0
- data/test/images/reference/hover.png +0 -0
- data/test/images/reference/index.html +182 -0
- data/test/images/reference/irregular.css +24 -0
- data/test/images/reference/irregular.fixed.css +24 -0
- data/test/images/reference/irregular.fixed.png +0 -0
- data/test/images/reference/irregular.horizontal.css +24 -0
- data/test/images/reference/irregular.horizontal.png +0 -0
- data/test/images/reference/irregular.margin.css +24 -0
- data/test/images/reference/irregular.margin.png +0 -0
- data/test/images/reference/irregular.packed.css +24 -0
- data/test/images/reference/irregular.packed.png +0 -0
- data/test/images/reference/irregular.padded.css +24 -0
- data/test/images/reference/irregular.padded.png +0 -0
- data/test/images/reference/irregular.png +0 -0
- data/test/images/reference/irregular.sassy.css +38 -0
- data/test/images/reference/irregular.sassy.png +0 -0
- data/test/images/reference/irregular.sassy.sass +40 -0
- data/test/images/reference/irregular.vertical.css +24 -0
- data/test/images/reference/irregular.vertical.png +0 -0
- data/test/images/reference/regular.css +24 -0
- data/test/images/reference/regular.custom.css +24 -0
- data/test/images/reference/regular.custom.png +0 -0
- data/test/images/reference/regular.fixed.css +24 -0
- data/test/images/reference/regular.fixed.png +0 -0
- data/test/images/reference/regular.horizontal.css +24 -0
- data/test/images/reference/regular.horizontal.png +0 -0
- data/test/images/reference/regular.margin.css +24 -0
- data/test/images/reference/regular.margin.png +0 -0
- data/test/images/reference/regular.nocomments.css +5 -0
- data/test/images/reference/regular.nocomments.png +0 -0
- data/test/images/reference/regular.packed.css +24 -0
- data/test/images/reference/regular.packed.png +0 -0
- data/test/images/reference/regular.padded.css +24 -0
- data/test/images/reference/regular.padded.png +0 -0
- data/test/images/reference/regular.png +0 -0
- data/test/images/reference/regular.sassy.css +38 -0
- data/test/images/reference/regular.sassy.png +0 -0
- data/test/images/reference/regular.sassy.sass +40 -0
- data/test/images/reference/regular.vertical.css +24 -0
- data/test/images/reference/regular.vertical.png +0 -0
- data/test/images/reference/s.gif +0 -0
- data/test/images/reference/subfolders.css +24 -0
- data/test/images/reference/subfolders.png +0 -0
- data/test/images/regular/regular1.PNG +0 -0
- data/test/images/regular/regular2.PNG +0 -0
- data/test/images/regular/regular3.PNG +0 -0
- data/test/images/regular/regular4.PNG +0 -0
- data/test/images/regular/regular5.PNG +0 -0
- data/test/images/subfolders/england/amy.png +0 -0
- data/test/images/subfolders/england/bob.png +0 -0
- data/test/images/subfolders/france/bob.png +0 -0
- data/test/images/subfolders/usa/amy.png +0 -0
- data/test/images/subfolders/usa/bob.png +0 -0
- data/test/integration_test.rb +167 -0
- data/test/layout/horizontal_test.rb +156 -0
- data/test/layout/packed_test.rb +283 -0
- data/test/layout/test_case.rb +56 -0
- data/test/layout/vertical_test.rb +156 -0
- data/test/library_test.rb +58 -0
- data/test/runner_test.rb +229 -0
- data/test/style_test.rb +72 -0
- data/test/test_case.rb +138 -0
- metadata +286 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8a81c8fe6af96b06771bb7f78ab64aaa536e4e4b
|
4
|
+
data.tar.gz: 148fe646cc3d9c81518a5b029b9d2027fb795663
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 60177384a302f97fa156797b768342a8897cb7c1e2f47b2745658d496fa46aa70d2c108f9f6038e08d33e0cd9286d103c122ef36a5540b98ce4a37e945a97672
|
7
|
+
data.tar.gz: 11daf41fed50c6e336c6ab4ba865d03684b8b9d0c56fce96abe653ec23135e0d033ed700a4d4a4d3d4b71ab2040d3f59888ec6921544617b2c02660a68032654
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011, 2012, 2013, 2014 Jake Gordon and contributors
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
20
|
+
|
data/README.md
ADDED
@@ -0,0 +1,351 @@
|
|
1
|
+
Sprite Factory (v1.6.0)
|
2
|
+
=======================
|
3
|
+
|
4
|
+
The sprite factory is a ruby library that can be used to generate
|
5
|
+
[CSS sprites](http://www.alistapart.com/articles/sprites). It combines
|
6
|
+
individual image files from a directory into a single unified sprite image
|
7
|
+
and creates an appropriate CSS stylesheet for use in your web application.
|
8
|
+
|
9
|
+
The library provides:
|
10
|
+
|
11
|
+
* both a ruby API and a command line script
|
12
|
+
* many customizable options
|
13
|
+
* support for multiple layout algorithms - horizontal, vertical or [packed](http://codeincomplete.com/posts/2011/5/7/bin_packing/)
|
14
|
+
* support for any stylesheet syntax, including [CSS](http://www.w3.org/Style/CSS/) and [Sass](http://sass-lang.com/).
|
15
|
+
* support for any image library, including [RMagick](http://rmagick.rubyforge.org/) and [ChunkyPNG](https://github.com/wvanbergen/chunky_png).
|
16
|
+
* support for any css selector style, including :hover pseudo-class selectors
|
17
|
+
* support for pngcrush'n the generated image file
|
18
|
+
* compatible with Rails 3.1 asset pipeline
|
19
|
+
|
20
|
+
|
21
|
+
Installation
|
22
|
+
============
|
23
|
+
|
24
|
+
$ gem install sprite-factory
|
25
|
+
|
26
|
+
An image library is also required. SpriteFactory comes with built in support for
|
27
|
+
[RMagick](http://rmagick.rubyforge.org/) or [ChunkyPng](https://github.com/wvanbergen/chunky_png).
|
28
|
+
|
29
|
+
RMagick is the most common image libary to use, installation instructions for ubuntu:
|
30
|
+
|
31
|
+
$ sudo aptitude install imageMagick libMagickWand-dev
|
32
|
+
$ sudo gem install rmagick
|
33
|
+
|
34
|
+
ChunkyPng is lighter weight but only supports .png format:
|
35
|
+
|
36
|
+
$ gem install chunky_png
|
37
|
+
|
38
|
+
SpriteFactory can also be easily extended to use the image library of your choice.
|
39
|
+
|
40
|
+
Usage
|
41
|
+
=====
|
42
|
+
|
43
|
+
Use the `sf` command line script specifying the location of your images.
|
44
|
+
|
45
|
+
$ sf images/icons
|
46
|
+
|
47
|
+
This will combine the individual image files within that directory and generate:
|
48
|
+
|
49
|
+
* images/icons.png
|
50
|
+
* images/icons.css
|
51
|
+
|
52
|
+
You can also use the SpriteFactory class directly from your own code:
|
53
|
+
|
54
|
+
require 'sprite_factory'
|
55
|
+
|
56
|
+
SpriteFactory.run!('images/icons')
|
57
|
+
|
58
|
+
The original image file name is used for the CSS class to show that image in HTML:
|
59
|
+
|
60
|
+
<img src='s.gif' class='high'> # e.g. original image was high.png
|
61
|
+
<img src='s.gif' class='medium'> # e.g. original image was medium.png
|
62
|
+
<img src='s.gif' class='low'> # e.g. original image was low.png
|
63
|
+
|
64
|
+
If original image files are included in sub-folders, the relative path
|
65
|
+
name will be used for the CSS class to show that image in HTML:
|
66
|
+
|
67
|
+
<img src='s.gif' class='other_high'> # e.g. original image was other/high.png
|
68
|
+
<img src='s.gif' class='other_medium'> # e.g. original image was other/medium.png
|
69
|
+
<img src='s.gif' class='other_low'> # e.g. original image was other/low.png
|
70
|
+
|
71
|
+
When using a framework such as Rails, you would usually DRY this up with a helper method:
|
72
|
+
|
73
|
+
def sprite_tag(name)
|
74
|
+
image_tag('s.gif', :class => name)
|
75
|
+
end
|
76
|
+
|
77
|
+
>> NOTE: `s.gif` is the traditional name of a 1x1 pixel transparent .gif used as a
|
78
|
+
dummy `src` when the true image comes from a css background attribute. Technically,
|
79
|
+
for css sprites, you could just use a `div` with a class instead of an `img`, but
|
80
|
+
to keep the markup semantic it is common to use an `img` tag with a dummy `src=s.gif`.
|
81
|
+
|
82
|
+
Customization
|
83
|
+
=============
|
84
|
+
|
85
|
+
Much of the behavior can be customized by overriding the following options:
|
86
|
+
|
87
|
+
- `:layout` - specify layout algorithm (horizontal, vertical or packed)
|
88
|
+
- `:style` - specify stylesheet syntax (css, scss or sass)
|
89
|
+
- `:library` - specify image library to use (rmagick or chunkypng)
|
90
|
+
- `:selector` - specify custom css selector (see below)
|
91
|
+
- `:cssurl` - specify custom css url (see below)
|
92
|
+
- `:output_image` - specify output location for generated image (default: <input folder>.png)
|
93
|
+
- `:output_style` - specify output location for generated stylesheet (default: <input folder>.<style>)
|
94
|
+
- `:pngcrush` - pngcrush the generated output image (if pngcrush is available)
|
95
|
+
- `:padding` - add padding to each sprite
|
96
|
+
- `:margin` - add margin to each sprite
|
97
|
+
- `:width` - fix width of each sprite to a specific size
|
98
|
+
- `:height` - fix height of each sprite to a specific size
|
99
|
+
- `:nocss` - suppress generation of output stylesheet (`run!` returns css content as a string instead)
|
100
|
+
- `:nocomments` - suppress generation of comments in output stylesheet
|
101
|
+
|
102
|
+
Options can be passed as command line arguments to the `sf` script:
|
103
|
+
|
104
|
+
$ sf images/icons --style sass --layout packed
|
105
|
+
|
106
|
+
Options can also be passed as the 2nd argument to the `#run!` method:
|
107
|
+
|
108
|
+
SpriteFactory.run!('images/icons', :style => :sass, :layout => :packed)
|
109
|
+
|
110
|
+
You can see the results of many of these options by viewing the sample page that
|
111
|
+
comes with the gem in `test/images/reference/index.html`.
|
112
|
+
|
113
|
+
>> NOTE: only the common options are available via the command line script (to keep it simple). Specifically,
|
114
|
+
the advanced `width`, `height`, and `nocss` options are only available via the Ruby interface.
|
115
|
+
|
116
|
+
>> NOTE: the `width`, `height` and `padding` options are not particularly useful - you would be better off just
|
117
|
+
making your source images have the correct dimensions by editing them appropriately in photoshop (or your editor of choice)
|
118
|
+
|
119
|
+
>> NOTE: the `margin` option is used primarily to buffer each image in the generated sprite with > 1px margin to
|
120
|
+
avoid images bleeding into each other when the browser needs to scale them (e.g. when user increases/decreases font size).
|
121
|
+
|
122
|
+
Layout
|
123
|
+
======
|
124
|
+
|
125
|
+
The generated image can be laid out in a horizontal or a vertical strip by
|
126
|
+
providing a `:layout` option (defaults to horizontal). A **new option in v1.2.0** is
|
127
|
+
to use a **:packed** layout which will attempt to generate an optimized packed
|
128
|
+
square-ish layout.
|
129
|
+
|
130
|
+
For more details on the bin-packing algorithm used:
|
131
|
+
|
132
|
+
* You can find a [description here](http://codeincomplete.com/posts/2011/5/7/bin_packing/)
|
133
|
+
* You can find a [demo here](http://codeincomplete.com/posts/2011/5/7/bin_packing/example/)
|
134
|
+
|
135
|
+
Customizing the CSS Selector
|
136
|
+
============================
|
137
|
+
|
138
|
+
By default, the CSS generated is fairly simple. It assumes you will be using `<img>`
|
139
|
+
elements for your sprites, and that the basename of each individual file is suitable for
|
140
|
+
use as a CSS classname. For example, the following files:
|
141
|
+
|
142
|
+
images/icons/high.png
|
143
|
+
images/icons/medium.png
|
144
|
+
images/icons/low.png
|
145
|
+
|
146
|
+
... when run with:
|
147
|
+
|
148
|
+
SpriteFactory.run!('images/icons')
|
149
|
+
|
150
|
+
... will generate the following css:
|
151
|
+
|
152
|
+
img.high { width: 16px; height: 16px; background: url(images/icons.png) 0px 0px no-repeat; }
|
153
|
+
img.medium { width: 16px; height: 16px; background: url(images/icons.png) -16px 0px no-repeat; }
|
154
|
+
img.low { width: 16px; height: 16px; background: url(images/icons.png) -32px 0px no-repeat; }
|
155
|
+
|
156
|
+
If you want to use different selectors for your rules, you can provide the `:selector` option. For
|
157
|
+
example:
|
158
|
+
|
159
|
+
SpriteFactory.run!('images/icons', :selector => 'span.icon_')
|
160
|
+
|
161
|
+
... will generate:
|
162
|
+
|
163
|
+
span.icon_high { width: 16px; height: 16px; background: url(images/icons.png) 0px 0px no-repeat; }
|
164
|
+
span.icon_medium { width: 16px; height: 16px; background: url(images/icons.png) -16px 0px no-repeat; }
|
165
|
+
span.icon_low { width: 16px; height: 16px; background: url(images/icons.png) -32px 0px no-repeat; }
|
166
|
+
|
167
|
+
Customizing the CSS Selector Per Image
|
168
|
+
======================================
|
169
|
+
|
170
|
+
If you want to specify a custom selector for each individual image, then name the image files
|
171
|
+
accordingly - the library will map '\_\_' (double underscore) to a single space ' ' in any source
|
172
|
+
image filename. For example:
|
173
|
+
|
174
|
+
images/icons/div.foo__span.icon_alert.png
|
175
|
+
images/icons/div.bar__span.icon_alert.png
|
176
|
+
|
177
|
+
... when run with:
|
178
|
+
|
179
|
+
SpriteFactory.run!('images/icons', :selector => 'div.example ')
|
180
|
+
|
181
|
+
... will generate:
|
182
|
+
|
183
|
+
div.example div.foo span.icon_alert { ... first file ... }
|
184
|
+
div.example div.bar span.icon_alert { ... second file ... }
|
185
|
+
|
186
|
+
|
187
|
+
If you want to specify a psuedo class such as `:hover` for some of your images, the library will also
|
188
|
+
map '--' (double dash) to a colon ':' in any source image filename. For example:
|
189
|
+
|
190
|
+
images/icons/alert.png
|
191
|
+
images/icons/alert--hover.png
|
192
|
+
|
193
|
+
... when run with:
|
194
|
+
|
195
|
+
SpriteFactory.run!('images/icons', :selector => 'span.icon_')
|
196
|
+
|
197
|
+
... will generate:
|
198
|
+
|
199
|
+
span.icon_alert { ... first file ... }
|
200
|
+
span.icon_alert:hover { ... second file ... }
|
201
|
+
|
202
|
+
Customizing the CSS Image Url
|
203
|
+
=============================
|
204
|
+
|
205
|
+
Within the generated CSS file, it can be tricky to get the correct path to your unified
|
206
|
+
sprite image. For example, you might be hosting your images on Amazon S3, or if you are
|
207
|
+
building a Ruby on Rails application you might need to generate URL's using the `#image_path`
|
208
|
+
helper method to ensure it gets the appropriate cache-busting query parameter.
|
209
|
+
|
210
|
+
By default, the SpriteFactory generates simple url's that contain the basename of the
|
211
|
+
unified sprite image, e.g:
|
212
|
+
|
213
|
+
SpriteFactory.run('icons')
|
214
|
+
|
215
|
+
# generates: url(icons.png)
|
216
|
+
|
217
|
+
...but you can control the generation of these url's using the `:cssurl` option:
|
218
|
+
|
219
|
+
For most CDN's, you can prepend a simple string to the image name:
|
220
|
+
|
221
|
+
SpriteFactory.run('icons',
|
222
|
+
:cssurl => "http://s3.amazonaws.com/")
|
223
|
+
|
224
|
+
# generates: url(http://s3.amazonaws.com/icons.png)
|
225
|
+
|
226
|
+
For more control, a simple token replacement can be performed using the $IMAGE token. For example, to generate calls
|
227
|
+
to custom Sass helper functions, such as those provided by [sass-rails](https://github.com/rails/sass-rails) plugin:
|
228
|
+
|
229
|
+
SpriteFactory.run('icons',
|
230
|
+
:cssurl => "image-url('$IMAGE')")
|
231
|
+
|
232
|
+
# generates: image-url('icons.png')
|
233
|
+
|
234
|
+
|
235
|
+
For full control, you can provide a lambda function and generate your own values:
|
236
|
+
|
237
|
+
SpriteFactory.run('icons',
|
238
|
+
:cssurl => lambda{|image| "url(#{image_path(image)})" })
|
239
|
+
|
240
|
+
# generates: url(/path/to/my/images/icons.png?v123456)
|
241
|
+
|
242
|
+
>> NOTE: the `:cssurl` option replaces `:csspath` from earlier versions. The previous option only let you
|
243
|
+
customize the path inside of the generated `url(...)`, while this new option allows you to customize the
|
244
|
+
entire value, including the outer `url(...)` itself.
|
245
|
+
|
246
|
+
Customizing the entire CSS output
|
247
|
+
=================================
|
248
|
+
|
249
|
+
If you want **complete** control over the generated styles, you can pass a block to the `run!` method.
|
250
|
+
|
251
|
+
The block will be provided with information about each image, including the generated css attributes.
|
252
|
+
Whatever content the block returns will be inserted into the generated css file.
|
253
|
+
|
254
|
+
SpriteFactory.run!('images/timer') do |images|
|
255
|
+
rules = []
|
256
|
+
rules << "div.running img.button { cursor: pointer; #{images[:running][:style]} }"
|
257
|
+
rules << "div.stopped img.button { cursor: pointer; #{images[:stopped][:style]} }"
|
258
|
+
rules.join("\n")
|
259
|
+
end
|
260
|
+
|
261
|
+
The `images` argument is a hash, where each key is the basename of an image file, and the
|
262
|
+
value is a hash of image metadata that includes the following:
|
263
|
+
|
264
|
+
* `:style` - the default generated style
|
265
|
+
* `:cssx` - the css sprite x position
|
266
|
+
* `:cssy` - the css sprite y position
|
267
|
+
* `:cssw` - the css sprite width
|
268
|
+
* `:cssh` - the css sprite height
|
269
|
+
* `:x` - the image x position
|
270
|
+
* `:y` - the image y position
|
271
|
+
* `:width` - the image width
|
272
|
+
* `:height` - the image height
|
273
|
+
|
274
|
+
>> NOTE: the image coords can differ form the css sprite coords when padding/margin or fixed width/height options are specified)
|
275
|
+
|
276
|
+
Using sprite-factory with the Rails asset pipeline
|
277
|
+
==================================================
|
278
|
+
|
279
|
+
The sprite-factory gem plays nice with the Rails asset pipeline with a few simple steps:
|
280
|
+
|
281
|
+
Add the sprite-factory to your Gemfile, including your chosen image library dependency:
|
282
|
+
|
283
|
+
group :assets do
|
284
|
+
gem 'sprite-factory', '>= 1.5.2'
|
285
|
+
gem 'rmagick'
|
286
|
+
end
|
287
|
+
|
288
|
+
Store your images in Rails 3.1 `app/assets/images` sub-folders, e.g
|
289
|
+
|
290
|
+
app/assets/images/avatars/*.png
|
291
|
+
app/assets/images/icons/*.png
|
292
|
+
...
|
293
|
+
|
294
|
+
Create a Rake task for regenerating your sprites, e.g. in `lib/tasks/assets.rake`
|
295
|
+
|
296
|
+
require 'sprite_factory'
|
297
|
+
|
298
|
+
namespace :assets do
|
299
|
+
desc 'recreate sprite images and css'
|
300
|
+
task :resprite => :environment do
|
301
|
+
SpriteFactory.cssurl = "image-url('$IMAGE')" # use a sass-rails helper method to be evaluated by the rails asset pipeline
|
302
|
+
SpriteFactory.run!('app/assets/images/avatars', :output_style => 'app/assets/stylesheets/avatars.css.erb')
|
303
|
+
SpriteFactory.run!('app/assets/images/icons', :output_style => 'app/assets/stylesheets/icons.css.erb')
|
304
|
+
# ... etc ...
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
Run the rake task
|
309
|
+
|
310
|
+
bundle exec rake assets:resprite
|
311
|
+
|
312
|
+
Generates
|
313
|
+
|
314
|
+
* sprite images in `app/assets/images`
|
315
|
+
* sprite styles in `app/assets/stylesheets` - automatically picked up by the asset pipeline and included in your generated application.css
|
316
|
+
|
317
|
+
You can find out more here:
|
318
|
+
|
319
|
+
* [Sprite Factory and the Rails Asset Pipeline](http://codeincomplete.com/posts/2011/8/6/sprite_factory_1_4_1/)
|
320
|
+
|
321
|
+
Extending the Library
|
322
|
+
=====================
|
323
|
+
|
324
|
+
The sprite factory library can be extended in a number of other ways.
|
325
|
+
|
326
|
+
* provide a custom layout algorithm in the `SpriteFactory::Layout` module.
|
327
|
+
* provide a custom style generator in the `SpriteFactory::Style` module.
|
328
|
+
* provide a custom image library in the `SpriteFactory::Library` module.
|
329
|
+
|
330
|
+
_(see existing code for examples of each)._
|
331
|
+
|
332
|
+
License
|
333
|
+
=======
|
334
|
+
|
335
|
+
See [LICENSE](https://github.com/jakesgordon/sprite-factory/blob/master/LICENSE) file.
|
336
|
+
|
337
|
+
Credits
|
338
|
+
=======
|
339
|
+
|
340
|
+
Thanks to my employer, [LiquidPlanner](http://liquidplanner.com) for allowing me to take this idea from our
|
341
|
+
online project management web application and release it into the wild.
|
342
|
+
|
343
|
+
Contact
|
344
|
+
=======
|
345
|
+
|
346
|
+
If you have any ideas, feedback, requests or bug reports, you can reach me at
|
347
|
+
[jake@codeincomplete.com](mailto:jake@codeincomplete.com), or via
|
348
|
+
my website: [Code inComplete](http://codeincomplete.com).
|
349
|
+
|
350
|
+
|
351
|
+
|
data/RELEASE_NOTES.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
March 16th 2014 - v1.6.0
|
2
|
+
------------------------
|
3
|
+
|
4
|
+
* Added raw ImageMagick driver can be used without RMagick gem (courtesy of @willglynn - Cheers!)
|
5
|
+
* Exposed `padding` and `margin` support to the cli interface (courtesy of @miguelgonz - Cheers!)
|
6
|
+
|
7
|
+
|
8
|
+
February 21st 2013 - v1.5.3
|
9
|
+
---------------------------
|
10
|
+
* bugfix: added back `:selector` when providing attributes for custom style generators (it was accidentally removed in v1.5.2)
|
11
|
+
|
12
|
+
January 13th 2013 - v1.5.2
|
13
|
+
--------------------------
|
14
|
+
* replaced `:csspath` option with `:cssurl` [issue #21](https://github.com/jakesgordon/sprite-factory/issues/21)
|
15
|
+
* ordered css rules by pseudoclass importance [issue #20](https://github.com/jakesgordon/sprite-factory/pull/20)
|
16
|
+
* added support for .ico files when using rmagick [issue #18](https://github.com/jakesgordon/sprite-factory/pull/18)
|
17
|
+
|
18
|
+
June 11th 2012 - v1.5.1
|
19
|
+
-----------------------
|
20
|
+
* added a new `:return => :images` option for callers that want access to the detailed `images` hash instead of the generated css content
|
21
|
+
|
22
|
+
May 10th 2012 - v1.5.0
|
23
|
+
----------------------
|
24
|
+
* @halida added a new `margin` option to (optionally) separate images in generated spritesheet to avoid 'bleeding' when browser scales the sprite (e.g. when user increases text size)
|
25
|
+
* added `padding` support for `packed` layout
|
26
|
+
* added `margin` support for `packed` layout
|
27
|
+
* added support for using source image filename as automatic css selector [issue #12](https://github.com/jakesgordon/sprite-factory/issues/12)
|
28
|
+
* added support for `:hover` (and other pseudo-class) selectors [issue #14](https://github.com/jakesgordon/sprite-factory/issues/14)
|
29
|
+
|
30
|
+
February 29th 2012 - v1.4.2
|
31
|
+
---------------------------
|
32
|
+
* added support for `:nocomments => true` to suppress comments in generated output stylesheet
|
33
|
+
* added support for images in subfolders - fixes [github issue #11](https://github.com/jakesgordon/sprite-factory/issues/11)
|
34
|
+
|
35
|
+
August 5th 2011 - v1.4.1
|
36
|
+
------------------------
|
37
|
+
* added support for `:style => :scss` to generate .scss file (even though content will be almost exactly same as .css style)
|
38
|
+
* deprecated `:output` option and replaced it with 2 new explicit `:output_image` and `:output_style` options
|
39
|
+
* updated RELEASE NOTES to include setup for use with Rails 3.1 asset pipeline
|
40
|
+
|
41
|
+
Auguest 5th 2011 - v1.4.0
|
42
|
+
-------------------------
|
43
|
+
* (not available)
|
44
|
+
|
45
|
+
July 9th 2011 - v1.3.0
|
46
|
+
----------------------
|
47
|
+
|
48
|
+
* source image file extensions now treated in case INsensitive manner (e.g. we detect both .PNG, .png and .Png)
|
49
|
+
* added `:nocss => true` option to suppress generation of output css file (caller should use `run!` return value instead - it contains the generated css content as a string)
|
50
|
+
|
51
|
+
May 8th 2011 - v1.2.0
|
52
|
+
---------------------
|
53
|
+
|
54
|
+
* added new `:layout => :packed` option to use bin-packing algorithm for generating rectangular sprite sheet
|
55
|
+
* added pngcrush support
|
56
|
+
|
57
|
+
April 29th 2011 - v1.0.0
|
58
|
+
------------------------
|
59
|
+
|
60
|
+
* original version
|
data/Rakefile
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
|
3
|
+
#------------------------------------------------------------------------------
|
4
|
+
|
5
|
+
Rake::TestTask.new do |t|
|
6
|
+
t.test_files = FileList['test/**/*_test.rb']
|
7
|
+
t.verbose = true
|
8
|
+
end
|
9
|
+
|
10
|
+
#------------------------------------------------------------------------------
|
11
|
+
|
12
|
+
desc "run a console with SpriteFactory loaded"
|
13
|
+
task :console do
|
14
|
+
system "irb -r #{File.expand_path('lib/sprite_factory', File.dirname(__FILE__))}"
|
15
|
+
end
|
16
|
+
|
17
|
+
#------------------------------------------------------------------------------
|
18
|
+
|
19
|
+
desc "regenerate test reference images"
|
20
|
+
task :reference do
|
21
|
+
|
22
|
+
require File.expand_path('lib/sprite_factory', File.dirname(__FILE__))
|
23
|
+
|
24
|
+
regenerate = lambda do |input, options = {}, &block|
|
25
|
+
output = options[:output] || input
|
26
|
+
SpriteFactory.run!(input, {:report => true}.merge(options), &block)
|
27
|
+
FileUtils.mv(output + "." + ( :png).to_s, 'test/images/reference')
|
28
|
+
FileUtils.mv(output + "." + (options[:style] || :css).to_s, 'test/images/reference')
|
29
|
+
end
|
30
|
+
|
31
|
+
regenerate.call('test/images/regular')
|
32
|
+
regenerate.call('test/images/regular', :output => 'test/images/regular.horizontal', :selector => 'img.horizontal_', :layout => :horizontal)
|
33
|
+
regenerate.call('test/images/regular', :output => 'test/images/regular.vertical', :selector => 'img.vertical_', :layout => :vertical)
|
34
|
+
regenerate.call('test/images/regular', :output => 'test/images/regular.packed', :selector => 'img.packed_', :layout => :packed, :padding => 10, :margin => 10)
|
35
|
+
regenerate.call('test/images/regular', :output => 'test/images/regular.padded', :selector => 'img.padded_', :padding => 10)
|
36
|
+
regenerate.call('test/images/regular', :output => 'test/images/regular.margin', :selector => 'img.margin_', :margin => 10)
|
37
|
+
regenerate.call('test/images/regular', :output => 'test/images/regular.fixed', :selector => 'img.fixed_', :width => 100, :height => 100)
|
38
|
+
regenerate.call('test/images/regular', :output => 'test/images/regular.sassy', :selector => 'img.sassy_', :style => :sass)
|
39
|
+
|
40
|
+
regenerate.call('test/images/irregular')
|
41
|
+
regenerate.call('test/images/irregular', :output => 'test/images/irregular.horizontal', :selector => 'img.horizontal_', :layout => :horizontal)
|
42
|
+
regenerate.call('test/images/irregular', :output => 'test/images/irregular.vertical', :selector => 'img.vertical_', :layout => :vertical)
|
43
|
+
regenerate.call('test/images/irregular', :output => 'test/images/irregular.packed', :selector => 'img.packed_', :layout => :packed, :padding => 10, :margin => 10)
|
44
|
+
regenerate.call('test/images/irregular', :output => 'test/images/irregular.padded', :selector => 'img.padded_', :padding => 10)
|
45
|
+
regenerate.call('test/images/irregular', :output => 'test/images/irregular.margin', :selector => 'img.margin_', :margin => 10)
|
46
|
+
regenerate.call('test/images/irregular', :output => 'test/images/irregular.fixed', :selector => 'img.fixed_', :width => 100, :height => 100)
|
47
|
+
regenerate.call('test/images/irregular', :output => 'test/images/irregular.sassy', :selector => 'img.sassy_', :style => :sass)
|
48
|
+
|
49
|
+
regenerate.call('test/images/hover', :output => 'test/images/hover', :selector => 'div.hover ', :style => :css)
|
50
|
+
|
51
|
+
regenerate.call('test/images/custom', :output => 'test/images/custom') do |images|
|
52
|
+
rules = []
|
53
|
+
rules << "div.running img.button { cursor: pointer; #{images[:running][:style]} }"
|
54
|
+
rules << "div.stopped img.button { cursor: pointer; #{images[:stopped][:style]} }"
|
55
|
+
rules.join("\n")
|
56
|
+
end
|
57
|
+
|
58
|
+
regenerate.call('test/images/formats', :library => :rmagick)
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
#------------------------------------------------------------------------------
|
63
|
+
|
64
|
+
desc "convert reference test sass files to css"
|
65
|
+
task :sass do
|
66
|
+
|
67
|
+
`sass 'test/images/reference/regular.sassy.sass' 'test/images/reference/regular.sassy.css'`
|
68
|
+
`sass 'test/images/reference/irregular.sassy.sass' 'test/images/reference/irregular.sassy.css'`
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
#------------------------------------------------------------------------------
|
73
|
+
|
data/bin/sf
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH.push File.expand_path("../lib", File.dirname(__FILE__)) # add sprite factory library to load path
|
4
|
+
|
5
|
+
require 'sprite_factory'
|
6
|
+
require 'optparse'
|
7
|
+
|
8
|
+
options = { :report => true }
|
9
|
+
op = OptionParser.new
|
10
|
+
op.banner = "#{SpriteFactory::DESCRIPTION}\nUsage: sprite <dir> [options]"
|
11
|
+
|
12
|
+
op.on("-h", "--help") do
|
13
|
+
puts op.to_s
|
14
|
+
exit
|
15
|
+
end
|
16
|
+
|
17
|
+
op.on("-v", "--version") do
|
18
|
+
puts SpriteFactory::VERSION
|
19
|
+
exit
|
20
|
+
end
|
21
|
+
|
22
|
+
layout_help = "specify layout orientation ( horizontal, vertical, packed )"
|
23
|
+
style_help = "specify stylesheet syntax ( css, scss, sass )"
|
24
|
+
library_help = "specify image library to use ( rmagic, chunkypng )"
|
25
|
+
selector_help = "specify custom selector to use for each css rule ( default: 'img.' )"
|
26
|
+
cssurl_help = "specify custom string to use for css image urls ( default: 'url(output image basename)' )"
|
27
|
+
output_image_help = "specify output location for generated image ( default: <input folder>.png )"
|
28
|
+
output_style_help = "specify output location for generated stylesheet ( default: <input folder>.<style>)"
|
29
|
+
pngcrush_help = "use pngcrush to optimize generated image"
|
30
|
+
padding_help = "add padding to each sprite"
|
31
|
+
margin_help = "add margin to each sprite"
|
32
|
+
nocomments_help = "suppress comments in generated stylesheet"
|
33
|
+
custom_styles_help = "Add custom styles for each sprites (E.g.: --custom-styles='display: inline-block;'"
|
34
|
+
|
35
|
+
op.on("--layout [ORIENTATION]", layout_help) {|value| options[:layout] = value }
|
36
|
+
op.on("--style [STYLE]", style_help) {|value| options[:style] = value }
|
37
|
+
op.on("--library [LIBRARY]", library_help) {|value| options[:library] = value }
|
38
|
+
op.on("--selector [SELECTOR]", selector_help) {|value| options[:selector] = value }
|
39
|
+
op.on("--cssurl [CSSURL]", cssurl_help) {|value| options[:cssurl] = value }
|
40
|
+
op.on("--output-image [PATH]", output_image_help) {|value| options[:output_image] = value }
|
41
|
+
op.on("--output-style [PATH]", output_style_help) {|value| options[:output_style] = value }
|
42
|
+
op.on("--custom-styles [STYLES]", custom_styles_help) {|value| options[:custom_style] = value }
|
43
|
+
op.on("--pngcrush", pngcrush_help) {|value| options[:pngcrush] = value }
|
44
|
+
op.on("--padding [PIXELS]", padding_help) {|value| options[:padding] = value.to_i }
|
45
|
+
op.on("--margin [PIXELS]", margin_help) {|value| options[:margin] = value.to_i }
|
46
|
+
op.on("--nocomments", nocomments_help) {|value| options[:nocomments] = true }
|
47
|
+
|
48
|
+
begin
|
49
|
+
op.parse!(ARGV)
|
50
|
+
raise "a single argument must be specified containing images to be sprited" if ARGV.empty?
|
51
|
+
SpriteFactory.run!(ARGV[0], options)
|
52
|
+
rescue Exception => ex
|
53
|
+
puts ex.message
|
54
|
+
exit
|
55
|
+
end
|
56
|
+
|
57
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module SpriteFactory
|
2
|
+
module Layout
|
3
|
+
module Horizontal
|
4
|
+
|
5
|
+
def self.layout(images, options = {})
|
6
|
+
width = options[:width]
|
7
|
+
height = options[:height]
|
8
|
+
hpadding = options[:hpadding] || 0
|
9
|
+
vpadding = options[:vpadding] || 0
|
10
|
+
hmargin = options[:hmargin] || 0
|
11
|
+
vmargin = options[:vmargin] || 0
|
12
|
+
max_height = height || (2 *(vpadding + vmargin) + images.map{|i| i[:height]}.max)
|
13
|
+
x = 0
|
14
|
+
images.each do |i|
|
15
|
+
|
16
|
+
if width
|
17
|
+
i[:cssw] = width
|
18
|
+
i[:cssx] = x
|
19
|
+
i[:x] = x + (width - i[:width]) / 2
|
20
|
+
else
|
21
|
+
i[:cssw] = i[:width] + (2 * hpadding) # image width plus padding
|
22
|
+
i[:cssx] = x + hmargin # anchored at x
|
23
|
+
i[:x] = i[:cssx] + hpadding # image drawn offset to account for padding
|
24
|
+
end
|
25
|
+
|
26
|
+
if height
|
27
|
+
i[:cssh] = height
|
28
|
+
i[:cssy] = 0
|
29
|
+
i[:y] = 0 + (height - i[:height]) / 2
|
30
|
+
else
|
31
|
+
i[:cssh] = i[:height] + (2 * vpadding) # image height plus padding
|
32
|
+
i[:cssy] = (max_height - i[:cssh]) / 2 # centered vertically
|
33
|
+
i[:y] = i[:cssy] + vpadding # image drawn offset to account for padding
|
34
|
+
end
|
35
|
+
|
36
|
+
x += i[:cssw] + 2 * hmargin
|
37
|
+
|
38
|
+
end
|
39
|
+
{ :width => x, :height => max_height }
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|