spriteful 0.0.5 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|