Class: Montage::Sprite

Inherits:
Object
  • Object
show all
Defined in:
lib/montage/sprite.rb

Overview

Represents a collection of images which will be used to make a sprite.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, sources, save_path, project, options = {}) ⇒ Sprite

Creates a new Sprite instance.

Parameters:

  • name (String)

    The name of the sprite. Will be used as the sprite filename (with an extension added).

  • sources (Array(String, Pathname))

    The name of each source image.

  • save_path (Pathname)

    The location at which the sprite should be saved.

  • project (Montage::Project)

    The project to which the sprite belongs.

  • options (Hash) (defaults to: {})

    Extra options where you wish to override project defaults.



21
22
23
24
25
26
27
28
29
# File 'lib/montage/sprite.rb', line 21

def initialize(name, sources, save_path, project, options = {})
  @name      = name
  @save_path = save_path

  @padding   = options.fetch(:padding, project.padding)
  @url       = options.fetch(:url, project.paths.url)

  @sources   = sources.map { |path| Source.new(path) }
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



5
6
7
# File 'lib/montage/sprite.rb', line 5

def name
  @name
end

#paddingObject (readonly)

Returns the value of attribute padding.



5
6
7
# File 'lib/montage/sprite.rb', line 5

def padding
  @padding
end

#save_pathObject (readonly)

Returns the value of attribute save_path.



5
6
7
# File 'lib/montage/sprite.rb', line 5

def save_path
  @save_path
end

#sourcesObject (readonly)

Returns the value of attribute sources.



5
6
7
# File 'lib/montage/sprite.rb', line 5

def sources
  @sources
end

#urlObject (readonly)

Returns the value of attribute url.



5
6
7
# File 'lib/montage/sprite.rb', line 5

def url
  @url
end

Instance Method Details

#digestDigest::SHA256

Returns a digest which represents the sprite and it’s contents. If any of the file contents or source names change, so will the hash.

Returns:

  • (Digest::SHA256)


74
75
76
# File 'lib/montage/sprite.rb', line 74

def digest
  Digest::SHA256.hexdigest(sources.map { |source| source.digest }.join)
end

#imagesArray<Magick::Image>

Returns an array of RMagick image instances; one for each source.

Returns:

  • (Array<Magick::Image>)

    The Image instances for the sources.



36
37
38
# File 'lib/montage/sprite.rb', line 36

def images
  sources.map { |source| source.image }
end

#position_of(source) ⇒ Integer, Source

Returns the y-position of a given source.

Returns:

  • (Integer, Source)

    The vertical position of the source image.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/montage/sprite.rb', line 45

def position_of(source)
  source = source.name if source.is_a?(Montage::Source)

  unless sources.detect { |src| src.name == source }
    raise MissingSource,
      "Source image '#{source}' is not present in the '#{@name}' sprite"
  end

  unless @positions
    # Rather than calculate each time we call position_of, cache the
    # position of each image the first time it is called. Since we almost
    # always want the position of each image at some point (when
    # generating CSS), it works out faster to fetch each source height
    # just once.
    @positions = {}
    @sources.inject(0) do |offset, src|
      @positions[src.name] = offset
      offset + src.image.rows + @padding
    end
  end

  @positions[source]
end

#writeObject

Uses RMagick to creates a 8-bit (with alpha) PNG containing all of the source files.

If a file exists at the output path, it will be overwritten.

Raises:



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
# File 'lib/montage/sprite.rb', line 86

def write
  unless @save_path.dirname.writable?
    raise TargetNotWritable, <<-MESSAGE
      Montage can't save the sprite in `#{@save_path.dirname.to_s}'
      as it isn't writable.
    MESSAGE
  end

  list = Magick::ImageList.new

  @sources.each do |source|
    list << source.image

    if @padding and @padding > 0
      list << Magick::Image.new(1, @padding) do
        self.background_color = '#FFF0'
      end
    end
  end

  # RMagick uses instance_eval, @set isn't available in the block below.
  sources_length = @sources.length

  montage = list.montage do
    self.gravity = Magick::NorthWestGravity
    # Transparent background.
    self.background_color = '#FFF0'
    # Allow each image to take up as much space as it needs.
    self.geometry = '+0+0'
    # columns=1, rows=Sources plus padding.
    self.tile = Magick::Geometry.new(1, sources_length * 2)
  end

  # Remove the blank space from the bottom of the image.
  montage.crop!(0, 0, 0, (montage.first.rows) - @padding)
  montage.write("PNG32:#{@save_path}")
end