walt 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +14 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +61 -0
- data/LICENSE +26 -0
- data/README.md +193 -0
- data/Rakefile +17 -0
- data/app/app_delegate.rb +71 -0
- data/examples/Apple/.gitignore +13 -0
- data/examples/Apple/Rakefile +14 -0
- data/examples/Apple/app/app_delegate.rb +99 -0
- data/examples/Apple/spec/main_spec.rb +9 -0
- data/examples/Apple/vendor/Podfile.lock +11 -0
- data/examples/Bouncing/.gitignore +13 -0
- data/examples/Bouncing/Rakefile +14 -0
- data/examples/Bouncing/app/app_delegate.rb +49 -0
- data/examples/Bouncing/spec/main_spec.rb +9 -0
- data/examples/Bouncing/vendor/Podfile.lock +11 -0
- data/lib/walt.rb +27 -0
- data/lib/walt/animation.rb +124 -0
- data/lib/walt/animation_set.rb +64 -0
- data/lib/walt/asset/asset.rb +79 -0
- data/lib/walt/asset/image.rb +48 -0
- data/lib/walt/asset/text.rb +64 -0
- data/lib/walt/operation/base.rb +60 -0
- data/lib/walt/operation/fade.rb +35 -0
- data/lib/walt/operation/move.rb +73 -0
- data/lib/walt/operation/rotate.rb +41 -0
- data/lib/walt/operation/scale.rb +41 -0
- data/lib/walt/patch/ui_color.rb +5 -0
- data/lib/walt/support/attr_default.rb +16 -0
- data/lib/walt/support/const_get.rb +60 -0
- data/lib/walt/support/font.rb +87 -0
- data/lib/walt/version.rb +3 -0
- data/lib/walt/walt.rb +53 -0
- data/spec/animation_set_spec.rb +49 -0
- data/spec/animation_spec.rb +128 -0
- data/spec/asset/image_spec.rb +16 -0
- data/spec/asset/text_spec.rb +24 -0
- data/spec/asset_spec.rb +11 -0
- data/spec/main_spec.rb +9 -0
- data/spec/operation/fade_spec.rb +25 -0
- data/spec/operation/move_spec.rb +43 -0
- data/spec/operation_spec.rb +26 -0
- data/spec/support_spec.rb +46 -0
- data/vendor/Podfile.lock +11 -0
- data/walt.gemspec +21 -0
- metadata +172 -0
@@ -0,0 +1,64 @@
|
|
1
|
+
=begin
|
2
|
+
{
|
3
|
+
text: "This goes on the screen",
|
4
|
+
text_color: "ff0000",
|
5
|
+
background_color: "00ff00",
|
6
|
+
number_of_lines: 2,
|
7
|
+
text_alignment: :center,
|
8
|
+
font: "MarkerFelt" # see support/font.rb
|
9
|
+
attributes: {...} # see support/font.rb
|
10
|
+
}
|
11
|
+
=end
|
12
|
+
module Walt
|
13
|
+
class TextAsset < Asset
|
14
|
+
PROPERTIES = [:text, :text_color, :background_color, :number_of_lines, :font, :attributes, :text_alignment]
|
15
|
+
attr_accessor *PROPERTIES
|
16
|
+
|
17
|
+
attr_default :content_mode, [UIViewContentModeRedraw]
|
18
|
+
attr_default :text_color, UIColor.blackColor
|
19
|
+
attr_default :background_color, UIColor.clearColor
|
20
|
+
attr_default :number_of_lines, 1
|
21
|
+
|
22
|
+
def initialize(params = {})
|
23
|
+
super
|
24
|
+
|
25
|
+
params.is_a?(NSDictionary) && params.each do |key, value|
|
26
|
+
if PROPERTIES.include?(key.to_sym)
|
27
|
+
self.send("#{key}=", value)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def view
|
33
|
+
@view ||= UILabel.alloc.initWithFrame(CGRectZero).tap do |view|
|
34
|
+
view.frame = [self.position || CGPointZero, self.size || CGSizeZero]
|
35
|
+
view.contentMode = self.view_content_mode
|
36
|
+
view.clipsToBounds = self.clips_to_bounds
|
37
|
+
view.text = self.text
|
38
|
+
view.textColor = self.text_color.to_color
|
39
|
+
view.backgroundColor = self.background_color.to_color
|
40
|
+
view.numberOfLines = self.number_of_lines
|
41
|
+
view.font = Walt::Font.make(self.font) if self.font
|
42
|
+
view.textAlignment = Walt::Support.constant("UITextAlignment", self.text_alignment) if self.text_alignment
|
43
|
+
|
44
|
+
if self.attributes
|
45
|
+
attributes = Walt::Font.attributes(self.attributes)
|
46
|
+
view.font = attributes[UITextAttributeFont] if attributes[UITextAttributeFont]
|
47
|
+
view.textColor = attributes[UITextAttributeTextColor] if attributes[UITextAttributeTextColor]
|
48
|
+
view.shadowColor = attributes[UITextAttributeTextShadowColor] if attributes[UITextAttributeTextShadowColor]
|
49
|
+
if attributes[UITextAttributeTextShadowOffset]
|
50
|
+
view.shadowOffset = CGSizeMake(self.attributes[:shadow_offset][:x], self.attributes[:shadow_offset][:y])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
if !self.size
|
55
|
+
view.sizeToFit
|
56
|
+
end
|
57
|
+
|
58
|
+
Dispatch::Queue.main.async do
|
59
|
+
self.on_ready(true)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
=begin
|
2
|
+
{
|
3
|
+
type: :move,
|
4
|
+
id: :one
|
5
|
+
}
|
6
|
+
=end
|
7
|
+
|
8
|
+
module Walt
|
9
|
+
module Operation
|
10
|
+
class Base
|
11
|
+
extend Walt::Support::AttrDefault
|
12
|
+
|
13
|
+
PROPERTIES = [:id, :type]
|
14
|
+
attr_accessor *PROPERTIES
|
15
|
+
|
16
|
+
def initialize(params = {})
|
17
|
+
params.each do |key, value|
|
18
|
+
if PROPERTIES.include?(key.to_sym)
|
19
|
+
self.send("#{key}=", value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def setup(view, animation)
|
25
|
+
# do initial before animation
|
26
|
+
end
|
27
|
+
|
28
|
+
def finalize(view, animation = nil)
|
29
|
+
# do whatever occurs during the animation
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module_function
|
34
|
+
def for(hash)
|
35
|
+
# Check classes in module for corresponding operation
|
36
|
+
type = hash[:type] || hash["type"]
|
37
|
+
|
38
|
+
# Check for the form {operation_type: :id}
|
39
|
+
if !type
|
40
|
+
type = (hash.keys.map(&:to_s) | self.operation_types)[0]
|
41
|
+
hash[:id] = (hash[type] || hash[type.to_sym])
|
42
|
+
hash[:type] = type
|
43
|
+
end
|
44
|
+
|
45
|
+
if type.is_a?(Symbol) || type.is_a?(String)
|
46
|
+
string = "#{type.to_s.downcase}_operation".camelize
|
47
|
+
if not const_defined? string
|
48
|
+
raise "Invalid Operation value for operation #{hash.inspect}. Create a class called #{string}."
|
49
|
+
end
|
50
|
+
return Walt::Operation.const_get(string).new(hash)
|
51
|
+
end
|
52
|
+
|
53
|
+
self.new(hash)
|
54
|
+
end
|
55
|
+
|
56
|
+
def operation_types
|
57
|
+
Walt::Operation.constants(false).select { |constant_name| constant_name =~ /Operation$/ }.collect! { |op| op.to_s.gsub("Operation", "").underscore }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
=begin
|
2
|
+
{
|
3
|
+
from: 0.0,
|
4
|
+
to: 0.8
|
5
|
+
}
|
6
|
+
=end
|
7
|
+
|
8
|
+
module Walt
|
9
|
+
module Operation
|
10
|
+
class FadeOperation < Base
|
11
|
+
PROPERTIES = [:from, :to]
|
12
|
+
attr_accessor *PROPERTIES
|
13
|
+
|
14
|
+
def initialize(params = {})
|
15
|
+
super
|
16
|
+
|
17
|
+
params.each do |key, value|
|
18
|
+
if PROPERTIES.include?(key.to_sym)
|
19
|
+
self.send("#{key}=", value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def setup(view, animation)
|
25
|
+
if self.from
|
26
|
+
view.alpha = self.from
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def finalize(view, animation)
|
31
|
+
view.alpha = self.to
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
=begin
|
2
|
+
{
|
3
|
+
from: [0, 0],
|
4
|
+
to: [10, 20]
|
5
|
+
}
|
6
|
+
|
7
|
+
{
|
8
|
+
from: 100,
|
9
|
+
to: 200,
|
10
|
+
axis: :y
|
11
|
+
}
|
12
|
+
=end
|
13
|
+
|
14
|
+
module Walt
|
15
|
+
module Operation
|
16
|
+
class MoveOperation < Base
|
17
|
+
PROPERTIES = [:from, :to, :axis]
|
18
|
+
attr_accessor *PROPERTIES
|
19
|
+
|
20
|
+
attr_default :axis, :x
|
21
|
+
|
22
|
+
def initialize(params = {})
|
23
|
+
super
|
24
|
+
|
25
|
+
if axis = (params[:axis] || params["axis"])
|
26
|
+
self.axis = axis
|
27
|
+
end
|
28
|
+
|
29
|
+
params.each do |key, value|
|
30
|
+
if PROPERTIES.include?(key.to_sym)
|
31
|
+
self.send("#{key}=", value)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
["from", "to"].each do |point|
|
37
|
+
define_method("#{point}=") do |new_point|
|
38
|
+
_point = new_point
|
39
|
+
case new_point
|
40
|
+
when Numeric
|
41
|
+
if self.axis.to_sym == :x
|
42
|
+
_point = [new_point, nil]
|
43
|
+
else
|
44
|
+
_point = [nil, new_point]
|
45
|
+
end
|
46
|
+
when CGPoint
|
47
|
+
_point = [new_point.x, new_point.y]
|
48
|
+
when NSArray
|
49
|
+
else
|
50
|
+
raise "Invalid class for #{point}=: #{new_point.inspect}"
|
51
|
+
end
|
52
|
+
instance_variable_set("@#{point}", _point)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def setup(view, animation)
|
57
|
+
if self.from
|
58
|
+
origin = view.frame.origin
|
59
|
+
origin.x = (self.from[0] || origin.x)
|
60
|
+
origin.y = (self.from[1] || origin.y)
|
61
|
+
view.frame = [origin, view.frame.size]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def finalize(view, animation)
|
66
|
+
origin = view.frame.origin
|
67
|
+
origin.x = (self.to[0] || origin.x)
|
68
|
+
origin.y = (self.to[1] || origin.y)
|
69
|
+
view.frame = [origin, view.frame.size]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
=begin
|
2
|
+
{
|
3
|
+
from: 0,
|
4
|
+
to: 45
|
5
|
+
}
|
6
|
+
=end
|
7
|
+
|
8
|
+
module Walt
|
9
|
+
module Operation
|
10
|
+
class RotateOperation < Base
|
11
|
+
PROPERTIES = [:from, :to]
|
12
|
+
attr_accessor *PROPERTIES
|
13
|
+
|
14
|
+
def initialize(params = {})
|
15
|
+
super
|
16
|
+
|
17
|
+
params.each do |key, value|
|
18
|
+
if PROPERTIES.include?(key.to_sym)
|
19
|
+
self.send("#{key}=", value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def finalize(view, animation)
|
25
|
+
rotate = CABasicAnimation.animationWithKeyPath("transform.rotation")
|
26
|
+
|
27
|
+
from = self.from || view.instance_variable_get("@__last_rotation") || 0
|
28
|
+
rotate.fromValue = NSNumber.numberWithFloat(from)
|
29
|
+
|
30
|
+
rotate.toValue = NSNumber.numberWithFloat(self.to * Math::PI / 180)
|
31
|
+
view.instance_variable_set("@__last_rotation", rotate.toValue.to_f)
|
32
|
+
|
33
|
+
rotate.duration = animation.duration
|
34
|
+
rotate.removedOnCompletion = false
|
35
|
+
rotate.fillMode = KCAFillModeForwards
|
36
|
+
|
37
|
+
view.layer.addAnimation(rotate, forKey:nil)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
=begin
|
2
|
+
{
|
3
|
+
from: 1.0,
|
4
|
+
to: 1.2
|
5
|
+
}
|
6
|
+
=end
|
7
|
+
|
8
|
+
module Walt
|
9
|
+
module Operation
|
10
|
+
class ScaleOperation < Base
|
11
|
+
PROPERTIES = [:from, :to]
|
12
|
+
attr_accessor *PROPERTIES
|
13
|
+
|
14
|
+
def initialize(params = {})
|
15
|
+
super
|
16
|
+
|
17
|
+
params.each do |key, value|
|
18
|
+
if PROPERTIES.include?(key.to_sym)
|
19
|
+
self.send("#{key}=", value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def finalize(view, animation)
|
25
|
+
scale = CABasicAnimation.animationWithKeyPath("transform.scale")
|
26
|
+
|
27
|
+
from = self.from || view.instance_variable_get("@__last_scale") || 1.0
|
28
|
+
scale.fromValue = NSNumber.numberWithFloat(from)
|
29
|
+
|
30
|
+
scale.toValue = NSNumber.numberWithFloat(self.to)
|
31
|
+
view.instance_variable_set("@__last_scale", scale.toValue.to_f)
|
32
|
+
|
33
|
+
scale.duration = animation.duration
|
34
|
+
scale.removedOnCompletion = false
|
35
|
+
scale.fillMode = KCAFillModeForwards
|
36
|
+
|
37
|
+
view.layer.addAnimation(scale, forKey:nil)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Walt
|
2
|
+
module Support
|
3
|
+
module AttrDefault
|
4
|
+
def attr_default(attribute, default)
|
5
|
+
attr_accessor attribute
|
6
|
+
define_method(attribute) do
|
7
|
+
ivar = "@#{attribute}"
|
8
|
+
if !instance_variable_defined?(ivar)
|
9
|
+
instance_variable_set(ivar, default)
|
10
|
+
end
|
11
|
+
instance_variable_get(ivar)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Walt
|
2
|
+
module Support
|
3
|
+
module_function
|
4
|
+
|
5
|
+
=begin
|
6
|
+
Constant.for("UIViewAnimationOption", value)
|
7
|
+
=end
|
8
|
+
|
9
|
+
def constant(base, value)
|
10
|
+
return value if value.is_a? Numeric
|
11
|
+
value = value.to_s.camelize
|
12
|
+
Kernel.const_get("#{base}#{value}")
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def hack
|
17
|
+
[
|
18
|
+
UIViewAnimationOptionLayoutSubviews,
|
19
|
+
UIViewAnimationOptionAllowUserInteraction,
|
20
|
+
UIViewAnimationOptionBeginFromCurrentState,
|
21
|
+
UIViewAnimationOptionRepeat,
|
22
|
+
UIViewAnimationOptionAutoreverse,
|
23
|
+
UIViewAnimationOptionOverrideInheritedDuration,
|
24
|
+
UIViewAnimationOptionOverrideInheritedCurve,
|
25
|
+
UIViewAnimationOptionAllowAnimatedContent,
|
26
|
+
UIViewAnimationOptionShowHideTransitionViews,
|
27
|
+
UIViewAnimationOptionCurveEaseInOut,
|
28
|
+
UIViewAnimationOptionCurveEaseIn,
|
29
|
+
UIViewAnimationOptionCurveEaseOut,
|
30
|
+
UIViewAnimationOptionCurveLinear,
|
31
|
+
UIViewAnimationOptionTransitionNone,
|
32
|
+
UIViewAnimationOptionTransitionFlipFromLeft,
|
33
|
+
UIViewAnimationOptionTransitionFlipFromRight,
|
34
|
+
UIViewAnimationOptionTransitionCurlUp,
|
35
|
+
UIViewAnimationOptionTransitionCurlDown,
|
36
|
+
UIViewAnimationOptionTransitionCrossDissolve,
|
37
|
+
UIViewAnimationOptionTransitionFlipFromTop,
|
38
|
+
UIViewAnimationOptionTransitionFlipFromBottom,
|
39
|
+
|
40
|
+
UIViewContentModeScaleToFill,
|
41
|
+
UIViewContentModeScaleAspectFit,
|
42
|
+
UIViewContentModeScaleAspectFill,
|
43
|
+
UIViewContentModeRedraw,
|
44
|
+
UIViewContentModeCenter,
|
45
|
+
UIViewContentModeTop,
|
46
|
+
UIViewContentModeBottom,
|
47
|
+
UIViewContentModeLeft,
|
48
|
+
UIViewContentModeRight,
|
49
|
+
UIViewContentModeTopLeft,
|
50
|
+
UIViewContentModeTopRight,
|
51
|
+
UIViewContentModeBottomLeft,
|
52
|
+
UIViewContentModeBottomRight,
|
53
|
+
|
54
|
+
UITextAlignmentLeft,
|
55
|
+
UITextAlignmentRight,
|
56
|
+
UITextAlignmentCenter
|
57
|
+
]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Walt
|
2
|
+
module Font
|
3
|
+
module_function
|
4
|
+
|
5
|
+
def bold(size)
|
6
|
+
Font.make(:bold, size)
|
7
|
+
end
|
8
|
+
|
9
|
+
def system(size)
|
10
|
+
Font.make(:system, size)
|
11
|
+
end
|
12
|
+
|
13
|
+
def italic(size)
|
14
|
+
Font.make(:italic, size)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Create font with params:
|
18
|
+
# String => The name of the font
|
19
|
+
# Hash => {
|
20
|
+
# size: Integer,
|
21
|
+
# name: String (see above)
|
22
|
+
# }
|
23
|
+
def make(params = {}, *args)
|
24
|
+
if params.is_a?(UIFont)
|
25
|
+
return params
|
26
|
+
end
|
27
|
+
|
28
|
+
_font = nil
|
29
|
+
if params.is_a?(NSString)
|
30
|
+
params = {name: params}
|
31
|
+
end
|
32
|
+
if args && args[0]
|
33
|
+
params.merge!({size: args[0]})
|
34
|
+
end
|
35
|
+
params[:size] ||= UIFont.systemFontSize
|
36
|
+
if [:system, :bold, :italic].member?(params[:name])
|
37
|
+
case params[:name]
|
38
|
+
when :system
|
39
|
+
_font = UIFont.systemFontOfSize(params[:size].to_f)
|
40
|
+
when :bold
|
41
|
+
_font = UIFont.boldSystemFontOfSize(params[:size].to_f)
|
42
|
+
when :italic
|
43
|
+
_font = UIFont.italicSystemFontOfSize(params[:size].to_f)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
if !_font
|
48
|
+
begin
|
49
|
+
_font = UIFont.fontWithName(params[:name], size: params[:size])
|
50
|
+
rescue
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
if !_font
|
55
|
+
raise "Invalid font for parameters: #{params.inspect} args #{args.inspect}"
|
56
|
+
end
|
57
|
+
|
58
|
+
_font
|
59
|
+
end
|
60
|
+
|
61
|
+
# Create font attributes with keys:
|
62
|
+
# {
|
63
|
+
# font: String or Hash (see Font.make),
|
64
|
+
# color: String,
|
65
|
+
# shadow_color: String,
|
66
|
+
# shadow_offset: {
|
67
|
+
# x: Integer,
|
68
|
+
# y: Integer
|
69
|
+
# }
|
70
|
+
# }
|
71
|
+
def attributes(params = {})
|
72
|
+
_attributes = {}
|
73
|
+
|
74
|
+
_attributes[UITextAttributeFont] = Font.make(params[:font]) if params[:font]
|
75
|
+
_attributes[UITextAttributeTextColor] = params[:color].to_color if params[:color]
|
76
|
+
_attributes[UITextAttributeTextShadowColor] = params[:shadow_color].to_color if params[:shadow_color]
|
77
|
+
_attributes[UITextAttributeTextShadowOffset] = begin
|
78
|
+
x = params[:shadow_offset][:x]
|
79
|
+
y = params[:shadow_offset][:y]
|
80
|
+
offset = UIOffsetMake(x,y)
|
81
|
+
NSValue.valueWithUIOffset(offset)
|
82
|
+
end if params[:shadow_offset]
|
83
|
+
|
84
|
+
_attributes
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|