jakesgordon / sprite-factory Goto Github PK
View Code? Open in Web Editor NEWAutomatic CSS Sprite Generator
Home Page: http://codeincomplete.com/posts/2011/4/29/sprite_factory/
License: MIT License
Automatic CSS Sprite Generator
Home Page: http://codeincomplete.com/posts/2011/4/29/sprite_factory/
License: MIT License
What I really loved about merbjedi's sprite gem was that it could output sass mixins (https://github.com/merbjedi/sprite/) which enabled you to add images via :before or :after pseudo-elements. you could just add your mixin to it with +sprite('icons', 'arrow'), no need for extra-markup.
would that be hard to do with sprite-factory?
Sprite Factory looks really great, but I wonder how to best use it together with rails 3.1? :)
It would be nice to have a way to handle "hover" states for sprites. At the moment, I'm adopting a naming convention ("foobar_off.png" and "foobar_on.png"), with this customization :
SpriteFactory.run!('app/assets/images/sprite', :output_style => 'app/assets/stylesheets/sprite.css.erb') do |images|
rules = []
images.each do |k, v|
rules << ".#{k} { #{v[:style]} }"
if k.to_s =~ /_on$/
rules << ".#{k.to_s.gsub(/_on$/, '_off')}:hover { #{v[:style]} }"
end
end
rules.join("\n")
end
…but maybe this could be elegantly integrated into the package?
I was wondering what plans there were, if any, to turn this into a maven or gradle plugin.
I've just switched my webapp to using sprites generated with sprite-factory. It was a pleasant experience, so thank you :)
While doing all this, I noticed that the sf
script doesn't accept all the options offered by SpriteFactory, e.g. padding
, width
, height
. Perhaps you could either make a note in the README or update the sf
script.
I looked at various other Ruby spriting libraries. I found yours the easiest to use.
I discovered a problem when image filenames start with a number.
Sprite-factory generates css lines such as :
img.001_25 { width: 24px; height: 24px; background: url(<%= asset_path 'common.png' %>) -304px -193px no-repeat; }
It seems that in css2, class names can't start with a digit, so they need to be escaped e.g.
img.\30 01_25 { width: 24px; height: 24px; background: url(<%= asset_path 'common.png' %>) -304px -193px no-repeat; }
After doing this, I can use sprite_tag in the normal way
<%= sprite_tag( "001_25", :title => "Details", :alt => "" ) %>
Hello there,
In a Rails project, when running the resprite rake task, I get the following error:
rake aborted!
NoMethodError: undefined method 'opacity=' for 4013x148 DirectClass 16-bit:Magick::Image
/home/user/.gem/ruby/ruby/2.5.0/gems/sprite-factory-1.7.1/lib/sprite_factory/library/rmagick.rb:23:in 'create'
/home/user/.gem/ruby/ruby/2.5.0/gems/sprite-factory-1.7.1/lib/sprite_factory/runner.rb:243:in 'create_sprite'
/home/user/.gem/ruby/ruby/2.5.0/gems/sprite-factory-1.7.1/lib/sprite_factory/runner.rb:65:in 'run!'
/home/user/.gem/ruby/ruby/2.5.0/gems/sprite-factory-1.7.1/lib/sprite_factory.rb:14:in 'run!'
/home/user/path/to/project/lib/tasks/assets.rake:7:in 'block (2 levels) in <top (required)>'
/home/user/.gem/ruby/ruby/2.5.0/gems/rake-13.0.1/exe/rake:27:in '<top (required)>'
/home/user/.gem/ruby/gems/bundler-1.17.2/lib/bundler/cli/exec.rb:74:in 'load'
/home/user/.gem/ruby/gems/bundler-1.17.2/lib/bundler/cli/exec.rb:74:in 'kernel_load'
/home/user/.gem/ruby/gems/bundler-1.17.2/lib/bundler/cli/exec.rb:28:in 'run'
/home/user/.gem/ruby/gems/bundler-1.17.2/lib/bundler/cli.rb:463:in 'exec'
/home/user/.gem/ruby/gems/bundler-1.17.2/lib/bundler/vendor/thor/lib/thor/command.rb:27:in 'run'
/home/user/.gem/ruby/gems/bundler-1.17.2/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in 'invoke_command'
/home/user/.gem/ruby/gems/bundler-1.17.2/lib/bundler/vendor/thor/lib/thor.rb:387:in 'dispatch'
/home/user/.gem/ruby/gems/bundler-1.17.2/lib/bundler/cli.rb:27:in 'dispatch'
/home/user/.gem/ruby/gems/bundler-1.17.2/lib/bundler/vendor/thor/lib/thor/base.rb:466:in 'start'
/home/user/.gem/ruby/gems/bundler-1.17.2/lib/bundler/cli.rb:18:in 'start'
/home/user/.gem/ruby/gems/bundler-1.17.2/exe/bundle:30:in 'block in <top (required)>'
/home/user/.gem/ruby/gems/bundler-1.17.2/lib/bundler/friendly_errors.rb:124:in 'with_friendly_errors'
/home/user/.gem/ruby/gems/bundler-1.17.2/exe/bundle:22:in '<top (required)>'
/home/user/bin/bundle:23:in 'load'
/home/user/bin/bundle:23:in '<main>'
Tasks: TOP => assets:resprite
It happens with rmagick 4.0.0, but not with earlier versions of the gem.
Let me know if you need more information.
Many thanks!
When browsers zoom, sometimes a line of the previous image appears on top of the wanted image. I suggest adding a 1px margin around all images to prevent this ugly effect from happening.
Y.
RMagick is kind of heavy, so many developers use direct replacement https://github.com/probablycorey/mini_magick
Do you consider adding it in the future?
So by default we get this:
background: url(icons.png) -224px -268px no-repeat
When I really want to end up with:
background: image-url("icons.png") -224px -268px no-repeat
csspath
option only allows me to change what goes inside url()
. What options do I have besides manually search/replacing things?
Maybe some sort of postprocess option that takes a lambda and allows running gsub on the output?
Sprite factory uses a deprecated RMagick constant:
/home/micha/.rvm/gems/ruby-2.1.3/gems/sprite-factory-1.6.1/lib/sprite_factory/library/rmagick.rb:23:in `create'
Replacing it by
target.opacity = Magick::QuantumRange
fixes the issue.
on running the sf images/icon
command on my terminal i get this error
input must be a single director
y
Hey,
Great tool - thanks
Any way of auto detecting directory changes like http://compass-style.org/help/tutorials/spriting/ does?
Yours hopefully,
The README gives <img src="s.gif" name="high">
as an example of how to render a sprite in one's HTML. It wasn't clear what s.gif
was and I assumed it was the image generated by sprite-factory containing all the sprites. Only when I happened to look at the examples images did I realise it's a 1x1 pixel image.
Perhaps a quick note in the README would clarify this.
If you try to sprite a directory containing any images with the same basename, sprite-factory will only add the last of those images to the sprite and CSS.
For example:
/app/assets/images/sprites
-> /icons
-> /client.png
-> /titles
-> /client.png
Only /titles/client.png will be output in the sprite.
Even passing a block to run!
to generate custom CSS can't fix this.
This issue occurs because when SpriteFactory::Runner#style
is given a block to generate custom CSS, it creates a hash of images using image[:name]
, which is non-unique, so the last image with a non-unique name is used.
I can't think of a way to fix this without breaking backwards compatibility. For example, creating a hash using image[:filename]
instead of image[:name]
would cause the examples in the README to fail.
Basically this issue comes down to being able to namespace images by directory (eg /titles/icon.png
) instead of by filename (eg /titles-icon.png
).
Can you think of any good ways to tackle this?
Wouldn't be great if was an option when you can write selectors in filenames. Often I know how I will use image so why don't write selectors in filename?
`````` body__div#main_shit__ul__li__a.class.double-dragon--hover.pngor even with whitespace
body div#main_shit ul li a.class.double-dragon--hover.png````
We can pass an options like repeat-x ````.class(rx).png => .class{background-image:url(sprites.png) repeat-x}````
I don't know how to write this beautifully so it just idea yet. Below just sample code, but it works
def self.css(selector, name, attributes)
if selector == 'filename'
name = name.gsub(/--/,":")
name = name.gsub(/__/," ")
"#{name} { #{css_style(attributes)}; }"
else
"#{selector}#{name} { #{css_style(attributes)}; }"
end
end
instead of
.icon-top { width: 25px; height: 12px; background: url(arrow.png) -733px -589px no-repeat; }
.icon-top:hover { width: 25px; height: 12px; background: url(arrow.png) -703px -606px no-repeat;}
we can do optimization like this(only set background-position of :hover pseudo-class):
.icon-top { width: 25px; height: 12px; background: url(arrow.png) -733px -589px no-repeat; }
.icon-top:hover { background-position: -703px -606px ; }
This way, we can reduce a HTTP request(maybe a 304 response), and reduce the size of .css file.
I have a patch(see https://github.com/dongyuwei/sprite-factory/blob/master/lib/sprite_factory/style.rb ):
def self.generate(style_name, selector, path, images)
styles = []
images.each do |image|
if image[:filename].index("--hover")
attr = [
"background-position: #{-image[:cssx]}px #{-image[:cssy]}px"
]
else
attr = [
"width: #{image[:cssw]}px",
"height: #{image[:cssh]}px",
"background: url(#{path}) #{-image[:cssx]}px #{-image[:cssy]}px no-repeat"
]
end
image[:path] = path
image[:selector] = selector
image[:style] = send("#{style_name}_style", attr) # make pure style available for (optional) custom rule generators (see usage of yield inside Runner#style)
styles << send(style_name, selector, image[:name], attr)
end
styles << ""
styles.join("\n")
end
I'm trying to run
sf images/signup and get error 'input must be a single directory', kindly help me
What an excellent library! Was quite excited when I came across your effort here, but then quickly became disappointed when it appeared that perhaps it won't work too well for jruby scenarios when rmagick is needed. Do you have any suggestions when in a scenario such as needing to run with jruby vs native c?
Could be worth adding to the readme that s.gif is required in the images directory. Or automatically creating one on run!
there is another sprite creater:
https://github.com/flyerhzm/css_sprite
after start a server, it can automatically convert files, I think it is a good feature.
any idea?
I have 2 source images with 500x500 size, and I want to fix the width and height of each sprite images to 100, but get the following error:
image test1 does not fit within a fixed width of 100 (RuntimeError)
Seems this options is not working as expect.
I check the source code of this very useful library, found the error comes from here:
images.each do |i|
i[:name], i[:ext] = map_image_filename(i[:filename], input_path)
raise RuntimeError, "image #{i[:name]} does not fit within a fixed width of #{width}" if width && (width < i[:width])
raise RuntimeError, "image #{i[:name]} does not fit within a fixed height of #{height}" if height && (height < i[:height])
end
Only if the options's width or height is less than the width or height of the image, this error occurs, the correct logic maybe is more than .
So, I try to change the <
to >
, the generated sprites size is then correct, but the source image size is clipped
but not stretched
. Is this a bug?
When I run
bundle exec rake assets:resprite
on windows, I get the error :
C:/RailsInstaller/Ruby1.8.7/lib/ruby/gems/1.8/bin/rake: No such file or directory - which pngcrush
rake aborted!
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.empty?
I don't have pngcrush installed. Maybe testing for the pngcrush flag being false before running "which" could allow a workaround ?
Hi, I implemented SVG sprites in a fork of your project, but turns out I will go another direction with it. Still I thought to drop you a few lines and share the bit of work I did in case you find it helpful. To be clear my changes aren't production ready, there even more of an experiment, so you'll find no tests. Still it works mostly.. Perhaps some changes to the generation of the SASS/CSS could would be helpful.
So anyway, here it is, as is, without warranties or guarantees: https://github.com/SnijderC/sprite-factory/commit/09c519c4e91cba96696c42cbde2a989421598389 I can make an MR is you like.
Specifically, undefined local variable or method 'attributes' for SpriteFactory::Style:Module
Running Mac OS X 10.7 with sf 1.4.1
installed via gem
.
How do I rewrite this code to Sprite Factory?
$sprite: sprite-map("sprite/*.png", $spacing: 5px)
$sprite2x: sprite-map("sprite2x/*.png", $spacing: 10px)
=s($map1x: false, $map2x: false, $filename: false, $size: false, $image: true, $position: false, $repeat: false)
@if $map1x != false
@if $filename != false and $size == true
width: image-width(sprite-file($map1x, $filename))
height: image-height(sprite-file($map1x, $filename))
@if $filename != false and $image == true and $position == true
$ending: null
@if $repeat == 'x'
$ending: repeat-x
@else if $repeat == 'y'
$ending: repeat-y
@else if $repeat == 'no'
$ending: no-repeat
@else if $repeat != false
$ending: unquote($repeat)
@if $repeat != false
background: sprite-url($map1x) sprite-position($map1x, $filename) $ending
@else
background-image: sprite-url($map1x)
background-position: sprite-position($map1x, $filename)
@else
@if $image == true
background-image: sprite-url($map1x)
@if $position == true
background-position: sprite-position($map1x, $filename)
@if $repeat == 'x'
background-repeat: repeat-x
@else if $repeat == 'y'
background-repeat: repeat-y
@else if $repeat == 'no'
background-repeat: no-repeat
@else if $repeat != false
background-repeat: unquote($repeat)
@if $map2x != false
+retina
@if $image == true
background-image: sprite-url($map2x)
@if $position == true
@if $map1x != false
$pos: sprite-position($map2x, $filename)
@if sprite-position($map1x, $filename) != ((nth($pos, 1) / 2) (nth($pos, 2) / 2))
background-position: (nth($pos, 1) / 2) (nth($pos, 2) / 2)
@else
background-position: sprite-position($map2x, $filename)
@if $image == true
@if $map1x != false
background-size: (image-width(sprite-path($map2x)) / 2) (image-height(sprite-path($map2x)) / 2)
non-critical
sf fails with comparison of Array with Array failed
error if name of some image contains double dash "--" f.ex. prev--disabled.png
i use this command for sf:
sf --layout packed --library chunkypng --selector 'i.icon-' --cssurl '../img' --output-image img/sprites.png --output-style css/_sprites.stl --pngcrush img/sprites
Hi, I am about to package sprite-factory for fedora, but I am getting a few errors during the build:
+ ruby -rminitest/autorun -rrubygems -Ilib:test -
MiniTest::Unit::TestCase is now Minitest::Test. From /builddir/build/BUILD/sprite-factory-1.6.0/usr/share/gems/gems/sprite-factory-1.6.0/test/test_case.rb:5:in `<module:SpriteFactory>'
MiniTest::Unit::TestCase is now Minitest::Test. From /builddir/build/BUILD/sprite-factory-1.6.0/usr/share/gems/gems/sprite-factory-1.6.0/test/library_test.rb:3:in `<top (required)>'
MiniTest::Unit::TestCase is now Minitest::Test. From /builddir/build/BUILD/sprite-factory-1.6.0/usr/share/gems/gems/sprite-factory-1.6.0/test/integration_test.rb:4:in `<module:SpriteFactory>'
MiniTest::Unit::TestCase is now Minitest::Test. From /builddir/build/BUILD/sprite-factory-1.6.0/usr/share/gems/gems/sprite-factory-1.6.0/test/style_test.rb:4:in `<module:SpriteFactory>'
MiniTest::Unit::TestCase is now Minitest::Test. From /builddir/build/BUILD/sprite-factory-1.6.0/usr/share/gems/gems/sprite-factory-1.6.0/test/runner_test.rb:4:in `<module:SpriteFactory>'
Run options: --seed 53921
# Running:
.......FFwhich: no pngcrush in (/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin:/builddir/.local/bin:/builddir/bin)
............................F.....
Finished in 1.929278s, 22.2881 runs/s, 109.3674 assertions/s.
1) Failure:
SpriteFactory::LibraryTest#test_load_irregular_using_image_magick [/builddir/build/BUILD/sprite-factory-1.6.0/usr/share/gems/gems/sprite-factory-1.6.0/test/library_test.rb:22]:
- unexpected width at index 0.
Expected: 60
Actual: 0
2) Failure:
SpriteFactory::LibraryTest#test_create_using_chunkypng [/builddir/build/BUILD/sprite-factory-1.6.0/usr/share/gems/gems/sprite-factory-1.6.0/test/library_test.rb:37]:
generated image does not match pregenerated reference:
actual: test/images/regular.horizontal.png
expected: test/images/reference/regular.horizontal.png.
Expected: 0.0
Actual: 3.2189052864267654e-20
3) Failure:
SpriteFactory::RunnerTest#test_invalid_config [/builddir/build/BUILD/sprite-factory-1.6.0/usr/share/gems/gems/sprite-factory-1.6.0/test/runner_test.rb:133]:
[RuntimeError] exception expected, not
Class: <LocalJumpError>
Message: <"no block given (yield)">
---Backtrace---
-:11:in `assert_raise'
/builddir/build/BUILD/sprite-factory-1.6.0/usr/share/gems/gems/sprite-factory-1.6.0/test/test_case.rb:81:in `assert_runtime_error'
/builddir/build/BUILD/sprite-factory-1.6.0/usr/share/gems/gems/sprite-factory-1.6.0/test/runner_test.rb:133:in `test_invalid_config'
---------------
43 runs, 211 assertions, 3 failures, 0 errors, 0 skips
Note that we have minitest5 in Fedora so I run the test suite as:
# To run the test suite against minitest 5
ruby -rminitest/autorun -rrubygems -Ilib:test - << \EOF
module Kernel
alias orig_require require
remove_method :require
def require path
orig_require path unless path == 'test/unit'
end
end
module MiniTest::Assertions
def assert_raise(*exp)
assert_raises(*exp)
end
end
Test = Minitest
Dir.glob "./test/*_test.rb", &method(:require)
EOF
I'm using sprite-factory in my html like
<%= link_to sprite_tag( "navicons_001_45", :title => "Edit", :alt => "" ), ...) %>
How can I also use sprites in my existing css where I have e.g.
background-image: url(/assets/navicons/001_24.png);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.