128 lines
3.2 KiB
Ruby
128 lines
3.2 KiB
Ruby
require 'chunky_png'
|
|
require 'lemonade/sprite_info.rb'
|
|
|
|
module Lemonade
|
|
@@sprites = {}
|
|
@@sprites_path = nil
|
|
@@images_path = nil
|
|
|
|
class << self
|
|
|
|
def sprites
|
|
@@sprites
|
|
end
|
|
|
|
def sprites_path
|
|
@@sprites_path || images_path
|
|
end
|
|
|
|
def sprites_path=(path)
|
|
@@sprites_path = path
|
|
end
|
|
|
|
def images_path
|
|
@@images_path || (defined?(Compass) ? Compass.configuration.images_path : 'public/images')
|
|
end
|
|
|
|
def images_path=(path)
|
|
@@images_path = path
|
|
end
|
|
|
|
def reset
|
|
@@sprites = {}
|
|
end
|
|
|
|
def generate_sprites
|
|
sprites.each do |sprite_name, sprite|
|
|
calculate_sprite sprite
|
|
if sprite_changed?(sprite_name, sprite)
|
|
generate_sprite_image sprite
|
|
remember_sprite_info! sprite_name, sprite
|
|
end
|
|
end
|
|
end
|
|
|
|
def extend_sass!
|
|
require 'sass'
|
|
require 'sass/plugin'
|
|
require File.expand_path('../lemonade/sass_functions', __FILE__)
|
|
require File.expand_path('../lemonade/sass_extension', __FILE__)
|
|
end
|
|
|
|
def sprite_changed?(sprite_name, sprite)
|
|
existing_sprite_info = YAML.load(File.read(sprite_info_file(sprite_name)))
|
|
existing_sprite_info[:sprite] != sprite or existing_sprite_info[:timestamps] != timestamps(sprite)
|
|
rescue
|
|
true
|
|
end
|
|
|
|
def remember_sprite_info!(sprite_name, sprite)
|
|
File.open(sprite_info_file(sprite_name), 'w') do |file|
|
|
file << {
|
|
:sprite => sprite,
|
|
:timestamps => timestamps(sprite),
|
|
}.to_yaml
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def sprite_info_file(sprite_name)
|
|
File.join(Lemonade.images_path, "#{sprite_name}.sprite_info.yml")
|
|
end
|
|
|
|
def timestamps(sprite)
|
|
result = {}
|
|
sprite[:images].each do |image|
|
|
file_name = image[:file]
|
|
result[file_name] = File.ctime(file_name)
|
|
end
|
|
result
|
|
end
|
|
|
|
def calculate_sprite(sprite)
|
|
width, margin_bottom, y = 0, 0, 0
|
|
sprite[:images].each do |sprite_item|
|
|
if sprite_item[:index] == 0
|
|
margin_top = 0
|
|
elsif sprite_item[:margin_top] > margin_bottom
|
|
margin_top = sprite_item[:margin_top]
|
|
else
|
|
margin_top = margin_bottom
|
|
end
|
|
y += margin_top
|
|
sprite_item[:y] = Sass::Script::Number.new(y, ['px'])
|
|
y += sprite_item[:height]
|
|
width = sprite_item[:width] if sprite_item[:width] > width
|
|
margin_bottom = sprite_item[:margin_bottom]
|
|
end
|
|
sprite[:height] = y
|
|
sprite[:width] = width
|
|
end
|
|
|
|
def generate_sprite_image(sprite)
|
|
sprite_image = ChunkyPNG::Image.new(sprite[:width], sprite[:height], ChunkyPNG::Color::TRANSPARENT)
|
|
sprite[:images].each do |sprite_item|
|
|
sprite_item_image = ChunkyPNG::Image.from_file(sprite_item[:file])
|
|
x = (sprite[:width] - sprite_item[:width]) * (sprite_item[:x].value / 100)
|
|
y = sprite_item[:y].value
|
|
sprite_image.replace sprite_item_image, x, y
|
|
end
|
|
sprite_image.save File.join(Lemonade.images_path, sprite[:file])
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
if defined?(ActiveSupport) and Sass::Util.has?(:public_method, ActiveSupport, :on_load)
|
|
# Rails 3.0
|
|
ActiveSupport.on_load :before_initialize do
|
|
Lemonade.extend_sass!
|
|
end
|
|
else
|
|
Lemonade.extend_sass!
|
|
end
|
|
|