Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
119 lines (90 sloc) 3.03 KB

zoom method with a little bit of metaprogramming

I attempted to use a little bit of Ruby Metaprogramming methods, Module#extended and Object#instance_variable_set.

If you use zoom module like this, the oval shape can get a zooming function easily.

require 'zoom'
Shoes.app do
  extend Zoom
  zoom oval 100, 100, 100
end

mouse click

  • left button: zoom start/stop
  • right button: reverse

Look at online demo.

# sample74.rb
require 'zoom'

Shoes.app :title => 'Zoom Demo v0.1' do
  extend Zoom
  nostroke
  imgs = []
  imgs << oval(100, 100, 100, :fill => crimson)
  imgs << rect(200, 250, 100, :fill => limegreen, :reverse => true)
  imgs << image(:left => 300, :top => 100, :width => 200, :height => 200){
    star 100, 100, 5, 100, 40, :fill => orange}.rotate(36)
  
  imgs.each{|e| zoom e}
end

You can use zoom.rb as like a common library.

#zoom.rb
module Zoom
  def self.extended mod
    mod.instance_variable_set :@app, mod
    mod.instance_variable_set :@flag, 1
  end
  
  def zoom img
    dir = img.style[:reverse] ? -1 : 1
    run = false
    a = nil
    img.click do
      run = !run
      a.remove if a
      a = @app.animate do
        img.width += 2 * @flag * dir
        img.height += 2 * @flag * dir
        img.move img.left - @flag * dir, img.top - @flag * dir
      end if run
    end
   
    @app.click{|n, | @flag *= -1 if n == 2}
  end
end

sample74.png

sample74.png


I found Image#scale() method by browsing Shoes source code ruby.c a little bit. So, I attempted to revise the above sample codes. It works like the same.

#zoom-1.rb
module Zoom
  def self.extended mod
    mod.instance_variable_set :@app, mod
    mod.instance_variable_set :@flag, 1
  end

  def zoom img
    dir = img.style[:reverse] ? -1 : 1
    run = false
    a = nil
    img.click do
      run = !run
      a.remove if a
      a = @app.animate do
        img.scale @flag * dir > 0 ? 1.02 : 0.98
      end if run
    end

    @app.click{|n, | @flag *= -1 if n == 2}
  end
end

Although, needed to edit the sample74.rb. Because Shoes::Shape class has no scale() method so far.

# sample74-1.rb
require 'zoom-1'

Shoes.app :title => 'Zoom Demo v0.1a' do
  extend Zoom
  nostroke
  imgs = []
  imgs << image(:left => 100, :top => 100, :width => 100, :height => 100){
    oval(0, 0, 100, :fill => crimson)}
  imgs << image(:left => 200, :top => 250, :width => 100, :height => 100, :reverse => true){
    rect(0, 0, 100, :fill => limegreen)}
  imgs << image(:left => 300, :top => 100, :width => 200, :height => 200){
    star 100, 100, 5, 100, 40, :fill => orange}.rotate(36)
  
  imgs.each{|e| zoom e}
end

Policeman

The sample74.rb and sample74-1.rb worked well with Shoes-0.r1263. Policeman looks like a bit faster than Raisins. :)