class Phantom::SVG::Base

Attributes

frames[RW]
height[RW]
loops[RW]
skip_first[RW]
width[RW]

Public Class Methods

new(path = nil, options = {}) click to toggle source
# File lib/phantom/svg.rb, line 16
def initialize(path = nil, options = {})
  reset

  add_frame_from_file(path, options) if path
end

Public Instance Methods

add_frame(frame = nil, options = {}) click to toggle source

Creates a blank frame when no arguments are passed Takes another Phantom::SVG object or file path

# File lib/phantom/svg.rb, line 50
def add_frame(frame = nil, options = {})
  if    frame.nil?                              then @frames << Phantom::SVG::Frame.new
  elsif frame.instance_of?(Phantom::SVG::Frame) then @frames << frame
  elsif frame.instance_of?(Phantom::SVG::Base)  then @frames += frame.frames
  elsif frame.instance_of?(String)              then add_frame_from_file(frame, options)
  end
end
add_frame_from_file(path, options = {}) click to toggle source
# File lib/phantom/svg.rb, line 30
def add_frame_from_file(path, options = {})
  create_file_list(path).each do |file|
    load_file(file, options)
  end
end
combine(path) click to toggle source

Combine image.

# File lib/phantom/svg.rb, line 132
def combine(path)
  src = Base.new(path, {unique_ids: true})

  if @width != src.width || @height != src.height
    fail "Can't combine source images of different sizes."
    return
  end

  if @frames.length == 1
    rest_duration = (src.total_duration * 1000).to_i
    @frames[0].duration = rest_duration * 0.001
  elsif src.frames.length == 1
    rest_duration = (total_duration * 1000).to_i
    src.frames[0].duration = rest_duration * 0.001
  else
    rest_duration = (total_duration * 1000).to_i.lcm((src.total_duration * 1000).to_i)
  end

  base_i = src_i = -1
  base_duration = src_duration = 0;
  base_frame = src_frame = nil
  new_frames = []

  begin
    if base_duration == 0
      base_i = (base_i + 1) % @frames.length
      base_frame = @frames[base_i]
      base_duration = (base_frame.duration * 1000).to_i
    end

    if src_duration == 0
      src_i = (src_i + 1) % src.frames.length
      src_frame = src.frames[src_i]
      src_duration = (src_frame.duration * 1000).to_i
    end

    elapsed = [base_duration, src_duration].min

    new_frame = base_frame.clone
    new_frame.duration = elapsed * 0.001
    new_frame.surfaces += src_frame.surfaces
    new_frame.namespaces = src_frame.namespaces.merge(new_frame.namespaces)
    new_frames << new_frame

    base_duration -= elapsed
    src_duration -= elapsed
    rest_duration -= elapsed
  end while rest_duration > 0

  @frames = new_frames
end
load_file(file, options) click to toggle source
# File lib/phantom/svg.rb, line 36
def load_file(file, options)
  case File.extname(file).downcase
  when '.svg'   then  load_from_svg(file, options)
  when '.png'   then  load_from_png(file, options)
  when '.jpg'   then  load_from_jpeg(file, options)
  when '.jpeg'  then  load_from_jpeg(file, options)
  when '.gif'   then  load_from_gif(file, options)
  when '.json'  then  load_from_json(file, options)
  when '.xml'   then  load_from_xml(file, options)
  end
end
reset() click to toggle source
# File lib/phantom/svg.rb, line 22
def reset
  @frames = []
  @width = 0
  @height = 0
  @loops = 0
  @skip_first = false
end
save_apng(path) click to toggle source
# File lib/phantom/svg.rb, line 117
def save_apng(path)
  Parser::PNGWriter.new.write(path, self)
end
save_svg(path) click to toggle source
# File lib/phantom/svg.rb, line 97
def save_svg(path)
  set_size

  Parser::SVGWriter.new.write(path, self)
end
save_svg_frame(path, frame, width = nil, height = nil) click to toggle source
# File lib/phantom/svg.rb, line 103
def save_svg_frame(path, frame, width = nil, height = nil)
  old_width = frame.width
  old_height = frame.height
  frame.width = width unless width.nil?
  frame.height = height unless height.nil?

  write_size = Parser::SVGWriter.new.write(path, frame)

  frame.width = old_width
  frame.height = old_height

  write_size
end
scale_h(height) click to toggle source
# File lib/phantom/svg.rb, line 92
def scale_h(height)
  @width = (@width.to_i * height.to_i / @height.to_i).to_i
  @height = height.to_i
end
scale_w(width) click to toggle source
# File lib/phantom/svg.rb, line 87
def scale_w(width)
  @height = (@height.to_i * width.to_i / @width.to_i).to_i
  @width = width.to_i
end
set_height(height) click to toggle source
# File lib/phantom/svg.rb, line 75
def set_height(height)
  if height.nil?
    if @height.nil? || @height == 0
      frames.each do |frame|
        @height = frame.height.to_i if frame.height.to_i > @height
      end
    end
  else
    @height = height
  end
end
set_size(width = nil, height = nil) click to toggle source
# File lib/phantom/svg.rb, line 58
def set_size(width = nil, height = nil)
  set_width(width)
  set_height(height)
end
set_width(width) click to toggle source
# File lib/phantom/svg.rb, line 63
def set_width(width)
  if width.nil?
    if @width.nil? || @width == 0
      frames.each do |frame|
        @width = frame.width.to_i if frame.width.to_i > @width
      end
    end
  else
    @width = width
  end
end
total_duration() click to toggle source

Calculate and return total duration.

# File lib/phantom/svg.rb, line 122
def total_duration
  result = 0.0
  @frames.each_with_index do |frame, i|
    next if i == 0 && @skip_first
    result += frame.duration
  end
  result
end

Private Instance Methods

create_file_list(path) click to toggle source
# File lib/phantom/svg.rb, line 271
def create_file_list(path)
  result = Dir.glob(path).sort_by { |k| k[/\d+/].to_i }
  result << path if result.empty?
  result
end
load_from_gif(path, option) click to toggle source
# File lib/phantom/svg.rb, line 234
def load_from_gif(path, option)
  reader = Parser::GIFReader.new(path, option)
  
  if reader.has_animation?
    @loops = reader.loops
    @skip_first = reader.skip_first
  else
    @loops = 0
    @skip_first = false
  end

  @frames += reader.frames
  @width = reader.width
  @height = reader.height
end
load_from_jpeg(path, options) click to toggle source
# File lib/phantom/svg.rb, line 218
def load_from_jpeg(path, options)
  reader = Parser::JPEGReader.new(path, options)
  
  if reader.has_animation?
    @loops = reader.loops
    @skip_first = reader.skip_first
  else
    @loops = 0
    @skip_first = false
  end

  @frames += reader.frames
  @width = reader.width
  @height = reader.height
end
load_from_json(path, options) click to toggle source
# File lib/phantom/svg.rb, line 250
def load_from_json(path, options)
  load_from_reader(Parser::JSONAnimationReader.new(path), options)
end
load_from_png(path, options) click to toggle source
# File lib/phantom/svg.rb, line 202
def load_from_png(path, options)
  reader = Parser::PNGReader.new(path, options)
  
  if reader.has_animation?
    @loops = reader.loops
    @skip_first = reader.skip_first
  else
    @loops = 0
    @skip_first = false
  end

  @frames += reader.frames
  @width = reader.width
  @height = reader.height
end
load_from_reader(reader, _options) click to toggle source
# File lib/phantom/svg.rb, line 258
def load_from_reader(reader, _options)
  if @frames.empty?
    @loops = reader.loops
    @skip_first = reader.skip_first
    @frames += reader.frames
    set_size
  elsif reader.skip_first
    @frames += reader.frames.slice(1, reader.frames.length - 1)
  else
    @frames += reader.frames
  end
end
load_from_svg(path, options) click to toggle source
# File lib/phantom/svg.rb, line 186
def load_from_svg(path, options)
  reader = Parser::SVGReader.new(path, options)
  
  if reader.has_animation?
    @loops = reader.loops
    @skip_first = reader.skip_first
  else
    @loops = 0
    @skip_first = false
  end

  @frames += reader.frames
  @width = reader.width
  @height = reader.height
end
load_from_xml(path, options) click to toggle source
# File lib/phantom/svg.rb, line 254
def load_from_xml(path, options)
  load_from_reader(Parser::XMLAnimationReader.new(path), options)
end