1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
module Compass
module SassExtensions
module Sprites
module LayoutMethods
HORIZONTAL = 'horizontal'
DIAGONAL = 'diagonal'
SMART = 'smart'
VERTICAL = 'vertical'
def smart?
layout == SMART
end
def horizontal?
layout == HORIZONTAL
end
def diagonal?
layout == DIAGONAL
end
def vertical?
layout == VERTICAL
end
def layout
@layout ||= @kwargs.get_var('layout').value
end
# Calculates the overal image dimensions
# collects image sizes and input parameters for each sprite
def compute_image_positions!
case layout
when SMART
calculate_smart_positions
when DIAGONAL
calculate_diagonal_dimensions
calculate_diagonal_positions
when HORIZONTAL
@height = height_for_horizontal_layout
calculate_horizontal_positions
@width = width_for_horizontal_layout
else
@images.sort! do |a,b|
if (b.size <=> a.size) === 0
a.name <=> b.name
else
b.size <=> a.size
end
end
@width = width_for_vertical_layout
calulate_vertical_postions
@height = height_for_vertical_layout
if @images.any?(&:repeat_x?)
calculate_repeat_extra_width!
tile_images_that_repeat
end
end
end
def tile_images_that_repeat
@images.map {|img| img if img.repeat_x?}.compact.each do |image|
x = image.left - (image.left / image.width).ceil * image.width
while x < @width do
begin
img = image.dup
img.top = image.top
img.left = x.to_i
@images << img
x += image.width
end
end
end
end
def calculate_repeat_extra_width!
require 'rational' #for ruby 1.8.7
m = @images.inject(1) {|m,img| img.repeat_x? ? m.lcm(img.width) : m}
remainder = @width % m
@width += (m - remainder) unless remainder.zero?
end
def calculate_smart_positions
fitter = ::Compass::SassExtensions::Sprites::RowFitter.new(@images)
current_y = 0
fitter.fit!.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
end
current_y += row.height
end
@width = fitter.width
@height = fitter.height
end
def calculate_diagonal_dimensions
@width = @images.inject(0) {|sum, img| sum + img.width}
@height = @images.inject(0) {|sum, img| sum + img.height}
end
def calculate_diagonal_positions
previous = nil
@images.each_with_index do |image, index|
if previous.nil?
previous = image
image.top = @height - image.height
image.left = 0
next
end
image.top = previous.top - image.height
image.left = previous.left + previous.width
previous = image
end
end
def calculate_horizontal_positions
@images.each_with_index do |image, index|
image.top = image.position.unit_str == '%' ? (@height - image.height) * (image.position.value / 100.0) : image.position.value
next if index == 0
last_image = @images[index-1]
image.left = last_image.left + last_image.width + [image.spacing, last_image.spacing].max
end
end
def calulate_vertical_postions
@images.each_with_index do |image, index|
image.left = (image.position.unit_str == "%" ? (@width - image.width) * (image.position.value / 100.0) : image.position.value).to_i
next if index == 0
last_image = @images[index-1]
image.top = last_image.top + last_image.height + [image.spacing, last_image.spacing].max
end
end
def height_for_vertical_layout
last = @images.last
last.top + last.height
end
def height_for_horizontal_layout
@height = @images.map {|image| image.height + image.offset}.max
end
def width_for_horizontal_layout
@images.inject(0) { |sum, image| sum += (image.width + image.spacing) }
end
def width_for_vertical_layout
@images.map { |image| image.width + image.offset }.max
end
end
end
end
end
|