smart packing inital implimentation

This commit is contained in:
Scott Davis 2011-05-17 12:36:39 -04:00
parent aa4999370f
commit bf0662cf87
4 changed files with 18 additions and 55 deletions

View File

@ -1,8 +1,11 @@
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
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
@ -34,6 +37,7 @@ module Compass
@name = sprite_map.name @name = sprite_map.name
@kwargs = kwargs @kwargs = kwargs
@kwargs['cleanup'] ||= Sass::Script::Bool.new(true) @kwargs['cleanup'] ||= Sass::Script::Bool.new(true)
@kwargs['smart_pack'] ||= Sass::Script::Bool.new(false)
@images = nil @images = nil
@width = nil @width = nil
@height = nil @height = nil
@ -43,10 +47,7 @@ module Compass
compute_image_metadata! compute_image_metadata!
end end
# Calculate the size of the sprite
def size
[width, height]
end
# Calculates the overal image dimensions # Calculates the overal image dimensions
# collects image sizes and input parameters for each sprite # collects image sizes and input parameters for each sprite
@ -70,54 +71,14 @@ module Compass
# Calculates the overal image dimensions # Calculates the overal image dimensions
# collects image sizes and input parameters for each sprite # collects image sizes and input parameters for each sprite
def compute_image_positions! def compute_image_positions!
fitter = ::Compass::SassExtensions::Sprites::RowFitter.new(@images) if kwargs.get_var('smart-pack').value
smart_packing
current_y = 0 else
fitter.fit!.each do |row| legacy_packing
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
# @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
# 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
# Validates that the sprite_names are valid sass # Validates that the sprite_names are valid sass
def validate! def validate!

View File

@ -116,8 +116,9 @@ $#{name}-spacing: 0 !default;
$#{name}-repeat: no-repeat !default; $#{name}-repeat: no-repeat !default;
$#{name}-prefix: '' !default; $#{name}-prefix: '' !default;
$#{name}-clean-up: true !default; $#{name}-clean-up: true !default;
$#{name}-smart-pack: false !default;
#{skip_overrides ? "$#{name}-sprites: sprite-map(\"#{uri}\", $cleanup: $#{name}-clean-up);" : generate_overrides } #{skip_overrides ? "$#{name}-sprites: sprite-map(\"#{uri}\", $smart-pack: $#{name}-smart-pack, $cleanup: $#{name}-clean-up);" : generate_overrides }
// All sprites should extend this class // All sprites should extend this class
// The #{name}-sprite mixin will do so for you. // The #{name}-sprite mixin will do so for you.
@ -171,7 +172,7 @@ $#{name}-#{sprite_name}-repeat: $#{name}-repeat !default;
SCSS SCSS
end.join end.join
content += "\n$#{name}-sprites: sprite-map(\"#{uri}\", \n$cleanup: $#{name}-clean-up,\n" content += "\n$#{name}-sprites: sprite-map(\"#{uri}\", \n $smart-pack: $#{name}-smart-pack, $cleanup: $#{name}-clean-up,\n"
content += sprite_names.map do |sprite_name| content += sprite_names.map do |sprite_name|
%Q{ $#{sprite_name}-position: $#{name}-#{sprite_name}-position, %Q{ $#{sprite_name}-position: $#{name}-#{sprite_name}-position,
$#{sprite_name}-spacing: $#{name}-#{sprite_name}-spacing, $#{sprite_name}-spacing: $#{name}-#{sprite_name}-spacing,

View File

@ -1,7 +1,7 @@
require 'test_helper' require 'test_helper'
class SpritesBaseTest < Test::Unit::TestCase class SpritesBaseTest < Test::Unit::TestCase
attr_accessor :options
def setup def setup
Hash.send(:include, Compass::SassExtensions::Functions::Sprites::VariableReader) Hash.send(:include, Compass::SassExtensions::Functions::Sprites::VariableReader)
@images_src_path = File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'sprites', 'public', 'images') @images_src_path = File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'sprites', 'public', 'images')
@ -11,12 +11,12 @@ class SpritesBaseTest < Test::Unit::TestCase
config.images_path = @images_tmp_path config.images_path = @images_tmp_path
Compass.add_configuration(config) Compass.add_configuration(config)
Compass.configure_sass_plugin! Compass.configure_sass_plugin!
@options = {'cleanup' => Sass::Script::Bool.new(true)} @options = {'cleanup' => Sass::Script::Bool.new(true), 'smart_pack' => Sass::Script::Bool.new(false)}
setup_map setup_map
end end
def setup_map def setup_map
@map = Compass::SpriteMap.new(:uri => "selectors/*.png", :options => @options) @map = Compass::SpriteMap.new(:uri => "selectors/*.png", :options => options)
@base = Compass::SassExtensions::Sprites::Base.new(@map.sprite_names.map{|n| "selectors/#{n}.png"}, @map, @map.sass_engine, @map.options) @base = Compass::SassExtensions::Sprites::Base.new(@map.sprite_names.map{|n| "selectors/#{n}.png"}, @map, @map.sass_engine, @map.options)
end end

View File

@ -19,7 +19,7 @@ class SpritesImageTest < Test::Unit::TestCase
let(:sprite_name) { File.basename(sprite_filename, '.png') } let(:sprite_name) { File.basename(sprite_filename, '.png') }
def parent def parent
map = Compass::SpriteMap.new(:uri => "selectors/*.png", :options => options) map = Compass::SpriteMap.new(:uri => "selectors/*.png", :options => {'cleanup' => Sass::Script::Bool.new(true), 'smart_pack' => Sass::Script::Bool.new(false)})
@parent ||= Compass::SassExtensions::Sprites::Base.new(map.sprite_names.map{|n| "selectors/#{n}.png"}, map, map.sass_engine, map.options) @parent ||= Compass::SassExtensions::Sprites::Base.new(map.sprite_names.map{|n| "selectors/#{n}.png"}, map, map.sass_engine, map.options)
end end
@ -30,6 +30,7 @@ class SpritesImageTest < Test::Unit::TestCase
options.stubs(:get_var).with("#{sprite_name}-repeat").returns(::OpenStruct.new(:value => @repeat)) options.stubs(:get_var).with("#{sprite_name}-repeat").returns(::OpenStruct.new(:value => @repeat))
options.stubs(:get_var).with("#{sprite_name}-spacing").returns(::OpenStruct.new(:value => @spacing)) options.stubs(:get_var).with("#{sprite_name}-spacing").returns(::OpenStruct.new(:value => @spacing))
options.stubs(:get_var).with("#{sprite_name}-position").returns(::OpenStruct.new(:value => @position)) options.stubs(:get_var).with("#{sprite_name}-position").returns(::OpenStruct.new(:value => @position))
options.stubs(:get_var).with('smart_pack').returns(Sass::Script::Bool.new(false))
options options
end end