Implemented drag and drop.
[kaya.git] / lib / animations.rb
blob21bbbc3867746a5aa472c7911f71a420375e69f8
1 require 'animation_field'
2 require 'factory'
4 module Animations
5   LENGTH = 100
6   
7   def group(*animations)
8     unless animations.empty?
9       anim = animations.dup.compact
10       Animation.new("group (#{anim.map{|a| a.to_s}.join(',')})") do |i|
11         anim.reject! do |a| 
12           a[i]
13         end
14         anim.empty?
15       end
16     end
17   end
18   
19   def sequence(*animations)
20     anim = animations.dup.compact
21     return nil if anim.empty?
22     Animation.new("sequence (#{anim.size})") do |i|
23       if anim.first[i]
24         anim.shift
25       end
26       anim.empty?
27     end
28   end
29   
30   def movement(item, src, dst, path_factory)
31     if item
32       src = if src
33         board.to_real(src)
34       else
35         item.pos
36       end
37         
38       dst = board.to_real(dst)
39       path = path_factory.new(src, dst)
40       
41       SimpleAnimation.new "move to #{dst}", LENGTH,
42         lambda { board.raise(item) },
43         lambda {|i| item.pos = src + path[i] },
44         lambda { item.pos = dst; board.lower(item) }
45     end
46   end
48   def disappear(item, name = "disappear")
49     if item
50       SimpleAnimation.new name, LENGTH,
51         lambda { item.opacity = 1.0; item.visible = true },
52         lambda {|t| item.opacity = 1.0 - t },
53         lambda { item.remove }
54     end
55   end
56   
57   def appear(item, name = "appear")
58     SimpleAnimation.new name, LENGTH,
59       lambda { item.opacity = 0.0; item.visible = true },
60       lambda {|i| item.opacity = i },
61       lambda { item.opacity = 1.0 }
62   end
63   
64   def instant_appear(p, piece, name = "appear")
65     Animation.new(name) { board.add_piece p, piece }
66   end
67   
68   def instant_disappear(p, name = "disappear")
69     Animation.new(name) { board.remove_item p }
70   end
71 end
73 module Path
74   Linear = Factory.new do |src, dst|
75     delta = dst - src
76     lambda {|i| delta * i }
77   end
79   class LShape
80     FACTOR = Math.exp(3.0) - 1
81     def initialize(src, dst)
82       @delta = dst - src
83       nonlin = lambda{|i| (Math.exp(3.0 * i) - 1) / FACTOR }
84       lin = lambda {|i| i }
85       if @delta.x.abs < @delta.y.abs
86         @x = lin
87         @y = nonlin
88       else
89         @y = lin
90         @x = nonlin
91       end
92     end
93     
94     def [](i)
95       Qt::PointF.new(@delta.x * @x[i], @delta.y * @y[i])
96     end
97   end
98 end