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