smart packing helper classes
This commit is contained in:
parent
d4227346af
commit
87240723e7
47
lib/compass/sass_extensions/sprites/image_row.rb
Normal file
47
lib/compass/sass_extensions/sprites/image_row.rb
Normal 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
|
86
lib/compass/sass_extensions/sprites/row_fitter.rb
Normal file
86
lib/compass/sass_extensions/sprites/row_fitter.rb
Normal 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
|
Loading…
Reference in New Issue
Block a user