refactored and extracted sprite methods into modules
This commit is contained in:
parent
bf0662cf87
commit
fc034092aa
@ -1,4 +1,9 @@
|
|||||||
require 'digest/md5'
|
require 'digest/md5'
|
||||||
|
#modules
|
||||||
|
require 'compass/sass_extensions/sprites/sprite'
|
||||||
|
require 'compass/sass_extensions/sprites/processing'
|
||||||
|
require 'compass/sass_extensions/sprites/image_helper'
|
||||||
|
#classes
|
||||||
require 'compass/sass_extensions/sprites/sprite_map'
|
require 'compass/sass_extensions/sprites/sprite_map'
|
||||||
require 'compass/sass_extensions/sprites/image'
|
require 'compass/sass_extensions/sprites/image'
|
||||||
require 'compass/sass_extensions/sprites/image_row'
|
require 'compass/sass_extensions/sprites/image_row'
|
||||||
@ -8,7 +13,6 @@ require 'compass/sass_extensions/sprites/engines'
|
|||||||
module Compass
|
module Compass
|
||||||
module SassExtensions
|
module SassExtensions
|
||||||
module Sprites
|
module Sprites
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -1,11 +1,14 @@
|
|||||||
require 'compass/sass_extensions/sprites/helpers/image_helper'
|
|
||||||
require 'compass/sass_extensions/sprites/helpers/processing_helper'
|
|
||||||
module Compass
|
module Compass
|
||||||
module SassExtensions
|
module SassExtensions
|
||||||
module Sprites
|
module Sprites
|
||||||
class Base < Sass::Script::Literal
|
class Base < Sass::Script::Literal
|
||||||
|
|
||||||
|
attr_accessor :image_names, :path, :name, :map, :kwargs
|
||||||
|
attr_accessor :images, :width, :height
|
||||||
|
|
||||||
|
include Sprite
|
||||||
|
include Processing
|
||||||
include ImageHelper
|
include ImageHelper
|
||||||
include ProcessingHelper
|
|
||||||
|
|
||||||
# Initialize a new aprite object from a relative file path
|
# Initialize a new aprite object from a relative file path
|
||||||
# the path is relative to the <tt>images_path</tt> confguration option
|
# the path is relative to the <tt>images_path</tt> confguration option
|
||||||
@ -17,19 +20,6 @@ module Compass
|
|||||||
new(sprites, sprite_map, context, kwargs)
|
new(sprites, sprite_map, context, kwargs)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Loads the sprite engine
|
|
||||||
def require_engine!
|
|
||||||
self.class.send(:include, eval("::Compass::SassExtensions::Sprites::#{modulize}Engine"))
|
|
||||||
end
|
|
||||||
|
|
||||||
# Changing this string will invalidate all previously generated sprite images.
|
|
||||||
# We should do so only when the packing algorithm changes
|
|
||||||
SPRITE_VERSION = "1"
|
|
||||||
|
|
||||||
attr_accessor :image_names, :path, :name, :map, :kwargs
|
|
||||||
attr_accessor :images, :width, :height
|
|
||||||
|
|
||||||
|
|
||||||
def initialize(sprites, sprite_map, context, kwargs)
|
def initialize(sprites, sprite_map, context, kwargs)
|
||||||
require_engine!
|
require_engine!
|
||||||
@image_names = sprites
|
@image_names = sprites
|
||||||
@ -47,115 +37,9 @@ module Compass
|
|||||||
compute_image_metadata!
|
compute_image_metadata!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Loads the sprite engine
|
||||||
|
def require_engine!
|
||||||
# Calculates the overal image dimensions
|
self.class.send(:include, eval("::Compass::SassExtensions::Sprites::#{modulize}Engine"))
|
||||||
# collects image sizes and input parameters for each sprite
|
|
||||||
# Calculates the height
|
|
||||||
def compute_image_metadata!
|
|
||||||
@width = 0
|
|
||||||
init_images
|
|
||||||
compute_image_positions!
|
|
||||||
@height = @images.last.top + @images.last.height
|
|
||||||
end
|
|
||||||
|
|
||||||
# Creates the Sprite::Image objects for each image and calculates the width
|
|
||||||
def init_images
|
|
||||||
@images = image_names.collect do |relative_file|
|
|
||||||
image = Compass::SassExtensions::Sprites::Image.new(self, relative_file, kwargs)
|
|
||||||
@width = [ @width, image.width + image.offset ].max
|
|
||||||
image
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Calculates the overal image dimensions
|
|
||||||
# collects image sizes and input parameters for each sprite
|
|
||||||
def compute_image_positions!
|
|
||||||
if kwargs.get_var('smart-pack').value
|
|
||||||
smart_packing
|
|
||||||
else
|
|
||||||
legacy_packing
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Validates that the sprite_names are valid sass
|
|
||||||
def validate!
|
|
||||||
for sprite_name in sprite_names
|
|
||||||
unless sprite_name =~ /\A#{Sass::SCSS::RX::IDENT}\Z/
|
|
||||||
raise Sass::SyntaxError, "#{sprite_name} must be a legal css identifier"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# The on-the-disk filename of the sprite
|
|
||||||
def filename
|
|
||||||
File.join(Compass.configuration.images_path, "#{path}-#{uniqueness_hash}.png")
|
|
||||||
end
|
|
||||||
|
|
||||||
# Generate a sprite image if necessary
|
|
||||||
def generate
|
|
||||||
if generation_required?
|
|
||||||
if kwargs.get_var('cleanup').value
|
|
||||||
cleanup_old_sprites
|
|
||||||
end
|
|
||||||
sprite_data = construct_sprite
|
|
||||||
save!(sprite_data)
|
|
||||||
Compass.configuration.run_callback(:sprite_generated, sprite_data)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def cleanup_old_sprites
|
|
||||||
Dir[File.join(Compass.configuration.images_path, "#{path}-*.png")].each do |file|
|
|
||||||
FileUtils.rm file
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Does this sprite need to be generated
|
|
||||||
def generation_required?
|
|
||||||
!File.exists?(filename) || outdated?
|
|
||||||
end
|
|
||||||
|
|
||||||
# Returns the uniqueness hash for this sprite object
|
|
||||||
def uniqueness_hash
|
|
||||||
@uniqueness_hash ||= begin
|
|
||||||
sum = Digest::MD5.new
|
|
||||||
sum << SPRITE_VERSION
|
|
||||||
sum << path
|
|
||||||
images.each do |image|
|
|
||||||
[:relative_file, :height, :width, :repeat, :spacing, :position, :digest].each do |attr|
|
|
||||||
sum << image.send(attr).to_s
|
|
||||||
end
|
|
||||||
end
|
|
||||||
sum.hexdigest[0...10]
|
|
||||||
end
|
|
||||||
@uniqueness_hash
|
|
||||||
end
|
|
||||||
|
|
||||||
# Saves the sprite engine
|
|
||||||
def save!(output_png)
|
|
||||||
saved = output_png.save filename
|
|
||||||
Compass.configuration.run_callback(:sprite_saved, filename)
|
|
||||||
saved
|
|
||||||
end
|
|
||||||
|
|
||||||
# All the full-path filenames involved in this sprite
|
|
||||||
def image_filenames
|
|
||||||
@images.map(&:file)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Checks whether this sprite is outdated
|
|
||||||
def outdated?
|
|
||||||
if File.exists?(filename)
|
|
||||||
return @images.map(&:mtime).any? { |imtime| imtime.to_i > self.mtime.to_i }
|
|
||||||
end
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
# Mtime of the sprite file
|
|
||||||
def mtime
|
|
||||||
@mtime ||= File.mtime(filename)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def inspect
|
def inspect
|
||||||
|
32
lib/compass/sass_extensions/sprites/image_helper.rb
Normal file
32
lib/compass/sass_extensions/sprites/image_helper.rb
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
module Compass
|
||||||
|
module SassExtensions
|
||||||
|
module Sprites
|
||||||
|
module ImageHelper
|
||||||
|
# Fetches the Sprite::Image object for the supplied name
|
||||||
|
def image_for(name)
|
||||||
|
@images.detect { |img| img.name == name}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns true if the image name has a hover selector image
|
||||||
|
def has_hover?(name)
|
||||||
|
!image_for("#{name}_hover").nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns true if the image name has a target selector image
|
||||||
|
def has_target?(name)
|
||||||
|
!image_for("#{name}_target").nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns true if the image name has an active selector image
|
||||||
|
def has_active?(name)
|
||||||
|
!image_for("#{name}_active").nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Return and array of image names that make up this sprite
|
||||||
|
def sprite_names
|
||||||
|
image_names.map { |f| File.basename(f, '.png') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
34
lib/compass/sass_extensions/sprites/processing.rb
Normal file
34
lib/compass/sass_extensions/sprites/processing.rb
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
module Compass
|
||||||
|
module SassExtensions
|
||||||
|
module Sprites
|
||||||
|
module Processing
|
||||||
|
def smart_packing
|
||||||
|
fitter = ::Compass::SassExtensions::Sprites::RowFitter.new(@images)
|
||||||
|
|
||||||
|
current_y = 0
|
||||||
|
fitter.fit!.each do |row|
|
||||||
|
current_x = 0
|
||||||
|
row.images.each_with_index do |image, index|
|
||||||
|
image.left = current_x
|
||||||
|
image.top = current_y
|
||||||
|
current_x += image.width
|
||||||
|
image.left = image.position.unit_str == "%" ? (@width - image.width) * (image.position.value / 100) : image.position.value
|
||||||
|
end
|
||||||
|
current_y += row.height
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def legacy_packing
|
||||||
|
@images.each_with_index do |image, index|
|
||||||
|
image.left = image.position.unit_str == "%" ? (@width - image.width) * (image.position.value / 100) : image.position.value
|
||||||
|
next if index == 0
|
||||||
|
last_image = @images[index-1]
|
||||||
|
image.top = last_image.top + last_image.height + [image.spacing, last_image.spacing].max
|
||||||
|
last_image = image
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
125
lib/compass/sass_extensions/sprites/sprite.rb
Normal file
125
lib/compass/sass_extensions/sprites/sprite.rb
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
module Compass
|
||||||
|
module SassExtensions
|
||||||
|
module Sprites
|
||||||
|
module Sprite
|
||||||
|
|
||||||
|
# Changing this string will invalidate all previously generated sprite images.
|
||||||
|
# We should do so only when the packing algorithm changes
|
||||||
|
SPRITE_VERSION = "1"
|
||||||
|
|
||||||
|
# Calculates the overal image dimensions
|
||||||
|
# collects image sizes and input parameters for each sprite
|
||||||
|
# Calculates the height
|
||||||
|
def compute_image_metadata!
|
||||||
|
@width = 0
|
||||||
|
init_images
|
||||||
|
compute_image_positions!
|
||||||
|
@height = @images.last.top + @images.last.height
|
||||||
|
end
|
||||||
|
|
||||||
|
# Creates the Sprite::Image objects for each image and calculates the width
|
||||||
|
def init_images
|
||||||
|
@images = image_names.collect do |relative_file|
|
||||||
|
image = Compass::SassExtensions::Sprites::Image.new(self, relative_file, kwargs)
|
||||||
|
@width = [ @width, image.width + image.offset ].max
|
||||||
|
image
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Calculates the overal image dimensions
|
||||||
|
# collects image sizes and input parameters for each sprite
|
||||||
|
def compute_image_positions!
|
||||||
|
if kwargs.get_var('smart-pack').value
|
||||||
|
smart_packing
|
||||||
|
else
|
||||||
|
legacy_packing
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Validates that the sprite_names are valid sass
|
||||||
|
def validate!
|
||||||
|
for sprite_name in sprite_names
|
||||||
|
unless sprite_name =~ /\A#{Sass::SCSS::RX::IDENT}\Z/
|
||||||
|
raise Sass::SyntaxError, "#{sprite_name} must be a legal css identifier"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# The on-the-disk filename of the sprite
|
||||||
|
def filename
|
||||||
|
File.join(Compass.configuration.images_path, "#{path}-#{uniqueness_hash}.png")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Generate a sprite image if necessary
|
||||||
|
def generate
|
||||||
|
if generation_required?
|
||||||
|
if kwargs.get_var('cleanup').value
|
||||||
|
cleanup_old_sprites
|
||||||
|
end
|
||||||
|
sprite_data = construct_sprite
|
||||||
|
save!(sprite_data)
|
||||||
|
Compass.configuration.run_callback(:sprite_generated, sprite_data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def cleanup_old_sprites
|
||||||
|
Dir[File.join(Compass.configuration.images_path, "#{path}-*.png")].each do |file|
|
||||||
|
FileUtils.rm file
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Does this sprite need to be generated
|
||||||
|
def generation_required?
|
||||||
|
!File.exists?(filename) || outdated?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns the uniqueness hash for this sprite object
|
||||||
|
def uniqueness_hash
|
||||||
|
@uniqueness_hash ||= begin
|
||||||
|
sum = Digest::MD5.new
|
||||||
|
sum << SPRITE_VERSION
|
||||||
|
sum << path
|
||||||
|
images.each do |image|
|
||||||
|
[:relative_file, :height, :width, :repeat, :spacing, :position, :digest].each do |attr|
|
||||||
|
sum << image.send(attr).to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sum.hexdigest[0...10]
|
||||||
|
end
|
||||||
|
@uniqueness_hash
|
||||||
|
end
|
||||||
|
|
||||||
|
# Saves the sprite engine
|
||||||
|
def save!(output_png)
|
||||||
|
saved = output_png.save filename
|
||||||
|
Compass.configuration.run_callback(:sprite_saved, filename)
|
||||||
|
saved
|
||||||
|
end
|
||||||
|
|
||||||
|
# All the full-path filenames involved in this sprite
|
||||||
|
def image_filenames
|
||||||
|
@images.map(&:file)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Checks whether this sprite is outdated
|
||||||
|
def outdated?
|
||||||
|
if File.exists?(filename)
|
||||||
|
return @images.map(&:mtime).any? { |imtime| imtime.to_i > self.mtime.to_i }
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
# Mtime of the sprite file
|
||||||
|
def mtime
|
||||||
|
@mtime ||= File.mtime(filename)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Calculate the size of the sprite
|
||||||
|
def size
|
||||||
|
[width, height]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user