smart packing helper classes

This commit is contained in:
Scott Davis 2011-08-02 23:35:27 -04:00
parent d4227346af
commit 87240723e7
2 changed files with 133 additions and 0 deletions

View File

@ -0,0 +1,47 @@
require 'forwardable'
module Compass
module SassExtensions
module Sprites
class ImageRow
extend Forwardable
attr_reader :images, :max_width
def_delegators :@images, :last, :delete, :empty?, :length
def initialize(max_width)
@images = []
@max_width = max_width
end
def add(image)
return false if !will_fit?(image)
@images << image
true
end
alias :<< :add
def height
images.map(&:height).max
end
def width
images.map(&:width).max
end
def total_width
images.inject(0) {|sum, img| sum + img.width }
end
def efficiency
1 - (total_width.to_f / max_width.to_f)
end
def will_fit?(image)
(total_width + image.width) <= max_width
end
end
end
end
end

View File

@ -0,0 +1,86 @@
require 'forwardable'
module Compass
module SassExtensions
module Sprites
class RowFitter
extend Forwardable
attr_reader :images, :rows
def_delegators :rows, :[]
def initialize(images)
@images = images.sort {|a,b| a.height <=> b.height }
@rows = []
end
def fit!(style = :scan)
send("#{style}_fit")
@rows
end
def width
@width ||= @images.collect(&:width).max
end
def height
@height ||= @rows.inject(0) {|sum, row| sum += row.height}
end
def efficiency
@rows.inject(0) { |sum, row| sum += row.efficiency } ** @rows.length
end
private
def new_row(image = nil)
row = Compass::SassExtensions::Sprites::ImageRow.new(width)
row.add(image) if image
row
end
def fast_fit
row = new_row
@images.each do |image|
if !row.add(image)
@rows << row
row = new_row(image)
end
end
@rows << row
end
def scan_fit
fast_fit
moved_images = []
begin
removed = false
catch :done do
@rows.each do |row|
(@rows - [ row ]).each do |other_row|
other_row.images.each do |image|
if !moved_images.include?(image)
if row.will_fit?(image)
other_row.delete(image)
row << image
@rows.delete(other_row) if other_row.empty?
removed = true
moved_images << image
throw :done
end
end
end
end
end
end
end while removed
end
end
end
end
end