Implement ActionList::Entry#clear.
[kaya.git] / lib / animations.rb
blobf7a05a3c46cb694728d6fd219b4a09059146a83a
1 # Copyright (c) 2009 Paolo Capriotti <p.capriotti@gmail.com>
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 require 'animation_field'
9 require 'factory'
11 module Animations
12   LENGTH = 100
13   
14   def group(*animations)
15     unless animations.empty?
16       anim = animations.dup.compact
17       return nil if anim.empty?
18       name = case anim.size
19       when 1
20         anim.first.name
21       else
22         "group (#{anim.map{|a| a.to_s}.join(',')})"
23       end
24       Animation.new(name) do |i|
25         anim.reject! do |a| 
26           a[i]
27         end
28         anim.empty?
29       end
30     end
31   end
32   
33   def sequence(*animations)
34     anim = animations.dup.compact
35     return nil if anim.empty?
36     name = case anim.size
37     when 1
38       anim.first.name
39     else
40       "sequence (#{anim.map{|a| a.to_s}.join(',')})"
41     end
42     Animation.new(name) do |i|
43       if anim.first[i]
44         anim.shift
45       end
46       anim.empty?
47     end
48   end
49   
50   def movement(item, src, dst, path_factory)
51     if item
52       name = "move to #{dst}"
53       src = if src
54         board.to_real(src)
55       else
56         item.pos
57       end
58         
59       dst = board.to_real(dst)
60       path = path_factory.new(src, dst)
61       
62       SimpleAnimation.new name, LENGTH,
63         lambda { board.raise(item) },
64         lambda {|i| item.pos = src + path[i] },
65         lambda { item.pos = dst; board.lower(item) }
66     end
67   end
69   def disappear(item, name, opts = { })
70     if item
71       if opts[:instant]
72         Animation.new(name) { item.visible = false; true }
73       else
74         SimpleAnimation.new name, LENGTH,
75           lambda { item.opacity = 1.0; item.visible = true },
76           lambda {|t| item.opacity = 1.0 - t },
77           lambda { item.remove }
78       end
79     end
80   end
81   
82   def appear(item, name, opts = { })
83     if opts[:instant]
84       Animation.new(name) { item.opacity = 1.0; item.visible = true; true }
85     else
86       SimpleAnimation.new name, LENGTH,
87         lambda { item.opacity = 0.0; item.visible = true },
88         lambda {|i| item.opacity = i },
89         lambda { item.opacity = 1.0 }
90     end
91   end
92 end
94 module Path
95   Linear = Factory.new do |src, dst|
96     delta = dst - src
97     lambda {|i| delta * i }
98   end
100   class LShape
101     FACTOR = Math.exp(3.0) - 1
102     def initialize(src, dst)
103       @delta = dst - src
104       nonlin = lambda{|i| (Math.exp(3.0 * i) - 1) / FACTOR }
105       lin = lambda {|i| i }
106       if @delta.x.abs < @delta.y.abs
107         @x = lin
108         @y = nonlin
109       else
110         @y = lin
111         @x = nonlin
112       end
113     end
114     
115     def [](i)
116       Qt::PointF.new(@delta.x * @x[i], @delta.y * @y[i])
117     end
118   end