Skip to content

Instantly share code, notes, and snippets.

@mguterl
Forked from jnunemaker/matrix_maker.rb
Created October 21, 2008 16:29
Show Gist options
  • Save mguterl/18343 to your computer and use it in GitHub Desktop.
Save mguterl/18343 to your computer and use it in GitHub Desktop.
class Nav
def self.padded_selector(sel, max_len)
sel.ljust(max_len)
end
attr_accessor :id, :height, :items, :image
def initialize(attrs={})
attrs.each { |k,v| send("#{k}=", v) }
end
def id
@id || 'nav'
end
def items
@items || []
end
def generate
raise 'Height undefined' if height.nil?
declaration + @items.collect { |item| item.declaration }.join("\n")
end
def declaration
declaration = <<-CSS
#{padded_selector(selector)} {float:left; width:#{width}px; height:#{height}px; margin:0; padding:0;}
#{padded_selector(selector + ' li')} {float:left; list-style-type:none; margin:0; padding:0;}
#{padded_selector(selector + ' li a')} {float:left; display:block; height:#{height}px; background:url(#{image}) no-repeat; text-indent:-9999px; overflow:hidden;}
CSS
end
def padded_selector(sel)
self.class.padded_selector(sel, max_item_selector_length)
end
def max_item_selector_length
@items.max { |a, b| a.selector_size <=> b.selector_size }.selector_size
end
def selector
"ul##{id}"
end
def width
@items.inject(0) { |sum, item| sum += item.width; sum }
end
def <<(item)
@items ||= []
item.nav = self
@items << item
end
end
class Item
def self.pretty_offset(offset)
prefix = postfix = ''
unless offset.zero?
prefix = '-'
postfix = 'px'
end
"#{prefix}#{offset}#{postfix}"
end
attr_accessor :name, :width, :nav, :body_id
def initialize(attrs={})
attrs.each { |k,v| send("#{k}=", v) }
end
def body_id
@body_id || "b_#{name.downcase.gsub(' ', '_')}"
end
def declaration
declaration = <<-CSS
#{nav.padded_selector(full_selector)} {background-position:#{offset} 0; width:#{width}px;}
#{nav.padded_selector(full_selector_hover)} {background-position:#{offset} -#{nav.height}px;}
#{nav.padded_selector(full_selector_with_body)} {background-position:#{offset} -#{nav.height*2}px;}
CSS
end
def full_selector
"#{nav.selector} #{selector}"
end
def full_selector_hover
"#{full_selector}:hover"
end
def full_selector_with_body
"body##{body_id} #{full_selector}"
end
def selector_size
full_selector_with_body.size
end
def selector
len = name.size > 3 ? 3 : name.size
"li#nav_#{name.downcase[0, len]} a"
end
def offset
unless @offset
offset = nav.items[0, position].inject(0) { |sum, item| sum += item.width; sum }
@offset = self.class.pretty_offset(offset)
end
@offset
end
def position
nav.items.index(self)
end
end
if $0 == __FILE__
nav = Nav.new(:height => 52, :image => 'images/nav.jpg')
nav << Item.new(:name => 'Home', :width => 135)
nav << Item.new(:name => 'Features', :width => 175)
nav << Item.new(:name => 'Pricing', :width => 155)
nav << Item.new(:name => 'Questions', :width => 181)
nav << Item.new(:name => 'Sign Up', :width => 156)
puts nav.generate
end
# OUTPUTS:
# ul#nav {float:left; width:802px; height:52px; margin:0; padding:0;}
# ul#nav li {float:left; list-style-type:none; margin:0; padding:0;}
# ul#nav li a {float:left; display:block; height:52px; background:url(images/nav.jpg) no-repeat; text-indent:-9999px; overflow:hidden;}
# ul#nav li#nav_hom a {background-position:0 0; width:135px;}
# ul#nav li#nav_hom a:hover {background-position:0 -52px;}
# body#b_home ul#nav li#nav_hom a {background-position:0 -104px;}
#
# ul#nav li#nav_fea a {background-position:-135px 0; width:175px;}
# ul#nav li#nav_fea a:hover {background-position:-135px -52px;}
# body#b_features ul#nav li#nav_fea a {background-position:-135px -104px;}
#
# ul#nav li#nav_pri a {background-position:-310px 0; width:155px;}
# ul#nav li#nav_pri a:hover {background-position:-310px -52px;}
# body#b_pricing ul#nav li#nav_pri a {background-position:-310px -104px;}
#
# ul#nav li#nav_que a {background-position:-465px 0; width:181px;}
# ul#nav li#nav_que a:hover {background-position:-465px -52px;}
# body#b_questions ul#nav li#nav_que a {background-position:-465px -104px;}
#
# ul#nav li#nav_sig a {background-position:-646px 0; width:156px;}
# ul#nav li#nav_sig a:hover {background-position:-646px -52px;}
# body#b_sign_up ul#nav li#nav_sig a {background-position:-646px -104px;}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment