spriteful 0.0.5 → 0.1.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 +35 -1
- data/lib/spriteful/image.rb +25 -9
- data/lib/spriteful/sprite.rb +14 -13
- data/lib/spriteful/stylesheet.rb +11 -1
- data/lib/spriteful/stylesheets/template.css.erb +6 -0
- data/lib/spriteful/stylesheets/template.scss.erb +11 -0
- data/lib/spriteful/version.rb +1 -1
- data/spec/fixtures/svg/green.svg +37 -0
- data/spec/fixtures/svg/red.png +0 -0
- data/spec/image_spec.rb +17 -4
- data/spec/sprite_spec.rb +6 -6
- data/spec/stylesheet_spec.rb +27 -0
- metadata +24 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b498ca0bbb52dc394d82e7f70a97da8cc396e95
|
4
|
+
data.tar.gz: 12de0e904606ee2d3db4906ced8e4bf0aa83eae2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e750c5e844f876add52a6a778d7958014afb925d56df0cb444f59f7eb30d9020bd935366d1a698b64fa4f0a5e69f81ebaf83d346d24ef47c1dfba0ae14b10056
|
7
|
+
data.tar.gz: cc43b5640091d6985dcf178068521ae140041658668a9f0b3aa8d3976f8deaac4ff7c4db2703401787b870aa8e47058789612fd9c13e977c869bf031b7c9c4dc
|
data/README.md
CHANGED
@@ -55,7 +55,7 @@ spriteful images/icons -f scss
|
|
55
55
|
}
|
56
56
|
```
|
57
57
|
|
58
|
-
You can also choose to
|
58
|
+
You can also choose to generate the code using
|
59
59
|
[Mixin Directives](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#mixins).
|
60
60
|
|
61
61
|
```bash
|
@@ -71,6 +71,17 @@ spriteful images/icons -f scss --mixin
|
|
71
71
|
}
|
72
72
|
```
|
73
73
|
|
74
|
+
When using SCSS, the generated stylesheet will have a variable with a list of all images
|
75
|
+
inside the generated sprite, so you can hack own your own on top of that.
|
76
|
+
|
77
|
+
```scss
|
78
|
+
@each $image in $icons-sprite-names {
|
79
|
+
.my-class-for-#{$image} {
|
80
|
+
@extend %icons-sprite-#{$image};
|
81
|
+
}
|
82
|
+
}
|
83
|
+
```
|
84
|
+
|
74
85
|
### Multiple sprites
|
75
86
|
|
76
87
|
You can deal with multiple sprites in a single run. If `images/icons` has a set of images for one
|
@@ -110,6 +121,29 @@ images under `icons` will generate the `icons.png` and `icons.css` files. This c
|
|
110
121
|
enforces previsibility over generated files and helps when regenating existing sprites whenever
|
111
122
|
you need to add a new source to an existing sprite.
|
112
123
|
|
124
|
+
## SVG Support
|
125
|
+
|
126
|
+
Spriteful has a basic support for dealing with SVG images (and not only PNGs). SVG images
|
127
|
+
will be combined along the rest of your images and will be embedded directly on the final
|
128
|
+
Stylesheet in the data URI format. Using the `svg` root class (based on Modernizr), the
|
129
|
+
data URI will be used for browsers that support SVG images and the composed PNG will work
|
130
|
+
as a fallback for legacy browsers.
|
131
|
+
|
132
|
+
```css
|
133
|
+
.images.update-icon {
|
134
|
+
background-position: 0px -10px;
|
135
|
+
}
|
136
|
+
|
137
|
+
.svg .images.update-icon {
|
138
|
+
background-image: url('data:image/svg+xml;utf8, SVG XML goes here :)');
|
139
|
+
background-position: 0 0;
|
140
|
+
}
|
141
|
+
|
142
|
+
```
|
143
|
+
|
144
|
+
Future versions of Spriteful could have support for generating composed images as SVG files
|
145
|
+
(and not only PNG), so feel free to send a contribution improving the feature.
|
146
|
+
|
113
147
|
## Available options
|
114
148
|
|
115
149
|
* `--stylesheets` (`-s`) - Directory to save the generated stylesheet(s), instead of copying them to the clipboard.
|
data/lib/spriteful/image.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'svg_optimizer'
|
2
|
+
|
1
3
|
module Spriteful
|
2
4
|
# Internal: Data structure to represent the images that are part
|
3
5
|
# of a sprite.
|
@@ -20,24 +22,38 @@ module Spriteful
|
|
20
22
|
# Public: Gets/sets the left position of the image in a sprite.
|
21
23
|
attr_accessor :left
|
22
24
|
|
23
|
-
# Public: Gets the source '
|
25
|
+
# Public: Gets the source 'Magick::Image'.
|
24
26
|
attr_reader :source
|
25
27
|
|
26
28
|
# Public: Initializes an Image, extracting the image
|
27
|
-
# metadata such as width and path supplied by an '
|
29
|
+
# metadata such as width and path supplied by an 'Magick::Image'
|
28
30
|
# object that was initialized from the real image blob.
|
29
31
|
#
|
30
|
-
#
|
31
|
-
|
32
|
-
|
33
|
-
@
|
34
|
-
@path = path
|
32
|
+
# magick_image - an 'Magick::Image' object.
|
33
|
+
def initialize(magick_image)
|
34
|
+
@source = magick_image
|
35
|
+
@path = magick_image.filename
|
35
36
|
@name = File.basename(@path)
|
36
|
-
@width =
|
37
|
-
@height =
|
37
|
+
@width = magick_image.columns
|
38
|
+
@height = magick_image.rows
|
38
39
|
|
39
40
|
@top = 0
|
40
41
|
@left = 0
|
41
42
|
end
|
43
|
+
|
44
|
+
# Public: Gets the source image contents.
|
45
|
+
#
|
46
|
+
# Returns a String.
|
47
|
+
def blob
|
48
|
+
@blob ||= SvgOptimizer.optimize(File.read(path))
|
49
|
+
end
|
50
|
+
|
51
|
+
# Public: detects if the source is a SVG image
|
52
|
+
# based on its path.
|
53
|
+
#
|
54
|
+
# Returns true or false.
|
55
|
+
def svg?
|
56
|
+
File.extname(@path) == '.svg'
|
57
|
+
end
|
42
58
|
end
|
43
59
|
end
|
data/lib/spriteful/sprite.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'RMagick'
|
2
2
|
|
3
3
|
module Spriteful
|
4
4
|
# Public: the 'Sprite' class is responsible for combining a directory
|
@@ -40,7 +40,7 @@ module Spriteful
|
|
40
40
|
# :spacing - spacing in pixels that should be placed between
|
41
41
|
# the images in the sprite. Defaults to 0.
|
42
42
|
def initialize(source_dir, destination, options = {})
|
43
|
-
source_pattern = File.join(source_dir, '
|
43
|
+
source_pattern = File.join(source_dir, '*{.png,.svg}')
|
44
44
|
sources = Dir[source_pattern].sort
|
45
45
|
|
46
46
|
if sources.size == 0
|
@@ -53,8 +53,8 @@ module Spriteful
|
|
53
53
|
@name = File.basename(source_dir)
|
54
54
|
@filename = "#{name}.png"
|
55
55
|
@path = File.expand_path(File.join(destination, @filename))
|
56
|
-
|
57
|
-
@images = initialize_images(
|
56
|
+
@list = Magick::ImageList.new(*sources)
|
57
|
+
@images = initialize_images(@list)
|
58
58
|
|
59
59
|
@height, @width = detect_dimensions
|
60
60
|
end
|
@@ -64,11 +64,12 @@ module Spriteful
|
|
64
64
|
#
|
65
65
|
# Returns nothing.
|
66
66
|
def combine!
|
67
|
-
combined =
|
67
|
+
combined = Magick::Image.new(width, height)
|
68
|
+
combined.opacity = Magick::MaxRGB
|
68
69
|
@images.each do |image|
|
69
|
-
combined.
|
70
|
+
combined.composite!(image.source, image.left.abs, image.top.abs, Magick::SrcOverCompositeOp)
|
70
71
|
end
|
71
|
-
@blob = combined.to_blob
|
72
|
+
@blob = combined.to_blob { self.format = 'png' }
|
72
73
|
end
|
73
74
|
|
74
75
|
# Public: exposes the source images found in the 'source'
|
@@ -110,14 +111,14 @@ module Spriteful
|
|
110
111
|
# 'left' coordinates that the image will be placed
|
111
112
|
# in the sprite.
|
112
113
|
#
|
113
|
-
#
|
114
|
-
#
|
115
|
-
|
116
|
-
def initialize_images(sources)
|
114
|
+
# list - a 'RMagick::ImageList' of sources.
|
115
|
+
# Returns an Array
|
116
|
+
def initialize_images(list)
|
117
117
|
sprite_position = 0
|
118
118
|
images = []
|
119
|
-
|
120
|
-
|
119
|
+
|
120
|
+
list.to_a.each_with_index do |magick_image, index|
|
121
|
+
image = Image.new(magick_image)
|
121
122
|
|
122
123
|
if vertical?
|
123
124
|
image.top = sprite_position
|
data/lib/spriteful/stylesheet.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'pathname'
|
2
1
|
require 'erb'
|
2
|
+
require 'pathname'
|
3
3
|
|
4
4
|
module Spriteful
|
5
5
|
# Public: class responsible for putting together the CSS code
|
@@ -122,5 +122,15 @@ module Spriteful
|
|
122
122
|
path.relative_path_from(@destination)
|
123
123
|
end
|
124
124
|
end
|
125
|
+
|
126
|
+
# Internal: Gets an embeddable Data URI of the image if it
|
127
|
+
# is a SVG image.
|
128
|
+
#
|
129
|
+
# Returns a String.
|
130
|
+
def data_uri(image)
|
131
|
+
if image.svg?
|
132
|
+
%['data:image/svg+xml;utf8,#{image.blob.gsub(/\r?\n/, "")}']
|
133
|
+
end
|
134
|
+
end
|
125
135
|
end
|
126
136
|
end
|
@@ -21,4 +21,10 @@
|
|
21
21
|
.<%= class_name_for(sprite) %>.<%= class_name_for(image) %> {
|
22
22
|
background-position: <%= image.left %>px <%= image.top %>px;
|
23
23
|
}
|
24
|
+
<% if image.svg? %>
|
25
|
+
.svg .<%= class_name_for(sprite) %>.<%= class_name_for(image) %> {
|
26
|
+
background-image: url(<%= data_uri(image) %>);
|
27
|
+
background-position: 0 0;
|
28
|
+
}
|
29
|
+
<% end -%>
|
24
30
|
<% end %>
|
@@ -16,6 +16,9 @@
|
|
16
16
|
// <%= extension_strategy %><%= class_name_for(sprite) %>-sprite-<%= class_name_for(sprite.images.first) %>;
|
17
17
|
// // Your styles here.
|
18
18
|
// }
|
19
|
+
//
|
20
|
+
// There also will be available a variable named '$<%= class_name_for(sprite) %>-sprite-names'
|
21
|
+
// with all the images inside this sprite.
|
19
22
|
|
20
23
|
<%= extension_prefix %><%= class_name_for(sprite) %>-sprite {
|
21
24
|
<%- if rails? -%>
|
@@ -29,5 +32,13 @@
|
|
29
32
|
<%= extension_prefix %><%= class_name_for(sprite) %>-sprite-<%= class_name_for(image) %> {
|
30
33
|
<%= extension_strategy %><%= class_name_for(sprite) %>-sprite;
|
31
34
|
background-position: <%= image.left %>px <%= image.top %>px;
|
35
|
+
<%- if image.svg? %>
|
36
|
+
.svg & {
|
37
|
+
background-image: url(<%= data_uri(image) %>);
|
38
|
+
background-position: 0 0;
|
39
|
+
}
|
40
|
+
<%- end -%>
|
32
41
|
}
|
33
42
|
<% end %>
|
43
|
+
|
44
|
+
$<%= class_name_for(sprite) %>-sprite-names: <%= sprite.images.map { |i| class_name_for(i) }.join(' ') %>;
|
data/lib/spriteful/version.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
3
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
4
|
+
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
5
|
+
width="10px" height="10px" viewBox="0 0 10 10" enable-background="new 0 0 10 10" xml:space="preserve">
|
6
|
+
<rect fill="#39B54A" width="10" height="10"/>
|
7
|
+
<g>
|
8
|
+
</g>
|
9
|
+
<g>
|
10
|
+
</g>
|
11
|
+
<g>
|
12
|
+
</g>
|
13
|
+
<g>
|
14
|
+
</g>
|
15
|
+
<g>
|
16
|
+
</g>
|
17
|
+
<g>
|
18
|
+
</g>
|
19
|
+
<g>
|
20
|
+
</g>
|
21
|
+
<g>
|
22
|
+
</g>
|
23
|
+
<g>
|
24
|
+
</g>
|
25
|
+
<g>
|
26
|
+
</g>
|
27
|
+
<g>
|
28
|
+
</g>
|
29
|
+
<g>
|
30
|
+
</g>
|
31
|
+
<g>
|
32
|
+
</g>
|
33
|
+
<g>
|
34
|
+
</g>
|
35
|
+
<g>
|
36
|
+
</g>
|
37
|
+
</svg>
|
Binary file
|
data/spec/image_spec.rb
CHANGED
@@ -1,13 +1,26 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Spriteful::Image do
|
4
|
-
let(:
|
5
|
-
|
6
|
-
subject(:image) { Spriteful::Image.new(chunky_image, path) }
|
4
|
+
let(:source_image) { double('Magick Image', filename: 'path/to/image.png', columns: 10, rows: 5) }
|
5
|
+
subject(:image) { Spriteful::Image.new(source_image) }
|
7
6
|
|
8
7
|
it { expect(image.name).to eq('image.png') }
|
9
8
|
it { expect(image.path).to eq('path/to/image.png') }
|
10
9
|
it { expect(image.width).to eq(10) }
|
11
10
|
it { expect(image.height).to eq(5) }
|
12
|
-
it { expect(image.source).to eq(
|
11
|
+
it { expect(image.source).to eq(source_image) }
|
12
|
+
it { expect(image).to_not be_svg }
|
13
|
+
|
14
|
+
context 'SVG images' do
|
15
|
+
before do
|
16
|
+
source_image.stub(filename: 'spec/fixtures/svg/green.svg')
|
17
|
+
end
|
18
|
+
|
19
|
+
it { expect(image).to be_svg }
|
20
|
+
|
21
|
+
it 'returns the SVG XML as the #blob' do
|
22
|
+
xml = SvgOptimizer.optimize(File.read(source_image.filename))
|
23
|
+
expect(image.blob).to eq(xml)
|
24
|
+
end
|
25
|
+
end
|
13
26
|
end
|
data/spec/sprite_spec.rb
CHANGED
@@ -64,17 +64,17 @@ describe Spriteful::Sprite do
|
|
64
64
|
it 'combine images vertically by default' do
|
65
65
|
sprite = Spriteful::Sprite.new(source, destination)
|
66
66
|
sprite.combine!
|
67
|
-
image =
|
68
|
-
expect(image.
|
69
|
-
expect(image.
|
67
|
+
image = Magick::Image.from_blob(sprite.blob).first
|
68
|
+
expect(image.columns).to be(10)
|
69
|
+
expect(image.rows).to be(20)
|
70
70
|
end
|
71
71
|
|
72
72
|
it 'can combine images horizontally' do
|
73
73
|
sprite = Spriteful::Sprite.new(source, destination, horizontal: true)
|
74
74
|
sprite.combine!
|
75
|
-
image =
|
76
|
-
expect(image.
|
77
|
-
expect(image.
|
75
|
+
image = Magick::Image.from_blob(sprite.blob).first
|
76
|
+
expect(image.columns).to be(20)
|
77
|
+
expect(image.rows).to be(10)
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
data/spec/stylesheet_spec.rb
CHANGED
@@ -36,6 +36,14 @@ describe Spriteful::Stylesheet do
|
|
36
36
|
expect(output).to match(/@mixin simple-sprite-red \{/)
|
37
37
|
end
|
38
38
|
|
39
|
+
it 'renders a SCSS variable with the all the images in the sprite' do
|
40
|
+
sprite = Spriteful::Sprite.new(source, destination)
|
41
|
+
stylesheet = Spriteful::Stylesheet.new(sprite, destination, format: 'scss', mixin: true)
|
42
|
+
output = stylesheet.render
|
43
|
+
|
44
|
+
expect(output).to match(/\$simple-sprite-names\: blue red/)
|
45
|
+
end
|
46
|
+
|
39
47
|
it 'documents the Spriteful options used to generate the stylesheet' do
|
40
48
|
Spriteful.options = %w(one two three)
|
41
49
|
sprite = Spriteful::Sprite.new(source, destination)
|
@@ -44,5 +52,24 @@ describe Spriteful::Stylesheet do
|
|
44
52
|
|
45
53
|
expect(output).to match(/'spriteful one two three'/)
|
46
54
|
end
|
55
|
+
|
56
|
+
describe 'SVG support' do
|
57
|
+
let(:source) { File.expand_path('spec/fixtures/svg') }
|
58
|
+
|
59
|
+
it 'exposes an alternative class for browsers that support SVG' do
|
60
|
+
stylesheet = Spriteful::Stylesheet.new(sprite, destination, format: 'css')
|
61
|
+
output = stylesheet.render
|
62
|
+
|
63
|
+
expect(output).to match(/^.svg.green \{/)
|
64
|
+
expect(output).to match(/^.svg .svg.green \{/)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'extends the placeholder selectors for browsers that support SVG' do
|
68
|
+
stylesheet = Spriteful::Stylesheet.new(sprite, destination, format: 'scss')
|
69
|
+
output = stylesheet.render
|
70
|
+
|
71
|
+
expect(output).to match(/^ .svg & \{/)
|
72
|
+
end
|
73
|
+
end
|
47
74
|
end
|
48
75
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spriteful
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lucas Mazza
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-10-
|
11
|
+
date: 2013-10-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -31,19 +31,33 @@ dependencies:
|
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '2.0'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
|
-
name:
|
34
|
+
name: rmagick
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - ~>
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
39
|
+
version: 2.13.2
|
40
40
|
type: :runtime
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - ~>
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version:
|
46
|
+
version: 2.13.2
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: svg_optimizer
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
47
61
|
- !ruby/object:Gem::Dependency
|
48
62
|
name: rspec
|
49
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -106,6 +120,8 @@ files:
|
|
106
120
|
- lib/spriteful.rb
|
107
121
|
- spec/fixtures/simple/blue.png
|
108
122
|
- spec/fixtures/simple/red.png
|
123
|
+
- spec/fixtures/svg/green.svg
|
124
|
+
- spec/fixtures/svg/red.png
|
109
125
|
- spec/image_spec.rb
|
110
126
|
- spec/spec_helper.rb
|
111
127
|
- spec/sprite_spec.rb
|
@@ -131,13 +147,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
131
147
|
version: '0'
|
132
148
|
requirements: []
|
133
149
|
rubyforge_project:
|
134
|
-
rubygems_version: 2.0.
|
150
|
+
rubygems_version: 2.0.3
|
135
151
|
signing_key:
|
136
152
|
specification_version: 4
|
137
153
|
summary: ''
|
138
154
|
test_files:
|
139
155
|
- spec/fixtures/simple/blue.png
|
140
156
|
- spec/fixtures/simple/red.png
|
157
|
+
- spec/fixtures/svg/green.svg
|
158
|
+
- spec/fixtures/svg/red.png
|
141
159
|
- spec/image_spec.rb
|
142
160
|
- spec/spec_helper.rb
|
143
161
|
- spec/sprite_spec.rb
|