sprite-factory-custom 1.6.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.
Files changed (115) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/Gemfile +12 -0
  4. data/LICENSE +20 -0
  5. data/README.md +351 -0
  6. data/RELEASE_NOTES.md +60 -0
  7. data/Rakefile +73 -0
  8. data/bin/sf +57 -0
  9. data/lib/sprite_factory/layout/horizontal.rb +44 -0
  10. data/lib/sprite_factory/layout/packed.rb +118 -0
  11. data/lib/sprite_factory/layout/vertical.rb +44 -0
  12. data/lib/sprite_factory/library/chunky_png.rb +31 -0
  13. data/lib/sprite_factory/library/image_magick.rb +74 -0
  14. data/lib/sprite_factory/library/rmagick.rb +32 -0
  15. data/lib/sprite_factory/runner.rb +287 -0
  16. data/lib/sprite_factory/style.rb +74 -0
  17. data/lib/sprite_factory.rb +85 -0
  18. data/sprite_factory.gemspec +27 -0
  19. data/test/images/custom/custom.css +4 -0
  20. data/test/images/custom/running.png +0 -0
  21. data/test/images/custom/stopped.png +0 -0
  22. data/test/images/empty/readme.txt +1 -0
  23. data/test/images/formats/alice.gif +0 -0
  24. data/test/images/formats/codeincomplete.ico +0 -0
  25. data/test/images/formats/github.ico +0 -0
  26. data/test/images/formats/monkey.gif +0 -0
  27. data/test/images/formats/spies.jpg +0 -0
  28. data/test/images/formats/stackoverflow.ico +0 -0
  29. data/test/images/formats/thief.png +0 -0
  30. data/test/images/hover/div.bar__img.icon--active.png +0 -0
  31. data/test/images/hover/div.bar__img.icon--focus.png +0 -0
  32. data/test/images/hover/div.bar__img.icon--hover.png +0 -0
  33. data/test/images/hover/div.bar__img.icon--link.png +0 -0
  34. data/test/images/hover/div.bar__img.icon--visited.png +0 -0
  35. data/test/images/hover/div.bar__img.icon.png +0 -0
  36. data/test/images/hover/div.foo__img.icon--active.png +0 -0
  37. data/test/images/hover/div.foo__img.icon--focus.png +0 -0
  38. data/test/images/hover/div.foo__img.icon--hover.png +0 -0
  39. data/test/images/hover/div.foo__img.icon--link.png +0 -0
  40. data/test/images/hover/div.foo__img.icon--visited.png +0 -0
  41. data/test/images/hover/div.foo__img.icon.png +0 -0
  42. data/test/images/irregular/irregular1.png +0 -0
  43. data/test/images/irregular/irregular2.png +0 -0
  44. data/test/images/irregular/irregular3.png +0 -0
  45. data/test/images/irregular/irregular4.png +0 -0
  46. data/test/images/irregular/irregular5.png +0 -0
  47. data/test/images/irregular/readme.txt +2 -0
  48. data/test/images/reference/custom.css +22 -0
  49. data/test/images/reference/custom.png +0 -0
  50. data/test/images/reference/formats.css +28 -0
  51. data/test/images/reference/formats.png +0 -0
  52. data/test/images/reference/hover.css +38 -0
  53. data/test/images/reference/hover.png +0 -0
  54. data/test/images/reference/index.html +182 -0
  55. data/test/images/reference/irregular.css +24 -0
  56. data/test/images/reference/irregular.fixed.css +24 -0
  57. data/test/images/reference/irregular.fixed.png +0 -0
  58. data/test/images/reference/irregular.horizontal.css +24 -0
  59. data/test/images/reference/irregular.horizontal.png +0 -0
  60. data/test/images/reference/irregular.margin.css +24 -0
  61. data/test/images/reference/irregular.margin.png +0 -0
  62. data/test/images/reference/irregular.packed.css +24 -0
  63. data/test/images/reference/irregular.packed.png +0 -0
  64. data/test/images/reference/irregular.padded.css +24 -0
  65. data/test/images/reference/irregular.padded.png +0 -0
  66. data/test/images/reference/irregular.png +0 -0
  67. data/test/images/reference/irregular.sassy.css +38 -0
  68. data/test/images/reference/irregular.sassy.png +0 -0
  69. data/test/images/reference/irregular.sassy.sass +40 -0
  70. data/test/images/reference/irregular.vertical.css +24 -0
  71. data/test/images/reference/irregular.vertical.png +0 -0
  72. data/test/images/reference/regular.css +24 -0
  73. data/test/images/reference/regular.custom.css +24 -0
  74. data/test/images/reference/regular.custom.png +0 -0
  75. data/test/images/reference/regular.fixed.css +24 -0
  76. data/test/images/reference/regular.fixed.png +0 -0
  77. data/test/images/reference/regular.horizontal.css +24 -0
  78. data/test/images/reference/regular.horizontal.png +0 -0
  79. data/test/images/reference/regular.margin.css +24 -0
  80. data/test/images/reference/regular.margin.png +0 -0
  81. data/test/images/reference/regular.nocomments.css +5 -0
  82. data/test/images/reference/regular.nocomments.png +0 -0
  83. data/test/images/reference/regular.packed.css +24 -0
  84. data/test/images/reference/regular.packed.png +0 -0
  85. data/test/images/reference/regular.padded.css +24 -0
  86. data/test/images/reference/regular.padded.png +0 -0
  87. data/test/images/reference/regular.png +0 -0
  88. data/test/images/reference/regular.sassy.css +38 -0
  89. data/test/images/reference/regular.sassy.png +0 -0
  90. data/test/images/reference/regular.sassy.sass +40 -0
  91. data/test/images/reference/regular.vertical.css +24 -0
  92. data/test/images/reference/regular.vertical.png +0 -0
  93. data/test/images/reference/s.gif +0 -0
  94. data/test/images/reference/subfolders.css +24 -0
  95. data/test/images/reference/subfolders.png +0 -0
  96. data/test/images/regular/regular1.PNG +0 -0
  97. data/test/images/regular/regular2.PNG +0 -0
  98. data/test/images/regular/regular3.PNG +0 -0
  99. data/test/images/regular/regular4.PNG +0 -0
  100. data/test/images/regular/regular5.PNG +0 -0
  101. data/test/images/subfolders/england/amy.png +0 -0
  102. data/test/images/subfolders/england/bob.png +0 -0
  103. data/test/images/subfolders/france/bob.png +0 -0
  104. data/test/images/subfolders/usa/amy.png +0 -0
  105. data/test/images/subfolders/usa/bob.png +0 -0
  106. data/test/integration_test.rb +167 -0
  107. data/test/layout/horizontal_test.rb +156 -0
  108. data/test/layout/packed_test.rb +283 -0
  109. data/test/layout/test_case.rb +56 -0
  110. data/test/layout/vertical_test.rb +156 -0
  111. data/test/library_test.rb +58 -0
  112. data/test/runner_test.rb +229 -0
  113. data/test/style_test.rb +72 -0
  114. data/test/test_case.rb +138 -0
  115. 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
@@ -0,0 +1,11 @@
1
+ *~
2
+ *.gem
3
+ .bundle
4
+ Gemfile.lock
5
+ pkg/*
6
+ *.swp
7
+ .sass-cache
8
+ test/images/*.png
9
+ test/images/*.css
10
+ test/images/*.sass
11
+ test/images/*.scss
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+
3
+ #
4
+ # NOTE: rmagick dependencies include:
5
+ #
6
+ # $ sudo apt-get install imagemagick
7
+ # $ sudo apt-get install libmagickwand-dev
8
+
9
+ group :development do
10
+ gem "chunky_png", "1.3.0"
11
+ gem "rmagick", "2.13.2"
12
+ end
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: &lt;input folder&gt;.png)
93
+ - `:output_style` - specify output location for generated stylesheet (default: &lt;input folder&gt;.&lt;style&gt;)
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