sprite-factory 1.0.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.
- data/LICENSE +20 -0
- data/README.md +207 -0
- data/Rakefile +67 -0
- data/bin/sf +46 -0
- data/lib/sprite_factory.rb +51 -0
- data/lib/sprite_factory/layout.rb +89 -0
- data/lib/sprite_factory/library/chunky_png.rb +31 -0
- data/lib/sprite_factory/library/rmagick.rb +32 -0
- data/lib/sprite_factory/runner.rb +204 -0
- data/lib/sprite_factory/style.rb +58 -0
- data/sprite_factory.gemspec +24 -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/monkey.gif +0 -0
- data/test/images/formats/spies.jpg +0 -0
- data/test/images/formats/thief.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 +22 -0
- data/test/images/reference/formats.png +0 -0
- data/test/images/reference/index.html +135 -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.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.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/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/integration_test.rb +100 -0
- data/test/layout_test.rb +228 -0
- data/test/library_test.rb +57 -0
- data/test/runner_test.rb +156 -0
- data/test/style_test.rb +64 -0
- data/test/test_case.rb +127 -0
- metadata +159 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'chunky_png'
|
2
|
+
|
3
|
+
module SpriteFactory
|
4
|
+
module Library
|
5
|
+
module ChunkyPng
|
6
|
+
|
7
|
+
VALID_EXTENSIONS = :png
|
8
|
+
|
9
|
+
def self.load(files)
|
10
|
+
files.map do |filename|
|
11
|
+
image = ChunkyPNG::Image.from_file(filename)
|
12
|
+
{
|
13
|
+
:filename => filename,
|
14
|
+
:image => image,
|
15
|
+
:width => image.width,
|
16
|
+
:height => image.height
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.create(filename, images, width, height)
|
22
|
+
target = ChunkyPNG::Image.new(width, height, ChunkyPNG::Color::TRANSPARENT)
|
23
|
+
images.each do |image|
|
24
|
+
target.compose!(image[:image], image[:x], image[:y])
|
25
|
+
end
|
26
|
+
target.save(filename)
|
27
|
+
end
|
28
|
+
|
29
|
+
end # module ChunkyPng
|
30
|
+
end # module Library
|
31
|
+
end # module SpriteFactory
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'RMagick'
|
2
|
+
|
3
|
+
module SpriteFactory
|
4
|
+
module Library
|
5
|
+
module RMagick
|
6
|
+
|
7
|
+
VALID_EXTENSIONS = [:png, :jpg, :jpeg, :gif]
|
8
|
+
|
9
|
+
def self.load(files)
|
10
|
+
files.map do |filename|
|
11
|
+
image = Magick::Image.read(filename)[0]
|
12
|
+
{
|
13
|
+
:filename => filename,
|
14
|
+
:image => image,
|
15
|
+
:width => image.columns,
|
16
|
+
:height => image.rows
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.create(filename, images, width, height)
|
22
|
+
target = Magick::Image.new(width,height)
|
23
|
+
target.opacity = Magick::MaxRGB
|
24
|
+
images.each do |image|
|
25
|
+
target.composite!(image[:image], image[:x], image[:y], Magick::SrcOverCompositeOp)
|
26
|
+
end
|
27
|
+
target.write(filename)
|
28
|
+
end
|
29
|
+
|
30
|
+
end # module RMagick
|
31
|
+
end # module Library
|
32
|
+
end # module SpriteFactory
|
@@ -0,0 +1,204 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module SpriteFactory
|
4
|
+
class Runner
|
5
|
+
|
6
|
+
#----------------------------------------------------------------------------
|
7
|
+
|
8
|
+
attr :input
|
9
|
+
attr :config
|
10
|
+
|
11
|
+
def initialize(input, config = {})
|
12
|
+
@input = input.to_s[-1] == "/" ? input[0...-1] : input # gracefully ignore trailing slash on input directory name
|
13
|
+
@config = config
|
14
|
+
@config[:style] ||= SpriteFactory.style || :css
|
15
|
+
@config[:layout] ||= SpriteFactory.layout || :horizontal
|
16
|
+
@config[:library] ||= SpriteFactory.library || :rmagick
|
17
|
+
@config[:selector] ||= SpriteFactory.selector || 'img.'
|
18
|
+
@config[:csspath] ||= SpriteFactory.csspath
|
19
|
+
@config[:report] ||= SpriteFactory.report
|
20
|
+
end
|
21
|
+
|
22
|
+
#----------------------------------------------------------------------------
|
23
|
+
|
24
|
+
def run!(&block)
|
25
|
+
|
26
|
+
raise RuntimeError, "unknown layout #{layout_name}" if !Layout.respond_to?(layout_name)
|
27
|
+
raise RuntimeError, "unknown style #{style_name}" if !Style.respond_to?(style_name)
|
28
|
+
raise RuntimeError, "unknown library #{library_name}" if !Library.respond_to?(library_name)
|
29
|
+
|
30
|
+
raise RuntimeError, "input must be a single directory" if input.nil? || input.to_s.empty? || !File.directory?(input)
|
31
|
+
raise RuntimeError, "no output file specified" if output.nil? || output.to_s.empty?
|
32
|
+
raise RuntimeError, "no image files found" if image_files.empty?
|
33
|
+
|
34
|
+
raise RuntimeError, "set :width for fixed width, or :hpadding for horizontal padding, but not both." if width && !hpadding.zero?
|
35
|
+
raise RuntimeError, "set :height for fixed height, or :vpadding for vertical padding, but not both." if height && !vpadding.zero?
|
36
|
+
|
37
|
+
images = load_images
|
38
|
+
max = layout_images(images)
|
39
|
+
header = summary(images, max)
|
40
|
+
|
41
|
+
create_sprite(images, max[:width], max[:height])
|
42
|
+
|
43
|
+
css_file = File.open(output_style_file, "w+")
|
44
|
+
css_file.puts style_comment(header)
|
45
|
+
css_file.puts style(selector, css_path, images, &block)
|
46
|
+
css_file.puts IO.read(custom_style_file) if File.exists?(custom_style_file)
|
47
|
+
css_file.close
|
48
|
+
|
49
|
+
report(header)
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
#----------------------------------------------------------------------------
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def output
|
58
|
+
config[:output] || input
|
59
|
+
end
|
60
|
+
|
61
|
+
def selector
|
62
|
+
config[:selector]
|
63
|
+
end
|
64
|
+
|
65
|
+
def style_name
|
66
|
+
config[:style]
|
67
|
+
end
|
68
|
+
|
69
|
+
def layout_name
|
70
|
+
config[:layout]
|
71
|
+
end
|
72
|
+
|
73
|
+
def library_name
|
74
|
+
config[:library]
|
75
|
+
end
|
76
|
+
|
77
|
+
def hpadding
|
78
|
+
config[:hpadding] || config[:padding] || 0
|
79
|
+
end
|
80
|
+
|
81
|
+
def vpadding
|
82
|
+
config[:vpadding] || config[:padding] || 0
|
83
|
+
end
|
84
|
+
|
85
|
+
def width
|
86
|
+
config[:width]
|
87
|
+
end
|
88
|
+
|
89
|
+
def height
|
90
|
+
config[:height]
|
91
|
+
end
|
92
|
+
|
93
|
+
def output_image_file
|
94
|
+
"#{output}.png" if output
|
95
|
+
end
|
96
|
+
|
97
|
+
def output_style_file
|
98
|
+
"#{output}.#{style_name}" if output and style_name
|
99
|
+
end
|
100
|
+
|
101
|
+
def custom_style_file
|
102
|
+
File.join(input, File.basename(input) + ".#{style_name}")
|
103
|
+
end
|
104
|
+
|
105
|
+
def css_path
|
106
|
+
base = File.basename(output_image_file)
|
107
|
+
custom = config[:csspath]
|
108
|
+
if custom
|
109
|
+
if custom.is_a?(Proc)
|
110
|
+
custom.call(base) # allow custom path using a lambda
|
111
|
+
elsif custom.include?('$IMAGE')
|
112
|
+
custom.sub('$IMAGE', base) # allow custom path with token replacement
|
113
|
+
else
|
114
|
+
File.join(custom, base) # allow custom path with simple prepend
|
115
|
+
end
|
116
|
+
else
|
117
|
+
base # otherwise, just default to basename of the output image
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def image_files
|
122
|
+
return [] if input.nil?
|
123
|
+
valid_extensions = library::VALID_EXTENSIONS
|
124
|
+
expansions = Array(valid_extensions).map{|ext| File.join(input, "**", "*.#{ext}")}
|
125
|
+
Dir[*expansions].sort
|
126
|
+
end
|
127
|
+
|
128
|
+
#----------------------------------------------------------------------------
|
129
|
+
|
130
|
+
def library
|
131
|
+
@library ||= Library.send(library_name)
|
132
|
+
end
|
133
|
+
|
134
|
+
def load_images
|
135
|
+
images = library.load(image_files)
|
136
|
+
images.each do |i|
|
137
|
+
i[:name] = File.basename(i[:filename])
|
138
|
+
i[:ext] = File.extname(i[:name])
|
139
|
+
i[:name] = i[:name][0...-i[:ext].length] unless i[:ext].empty?
|
140
|
+
|
141
|
+
raise RuntimeError, "image #{i[:name]} does not fit within a fixed width of #{width}" if width && (width < i[:width])
|
142
|
+
raise RuntimeError, "image #{i[:name]} does not fit within a fixed height of #{height}" if height && (height < i[:height])
|
143
|
+
end
|
144
|
+
images
|
145
|
+
end
|
146
|
+
|
147
|
+
def create_sprite(images, width, height)
|
148
|
+
library.create(output_image_file, images, width, height)
|
149
|
+
end
|
150
|
+
|
151
|
+
#----------------------------------------------------------------------------
|
152
|
+
|
153
|
+
def layout_images(images)
|
154
|
+
Layout.send(layout_name, images, :width => width, :height => height, :hpadding => hpadding, :vpadding => vpadding)
|
155
|
+
end
|
156
|
+
|
157
|
+
#----------------------------------------------------------------------------
|
158
|
+
|
159
|
+
def style(selector, path, images, &block)
|
160
|
+
defaults = Style.generate(style_name, selector, path, images) # must call, even if custom block is given, because it stashes generated css style into image[:style] attributes
|
161
|
+
if block_given?
|
162
|
+
yield images.inject({}) {|h,i| h[i[:name].to_sym] = i; h} # provide custom rule builder a hash by image name
|
163
|
+
else
|
164
|
+
defaults
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def style_comment(comment)
|
169
|
+
Style.comment(style_name, comment)
|
170
|
+
end
|
171
|
+
|
172
|
+
#----------------------------------------------------------------------------
|
173
|
+
|
174
|
+
def summary(images, max)
|
175
|
+
return <<-EOF
|
176
|
+
|
177
|
+
Creating a sprite from following images:
|
178
|
+
\n#{images.map{|i| " #{report_path(i[:filename])} (#{i[:width]}x#{i[:height]})" }.join("\n")}
|
179
|
+
|
180
|
+
Output files:
|
181
|
+
#{report_path(output_image_file)}
|
182
|
+
#{report_path(output_style_file)}
|
183
|
+
|
184
|
+
Output size:
|
185
|
+
#{max[:width]}x#{max[:height]}
|
186
|
+
|
187
|
+
EOF
|
188
|
+
end
|
189
|
+
|
190
|
+
def report(msg)
|
191
|
+
puts msg if config[:report]
|
192
|
+
end
|
193
|
+
|
194
|
+
def report_path(path) # always report paths relative to . to avoid machine specific information in report (to avoid DIFF issues in tests and version control)
|
195
|
+
@cwd ||= Pathname.new(File.expand_path('.'))
|
196
|
+
path = Pathname.new(path)
|
197
|
+
path = path.relative_path_from(@cwd) if path.absolute?
|
198
|
+
path.to_s
|
199
|
+
end
|
200
|
+
|
201
|
+
#----------------------------------------------------------------------------
|
202
|
+
|
203
|
+
end # class Runner
|
204
|
+
end # module SpriteFactory
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module SpriteFactory
|
2
|
+
module Style
|
3
|
+
|
4
|
+
#----------------------------------------------------------------------------
|
5
|
+
|
6
|
+
def self.css(selector, name, attributes)
|
7
|
+
"#{selector}#{name} { #{css_style(attributes)}; }"
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.css_style(attributes)
|
11
|
+
attributes.join("; ")
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.css_comment(comment)
|
15
|
+
return "/*\n#{comment}\n*/"
|
16
|
+
end
|
17
|
+
|
18
|
+
#----------------------------------------------------------------------------
|
19
|
+
|
20
|
+
def self.sass(selector, name, attributes)
|
21
|
+
"#{selector}#{name}\n" + sass_style(attributes)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.sass_style(attributes)
|
25
|
+
attributes.map{|a| " #{a}"}.join("\n") + "\n"
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.sass_comment(comment)
|
29
|
+
return "/* #{comment.rstrip} */" # SASS has peculiar indenting requirements in order to recognise closing block comment
|
30
|
+
end
|
31
|
+
|
32
|
+
#----------------------------------------------------------------------------
|
33
|
+
|
34
|
+
def self.generate(style_name, selector, path, images)
|
35
|
+
styles = []
|
36
|
+
images.each do |image|
|
37
|
+
attr = [
|
38
|
+
"width: #{image[:cssw]}px",
|
39
|
+
"height: #{image[:cssh]}px",
|
40
|
+
"background: url(#{path}) #{-image[:cssx]}px #{-image[:cssy]}px no-repeat"
|
41
|
+
]
|
42
|
+
image[:style] = send("#{style_name}_style", attr) # make pure style available for (optional) custom rule generators (see usage of yield inside Runner#style)
|
43
|
+
styles << send(style_name, selector, image[:name], attr)
|
44
|
+
end
|
45
|
+
styles << ""
|
46
|
+
styles.join("\n")
|
47
|
+
end
|
48
|
+
|
49
|
+
#----------------------------------------------------------------------------
|
50
|
+
|
51
|
+
def self.comment(style_name, comment)
|
52
|
+
send("#{style_name}_comment", comment)
|
53
|
+
end
|
54
|
+
|
55
|
+
#----------------------------------------------------------------------------
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$LOAD_PATH.push File.expand_path("lib", File.dirname(__FILE__))
|
3
|
+
require 'sprite_factory'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
|
7
|
+
s.name = "sprite-factory"
|
8
|
+
s.version = SpriteFactory::VERSION
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ["Jake Gordon"]
|
11
|
+
s.email = ["jake@codeincomplete.com"]
|
12
|
+
s.homepage = "https://github.com/jakesgordon/sprite-factory"
|
13
|
+
s.summary = SpriteFactory::SUMMARY
|
14
|
+
s.description = SpriteFactory::DESCRIPTION
|
15
|
+
|
16
|
+
s.add_development_dependency 'rmagick'
|
17
|
+
s.add_development_dependency 'chunky_png'
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
|
+
s.require_paths = ["lib"]
|
23
|
+
|
24
|
+
end
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
this file is only here because git can't deal with empty directories (uck)
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,22 @@
|
|
1
|
+
/*
|
2
|
+
|
3
|
+
Creating a sprite from following images:
|
4
|
+
|
5
|
+
test/images/custom/running.png (46x25)
|
6
|
+
test/images/custom/stopped.png (46x25)
|
7
|
+
|
8
|
+
Output files:
|
9
|
+
test/images/custom.png
|
10
|
+
test/images/custom.css
|
11
|
+
|
12
|
+
Output size:
|
13
|
+
92x25
|
14
|
+
|
15
|
+
|
16
|
+
*/
|
17
|
+
div.running img.button { cursor: pointer; width: 46px; height: 25px; background: url(custom.png) 0px 0px no-repeat }
|
18
|
+
div.stopped img.button { cursor: pointer; width: 46px; height: 25px; background: url(custom.png) -46px 0px no-repeat }
|
19
|
+
div.running span.running { display: inline; }
|
20
|
+
div.running span.stopped { display: none; }
|
21
|
+
div.stopped span.running { display: none; }
|
22
|
+
div.stopped span.stopped { display: inline; }
|
Binary file
|
@@ -0,0 +1,22 @@
|
|
1
|
+
/*
|
2
|
+
|
3
|
+
Creating a sprite from following images:
|
4
|
+
|
5
|
+
test/images/formats/alice.gif (50x50)
|
6
|
+
test/images/formats/monkey.gif (50x50)
|
7
|
+
test/images/formats/spies.jpg (150x92)
|
8
|
+
test/images/formats/thief.png (50x50)
|
9
|
+
|
10
|
+
Output files:
|
11
|
+
test/images/formats.png
|
12
|
+
test/images/formats.css
|
13
|
+
|
14
|
+
Output size:
|
15
|
+
300x92
|
16
|
+
|
17
|
+
|
18
|
+
*/
|
19
|
+
img.alice { width: 50px; height: 50px; background: url(formats.png) 0px -21px no-repeat; }
|
20
|
+
img.monkey { width: 50px; height: 50px; background: url(formats.png) -50px -21px no-repeat; }
|
21
|
+
img.spies { width: 150px; height: 92px; background: url(formats.png) -100px 0px no-repeat; }
|
22
|
+
img.thief { width: 50px; height: 50px; background: url(formats.png) -250px -21px no-repeat; }
|
Binary file
|
@@ -0,0 +1,135 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset='utf-8' />
|
5
|
+
<title>Test page for sprite factory</title>
|
6
|
+
<link href='regular.css' rel='stylesheet' type='text/css' media='screen'></link>
|
7
|
+
<link href='regular.horizontal.css' rel='stylesheet' type='text/css' media='screen'></link>
|
8
|
+
<link href='regular.vertical.css' rel='stylesheet' type='text/css' media='screen'></link>
|
9
|
+
<link href='regular.padded.css' rel='stylesheet' type='text/css' media='screen'></link>
|
10
|
+
<link href='regular.fixed.css' rel='stylesheet' type='text/css' media='screen'></link>
|
11
|
+
<link href='regular.sassy.css' rel='stylesheet' type='text/css' media='screen'></link>
|
12
|
+
<link href='irregular.css' rel='stylesheet' type='text/css' media='screen'></link>
|
13
|
+
<link href='irregular.horizontal.css' rel='stylesheet' type='text/css' media='screen'></link>
|
14
|
+
<link href='irregular.vertical.css' rel='stylesheet' type='text/css' media='screen'></link>
|
15
|
+
<link href='irregular.padded.css' rel='stylesheet' type='text/css' media='screen'></link>
|
16
|
+
<link href='irregular.fixed.css' rel='stylesheet' type='text/css' media='screen'></link>
|
17
|
+
<link href='irregular.sassy.css' rel='stylesheet' type='text/css' media='screen'></link>
|
18
|
+
<link href='custom.css' rel='stylesheet' type='text/css' media='screen'></link>
|
19
|
+
<link href='formats.css' rel='stylesheet' type='text/css' media='screen'></link>
|
20
|
+
<style>
|
21
|
+
img { border: 1px solid red; }
|
22
|
+
</style>
|
23
|
+
</head>
|
24
|
+
<body>
|
25
|
+
|
26
|
+
<h1>Regular (defaults)</h1>
|
27
|
+
<img src='s.gif' class='regular1'>
|
28
|
+
<img src='s.gif' class='regular2'>
|
29
|
+
<img src='s.gif' class='regular3'>
|
30
|
+
<img src='s.gif' class='regular4'>
|
31
|
+
<img src='s.gif' class='regular5'>
|
32
|
+
|
33
|
+
<h1>Regular (horizontal)</h1>
|
34
|
+
<img src='s.gif' class='horizontal_regular1'>
|
35
|
+
<img src='s.gif' class='horizontal_regular2'>
|
36
|
+
<img src='s.gif' class='horizontal_regular3'>
|
37
|
+
<img src='s.gif' class='horizontal_regular4'>
|
38
|
+
<img src='s.gif' class='horizontal_regular5'>
|
39
|
+
|
40
|
+
<h1>Regular (vertical)</h1>
|
41
|
+
<img src='s.gif' class='vertical_regular1'><br>
|
42
|
+
<img src='s.gif' class='vertical_regular2'><br>
|
43
|
+
<img src='s.gif' class='vertical_regular3'><br>
|
44
|
+
<img src='s.gif' class='vertical_regular4'><br>
|
45
|
+
<img src='s.gif' class='vertical_regular5'><br>
|
46
|
+
|
47
|
+
<h1>Regular (padded)</h1>
|
48
|
+
<img src='s.gif' class='padded_regular1'>
|
49
|
+
<img src='s.gif' class='padded_regular2'>
|
50
|
+
<img src='s.gif' class='padded_regular3'>
|
51
|
+
<img src='s.gif' class='padded_regular4'>
|
52
|
+
<img src='s.gif' class='padded_regular5'>
|
53
|
+
|
54
|
+
<h1>Regular (fixed)</h1>
|
55
|
+
<img src='s.gif' class='fixed_regular1'>
|
56
|
+
<img src='s.gif' class='fixed_regular2'>
|
57
|
+
<img src='s.gif' class='fixed_regular3'>
|
58
|
+
<img src='s.gif' class='fixed_regular4'>
|
59
|
+
<img src='s.gif' class='fixed_regular5'>
|
60
|
+
|
61
|
+
<h1>Regular (sassy)</h1>
|
62
|
+
<img src='s.gif' class='sassy_regular1'>
|
63
|
+
<img src='s.gif' class='sassy_regular2'>
|
64
|
+
<img src='s.gif' class='sassy_regular3'>
|
65
|
+
<img src='s.gif' class='sassy_regular4'>
|
66
|
+
<img src='s.gif' class='sassy_regular5'>
|
67
|
+
|
68
|
+
<h1>Irregular (defaults)</h1>
|
69
|
+
<img src='s.gif' class='irregular1'>
|
70
|
+
<img src='s.gif' class='irregular2'>
|
71
|
+
<img src='s.gif' class='irregular3'>
|
72
|
+
<img src='s.gif' class='irregular4'>
|
73
|
+
<img src='s.gif' class='irregular5'>
|
74
|
+
|
75
|
+
<h1>Irregular (horizontal)</h1>
|
76
|
+
<img src='s.gif' class='horizontal_irregular1'>
|
77
|
+
<img src='s.gif' class='horizontal_irregular2'>
|
78
|
+
<img src='s.gif' class='horizontal_irregular3'>
|
79
|
+
<img src='s.gif' class='horizontal_irregular4'>
|
80
|
+
<img src='s.gif' class='horizontal_irregular5'>
|
81
|
+
|
82
|
+
<h1>Irregular (vertical)</h1>
|
83
|
+
<img src='s.gif' class='vertical_irregular1'><br>
|
84
|
+
<img src='s.gif' class='vertical_irregular2'><br>
|
85
|
+
<img src='s.gif' class='vertical_irregular3'><br>
|
86
|
+
<img src='s.gif' class='vertical_irregular4'><br>
|
87
|
+
<img src='s.gif' class='vertical_irregular5'><br>
|
88
|
+
|
89
|
+
<h1>Irregular (padded)</h1>
|
90
|
+
<img src='s.gif' class='padded_irregular1'>
|
91
|
+
<img src='s.gif' class='padded_irregular2'>
|
92
|
+
<img src='s.gif' class='padded_irregular3'>
|
93
|
+
<img src='s.gif' class='padded_irregular4'>
|
94
|
+
<img src='s.gif' class='padded_irregular5'>
|
95
|
+
|
96
|
+
<h1>Irregular (fixed)</h1>
|
97
|
+
<img src='s.gif' class='fixed_irregular1'>
|
98
|
+
<img src='s.gif' class='fixed_irregular2'>
|
99
|
+
<img src='s.gif' class='fixed_irregular3'>
|
100
|
+
<img src='s.gif' class='fixed_irregular4'>
|
101
|
+
<img src='s.gif' class='fixed_irregular5'>
|
102
|
+
|
103
|
+
<h1>Irregular (sassy)</h1>
|
104
|
+
<img src='s.gif' class='sassy_irregular1'>
|
105
|
+
<img src='s.gif' class='sassy_irregular2'>
|
106
|
+
<img src='s.gif' class='sassy_irregular3'>
|
107
|
+
<img src='s.gif' class='sassy_irregular4'>
|
108
|
+
<img src='s.gif' class='sassy_irregular5'>
|
109
|
+
|
110
|
+
<h1>Custom</h1>
|
111
|
+
<div class='running' id='timer'>
|
112
|
+
<img src='s.gif' class='button' onclick="SpriteFactory.toggleTimer();">
|
113
|
+
<span class='running'>running</span>
|
114
|
+
<span class='stopped'>stopped</span>
|
115
|
+
</div>
|
116
|
+
|
117
|
+
<h1>Other Formats</h1>
|
118
|
+
<img src='s.gif' class='alice'>
|
119
|
+
<img src='s.gif' class='monkey'>
|
120
|
+
<img src='s.gif' class='spies'>
|
121
|
+
<img src='s.gif' class='thief'>
|
122
|
+
|
123
|
+
<script>
|
124
|
+
SpriteFactory = {
|
125
|
+
toggleTimer: function() {
|
126
|
+
var timer = document.getElementById('timer');
|
127
|
+
if (timer) {
|
128
|
+
timer.setAttribute('class', timer.getAttribute('class') == 'running' ? 'stopped' : 'running');
|
129
|
+
}
|
130
|
+
}
|
131
|
+
}
|
132
|
+
</script>
|
133
|
+
|
134
|
+
</body>
|
135
|
+
</html>
|