Last active
November 15, 2018 09:48
-
-
Save rosenfeld/e756423e6eeba481888b to your computer and use it in GitHub Desktop.
Sprite generator to replace compass (only Ruby and ImageMagick are required)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This was created to replace compass in a Rails project. | |
The generator supports multiple themes and the sprite dimensions are available in a dimensions.sass file as variables. | |
There are no other dependencies than Ruby and ImageMagick binaries (or compatible commands with convert and identify). | |
The image name contains an MD5 hash of all images content and is stored directly into public/assets | |
so that the resulting CSS doesn't depend on sprockets. | |
It took about 0.2s to generate two theme sprites for me with about 30 images each. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require_relative 'sprite_generator' | |
['default', 'fancy'].each{|theme| SpriteGenerator.generate theme } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'fileutils' | |
class SpriteGenerator | |
def self.generate(theme) | |
new(theme).generate | |
end | |
def initialize(theme) | |
@theme = theme | |
end | |
def generate | |
create_sprite | |
compute_size_and_offset | |
FileUtils.rm_rf css_output_path | |
FileUtils.mkdir_p css_output_path | |
generate_css | |
generate_dimensions_sass_vars | |
end | |
private | |
def create_sprite | |
FileUtils.rm_rf output_path | |
FileUtils.mkdir_p output_path | |
`convert -append #{theme_path}/*.png #{output_path}/#{sprite_filename}` | |
end | |
def theme_path | |
@theme_path ||= "images/#{@theme}/theme" | |
end | |
def output_path | |
@output_path ||= "public/assets/#{@theme}" | |
end | |
def sprite_filename | |
@sprite_filename ||= "theme-#{checksum}.png" | |
end | |
def checksum | |
@checksum ||= `cat #{theme_path}/*.png|md5sum`.match(/(.*?)\s/)[1] | |
end | |
def compute_size_and_offset | |
dimensions = `identify -format "%wx%h,%t\\n" #{theme_path}/*.png` | |
@image_props = [] | |
offset = 0 | |
dimensions.split("\n").each do |d| | |
m = d.match /(\d+)x(\d+),(.*)/ | |
w, h, name = m[1..-1] | |
@image_props << [w.to_i, h = h.to_i, name, offset] | |
offset += h | |
end | |
end | |
def css_output_path | |
@css_output_path ||= "app/assets/stylesheets/themes/#{@theme}" | |
end | |
def generate_css | |
common_rules = [ | |
@image_props.map{|(w, h, name, offset)| ".#{name}"}.join(', '), | |
'{', | |
" background-image: url(/assets/#{@theme}/#{sprite_filename});", | |
' background-repeat: no-repeat;', | |
' display: inline-block;', | |
' border: 0;', | |
' background-color: transparent;', | |
'}', | |
].join "\n" | |
content = @image_props.map do |(w, h, name, offset)| | |
[ | |
".theme-#{name} {", | |
" height: #{h}px;", | |
" width: #{w}px;", | |
" background-position: 0 -#{offset}px;", | |
"}", | |
].join "\n" | |
end.join("\n") | |
File.write "#{css_output_path}/theme.css", "#{common_rules}\n\n#{content}" | |
end | |
def generate_dimensions_sass_vars | |
content = @image_props.map do |(w, h, name, offset)| | |
"$theme-#{name}-width: #{w}px;\n$theme-#{name}-height: #{h}px;\n" | |
end.join("\n") | |
File.write "#{css_output_path}/dimensions.sass", content | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment