diff --git a/lib/compass/sass_extensions/sprites.rb b/lib/compass/sass_extensions/sprites.rb index 12e821ed..7927799e 100644 --- a/lib/compass/sass_extensions/sprites.rb +++ b/lib/compass/sass_extensions/sprites.rb @@ -1,6 +1,7 @@ require 'digest/md5' require 'compass/sass_extensions/sprites/sprite_map' require 'compass/sass_extensions/sprites/image' +require 'compass/sass_extensions/sprites/image_row' require 'compass/sass_extensions/sprites/base' require 'compass/sass_extensions/sprites/engines' diff --git a/lib/compass/sass_extensions/sprites/base.rb b/lib/compass/sass_extensions/sprites/base.rb index 3051248a..f734118a 100644 --- a/lib/compass/sass_extensions/sprites/base.rb +++ b/lib/compass/sass_extensions/sprites/base.rb @@ -70,12 +70,36 @@ module Compass # Calculates the overal image dimensions # collects image sizes and input parameters for each sprite def compute_image_positions! - @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 + imgs = @images.sort { |a,b| a.width <=> b.width } + rows = [::Compass::SassExtensions::Sprites::ImageRow.new(@width)] + imgs.each do |image| + next if rows.last.add(image) + + rows << ::Compass::SassExtensions::Sprites::ImageRow.new(@width) + unless rows.last.add(image) + raise "Image failed to be added" + end + end + current_y = 0 + rows.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 + + # @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 # Fetches the Sprite::Image object for the supplied name diff --git a/lib/compass/sass_extensions/sprites/image_row.rb b/lib/compass/sass_extensions/sprites/image_row.rb new file mode 100644 index 00000000..d7a85d52 --- /dev/null +++ b/lib/compass/sass_extensions/sprites/image_row.rb @@ -0,0 +1,35 @@ +module Compass + module SassExtensions + module Sprites + class ImageRow + attr_reader :images, :max_width + + def initialize(max_width) + @images = [] + @max_width = max_width + end + + def add(image) + unless image.is_a?(Compass::SassExtensions::Sprites::Image) + raise ArgumentError, "Must be a SpriteImage" + end + if (images.inject(0) {|sum, img| sum + img.width} + image.width) > max_width + return false + end + @images << image + true + end + + def height + images.map(&:height).max + end + + def width + images.map(&:width).max + end + + end + end + end +end + \ No newline at end of file diff --git a/test/fixtures/sprites/public/images/image_row/large.png b/test/fixtures/sprites/public/images/image_row/large.png new file mode 100644 index 00000000..f86cca9b Binary files /dev/null and b/test/fixtures/sprites/public/images/image_row/large.png differ diff --git a/test/fixtures/sprites/public/images/image_row/large_square.png b/test/fixtures/sprites/public/images/image_row/large_square.png new file mode 100644 index 00000000..b99cf980 Binary files /dev/null and b/test/fixtures/sprites/public/images/image_row/large_square.png differ diff --git a/test/fixtures/sprites/public/images/image_row/medium.png b/test/fixtures/sprites/public/images/image_row/medium.png new file mode 100644 index 00000000..faf62a6d Binary files /dev/null and b/test/fixtures/sprites/public/images/image_row/medium.png differ diff --git a/test/fixtures/sprites/public/images/image_row/small.png b/test/fixtures/sprites/public/images/image_row/small.png new file mode 100644 index 00000000..d8e52311 Binary files /dev/null and b/test/fixtures/sprites/public/images/image_row/small.png differ diff --git a/test/fixtures/sprites/public/images/image_row/tall.png b/test/fixtures/sprites/public/images/image_row/tall.png new file mode 100644 index 00000000..ef422eff Binary files /dev/null and b/test/fixtures/sprites/public/images/image_row/tall.png differ diff --git a/test/units/sprites/image_row_test.rb b/test/units/sprites/image_row_test.rb new file mode 100644 index 00000000..397793dc --- /dev/null +++ b/test/units/sprites/image_row_test.rb @@ -0,0 +1,52 @@ +require 'test_helper' + +class ImageRowTest < Test::Unit::TestCase + + def setup + @filenames = %w(large.png large_square.png medium.png tall.png small.png) + Compass.configuration.stubs(:images_path).returns('./') + @images_src_path = File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'sprites', 'public', 'images') + @image_files = Dir["#{@images_src_path}/image_row/*.png"].sort + @images = @image_files.map do |img| + Compass::SassExtensions::Sprites::Image.new(nil, img, {}) + end + image_row(1000) + end + + def image_row(max) + @image_row = Compass::SassExtensions::Sprites::ImageRow.new(max) + end + + def teardown + + end + + + def populate_row + @images.each do |image| + assert @image_row.add(image) + end + end + + it "should return false if image will not fit in row" do + image_row(100) + img = Compass::SassExtensions::Sprites::Image.new(nil, File.join(@images_src_path, 'image_row', 'large.png'), {}) + assert !@image_row.add(img) + end + + it "should have 5 images" do + populate_row + assert_equal 5, @image_row.images.size + end + + it "should return max image width" do + populate_row + assert_equal 400, @image_row.width + end + + it "should return max image height" do + populate_row + assert_equal 40, @image_row.height + end + +end \ No newline at end of file