inkcite 1.14.0 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/assets/init/config.yml +2 -0
  3. data/assets/social/facebook.png +0 -0
  4. data/assets/social/instagram.png +0 -0
  5. data/assets/social/pintrest.png +0 -0
  6. data/assets/social/twitter.png +0 -0
  7. data/inkcite.gemspec +2 -2
  8. data/lib/inkcite.rb +1 -0
  9. data/lib/inkcite/cli/base.rb +32 -6
  10. data/lib/inkcite/cli/preview.rb +24 -28
  11. data/lib/inkcite/cli/server.rb +22 -19
  12. data/lib/inkcite/cli/test.rb +1 -1
  13. data/lib/inkcite/email.rb +8 -4
  14. data/lib/inkcite/facade/animation.rb +4 -0
  15. data/lib/inkcite/facade/keyframe.rb +26 -3
  16. data/lib/inkcite/image/base.rb +38 -0
  17. data/lib/inkcite/image/guetzli_minifier.rb +62 -0
  18. data/lib/inkcite/image/image_minifier.rb +143 -0
  19. data/lib/inkcite/image/image_optim_minifier.rb +90 -0
  20. data/lib/inkcite/image/mozjpeg_minifier.rb +92 -0
  21. data/lib/inkcite/mailer.rb +201 -112
  22. data/lib/inkcite/minifier.rb +2 -146
  23. data/lib/inkcite/post_processor.rb +13 -0
  24. data/lib/inkcite/renderer.rb +19 -0
  25. data/lib/inkcite/renderer/background.rb +53 -14
  26. data/lib/inkcite/renderer/base.rb +29 -15
  27. data/lib/inkcite/renderer/button.rb +1 -1
  28. data/lib/inkcite/renderer/carousel.rb +245 -0
  29. data/lib/inkcite/renderer/container_base.rb +10 -0
  30. data/lib/inkcite/renderer/div.rb +1 -3
  31. data/lib/inkcite/renderer/fireworks.rb +54 -40
  32. data/lib/inkcite/renderer/footnote.rb +22 -2
  33. data/lib/inkcite/renderer/image.rb +11 -0
  34. data/lib/inkcite/renderer/image_base.rb +3 -6
  35. data/lib/inkcite/renderer/in_browser.rb +4 -0
  36. data/lib/inkcite/renderer/link.rb +39 -12
  37. data/lib/inkcite/renderer/mobile_image.rb +1 -1
  38. data/lib/inkcite/renderer/responsive.rb +9 -1
  39. data/lib/inkcite/renderer/social.rb +31 -3
  40. data/lib/inkcite/renderer/special_effect.rb +22 -13
  41. data/lib/inkcite/renderer/sup.rb +32 -0
  42. data/lib/inkcite/renderer/table_base.rb +3 -0
  43. data/lib/inkcite/renderer/topic.rb +76 -0
  44. data/lib/inkcite/renderer/trademark.rb +47 -0
  45. data/lib/inkcite/renderer/video_preview.rb +3 -2
  46. data/lib/inkcite/uploader.rb +2 -3
  47. data/lib/inkcite/util.rb +51 -0
  48. data/lib/inkcite/version.rb +1 -1
  49. data/lib/inkcite/view.rb +140 -54
  50. data/lib/inkcite/view/context.rb +1 -31
  51. data/lib/inkcite/view/media_query.rb +6 -0
  52. data/test/animation_spec.rb +7 -0
  53. data/test/parser_spec.rb +1 -1
  54. data/test/renderer/background_spec.rb +16 -12
  55. data/test/renderer/div_spec.rb +11 -0
  56. data/test/renderer/footnote_spec.rb +5 -1
  57. data/test/renderer/image_spec.rb +51 -28
  58. data/test/renderer/link_spec.rb +20 -8
  59. data/test/renderer/lorem_spec.rb +2 -2
  60. data/test/renderer/mobile_image_spec.rb +6 -0
  61. data/test/renderer/mobile_style_spec.rb +3 -3
  62. data/test/renderer/redacted_spec.rb +2 -2
  63. data/test/renderer/social_spec.rb +6 -6
  64. data/test/renderer/table_spec.rb +4 -0
  65. data/test/renderer/topic_spec.rb +28 -0
  66. data/test/renderer/trademark_spec.rb +40 -0
  67. data/test/renderer/video_preview_spec.rb +1 -1
  68. data/test/test_helper.rb +14 -0
  69. data/test/view_spec.rb +4 -0
  70. metadata +26 -12
  71. data/assets/init/image_optim.yml +0 -37
@@ -148,7 +148,7 @@ module Inkcite
148
148
  html << %Q( mobile="fill"}\n)
149
149
  html << "{td align=center"
150
150
  html << " height=#{cfg.height} valign=middle" if cfg.height > 0
151
- html << " font=\"#{cfg.font}\""
151
+ html << %Q( font="#{cfg.font}" color="none")
152
152
  html << " line-height=#{cfg.line_height}" unless cfg.line_height.blank?
153
153
  html << %Q( font-size="#{cfg.font_size}") if cfg.font_size > 0
154
154
  html << %Q( font-weight="#{cfg.font_weight}") unless cfg.font_weight.blank?
@@ -0,0 +1,245 @@
1
+ module Inkcite
2
+ module Renderer
3
+
4
+ # Interactive image carousel based on FreshInbox's technique
5
+ # http://freshinbox.com/resources/tools/carousel/
6
+ #
7
+ # Usage:
8
+ #
9
+ # {carousel width=450 height=280 href="..."}
10
+ # {carousel-img id="..." src="..."}
11
+ # {carousel-img id="..." src="..." href="..."}
12
+ # {carousel-img id="..." src="..."}
13
+ # {/carousel}
14
+ #
15
+ class Carousel < ContainerBase
16
+
17
+ class Image < ImageBase
18
+
19
+ def render tag, opt, ctx
20
+
21
+ # Get a reference to the tag stack that contains these frames
22
+ tag_stack = ctx.tag_stack :carousel
23
+
24
+ # Get the opts held by the parent carousel.
25
+ carousel_opt = tag_stack.opts
26
+
27
+ #opt[:_src] = image_url(opt[:src], opt, ctx, false, false)
28
+
29
+ # Initialize the frames array
30
+ carousel_opt[:frames] << opt
31
+
32
+ nil
33
+ end
34
+
35
+ end
36
+
37
+ def render tag, opt, ctx
38
+
39
+ html = []
40
+
41
+ # Get a reference to the tag stack
42
+ tag_stack = ctx.tag_stack :carousel
43
+
44
+ # All the rendering heavylifting is done when the closing tag is encountered
45
+ # meaning we've indexed each of the carousel-img entries between it and the
46
+ # opening tag.
47
+ if tag == '/carousel'
48
+
49
+ # Remove the previously opened opts from the tag stack.
50
+ open_opt = tag_stack.pop
51
+
52
+ # Unique ID of this carousel to uniquely identify the classes
53
+ uuid = open_opt[:uuid]
54
+
55
+ # Link ID prefix
56
+ carousel_id = open_opt[:id]
57
+
58
+ # Width of the primary image
59
+ width = open_opt[:width].to_i
60
+ height = open_opt[:height].to_i
61
+ ctx.error('Missing carousel dimensions', { :id => carousel_id, :width => width, :height => height }) if height <= 0 || width <= 0
62
+
63
+ # Grab the array of frames and count the total number of frames.
64
+ frames = open_opt[:frames]
65
+ total_frames = frames.count
66
+
67
+ # This {table} Helper wraps the entire carousel.
68
+ table = Element.new('table', :width => width, :class => 'crsl', :mobile => :fill)
69
+
70
+ # Determine if a background color for the entire carousel has been specified
71
+ # using either bgcolor or background-color. If so, pass it on to the table Helper.
72
+ bgcolor = detect_bgcolor(open_opt)
73
+ table[:bgcolor] = quote(bgcolor) unless none?(bgcolor)
74
+
75
+ html << table.to_helper
76
+
77
+ td = Element.new('td')
78
+ mix_font td, open_opt, ctx
79
+ html << td.to_s
80
+
81
+ html << %q({not-outlook})
82
+ html << %q(<input type=radio class="crsl-radio" style="display:none !important;" checked>)
83
+ html << %q({/not-outlook})
84
+
85
+ # Div to hold the carousel contents.
86
+ html << %q({div})
87
+
88
+ html << %q({not-outlook})
89
+ html << Element.new('div', :class => %Q("crsl-wrap crsl-#{uuid}"), :style => {
90
+ :width => pct(100), :height => px(0), MAX_HEIGHT => px(0), :overflow => :hidden, TEXT_ALIGN => :center
91
+ }).to_s
92
+
93
+ # Array of hidden radio buttons that manage which thumbnail is selected.
94
+ total_frames.times do |n|
95
+ box_index = total_frames - n
96
+
97
+ html << %q(<label>)
98
+ html << %Q(<input type="radio" name="crsl#{uuid}" class="crsl-radio-#{box_index}" style="display:none !important;"#{' checked' if box_index == 1}>)
99
+ html << %q(<span>)
100
+
101
+ end
102
+
103
+ total_frames.times do |n|
104
+ box_index = n + 1
105
+ frame_opt = frames[n]
106
+ frame_id = frame_opt[:id] || "#{carousel_id}-#{box_index}"
107
+
108
+ href = frame_opt[:href] || open_opt[:href]
109
+ src = frame_opt[:src]
110
+
111
+ caption = frame_opt[:caption]
112
+ alt = frame_opt[:alt] || caption
113
+
114
+ html << %Q(<div class="crsl-content-#{box_index} crsl-content">)
115
+ html << %Q({a id="#{frame_id}" href="#{href}"}) unless href.blank?
116
+ html << %Q({img src="#{src}" width=#{width} height=#{height} alt="#{alt}" max-height=0 mobile="fill"})
117
+ html << %q({/a}) unless href.blank?
118
+
119
+ unless caption.blank?
120
+ caption_div = Element.new('div', :class => 'crsl-caption', :style => { :padding => '5px 0 10px' })
121
+ mix_font caption_div, open_opt, ctx
122
+ html << caption_div.to_s
123
+ html << caption
124
+ html << '</div>'
125
+ end
126
+
127
+ html << %q(</div>)
128
+
129
+ end
130
+
131
+ thumbnail_width = 50
132
+ thumnail_height = (thumbnail_width / width) * height.round(0)
133
+
134
+ total_frames.times do |n|
135
+ box_index = total_frames - n
136
+ frame_opt = frames[n]
137
+
138
+ src = frame_opt[:src]
139
+
140
+ html << %q(<span class="crsl-thumb" style="display:none;">)
141
+ html << %Q({img src="#{src}" width=#{width} height=#{height} max-height=0})
142
+ html << %q(</span>)
143
+ html << %q(</span>)
144
+ html << %q(</label>)
145
+
146
+ end
147
+
148
+ html << %q(</div>)
149
+ html << %q({/not-outlook})
150
+
151
+ # Fallback
152
+ fallback_frame_opt = frames[0]
153
+ fallback_href = fallback_frame_opt[:href] || open_opt[:href]
154
+ fallback_src = open_opt[OUTLOOK_SRC] || fallback_frame_opt[:src]
155
+
156
+ html << %q(<div class="fallback"><div class="crsl-content">)
157
+ html << %Q({a id="#{carousel_id}" href="#{fallback_href}"}{img src="#{fallback_src}" width=#{width} height=#{height} alt="#{fallback_frame_opt[:caption]}" mobile="fill"}{/a})
158
+ html << %q(</div></div>)
159
+
160
+ html << '{/div}'
161
+ html << '</td>'
162
+ html << '{/table}'
163
+
164
+ styles = []
165
+
166
+ if uuid == 1
167
+
168
+ styles << Inkcite::Renderer::Style.new('input', ctx, { :display => :none })
169
+
170
+ styles << Inkcite::Renderer::Style.new('.crsl-radio:checked + * .crsl-wrap', ctx, { :'height' => 'auto !important', MAX_HEIGHT => 'none !important;', :'line-height' => 0 })
171
+
172
+ styles << Inkcite::Renderer::Style.new('.crsl-wrap span', ctx, { :'font-size' => 0, :'line-height' => 0 })
173
+
174
+ styles << Inkcite::Renderer::Style.new('.crsl-radio:checked + * .crsl-wrap .crsl-content', ctx, { :'display' => 'none', MAX_HEIGHT => px(0), :'overflow' => 'hidden' })
175
+
176
+ styles << Inkcite::Renderer::Style.new('.crsl-wrap .crsl-thumb', ctx, { :cursor => 'pointer', :display => 'inline-block !important', :width => '17.5%', :margin => '1% 0.61%', :border => "2px solid #{DEFAULT_BORDER_COLOR}" })
177
+
178
+ # hide for thunderbird as it doesn't support checkboxes
179
+ styles << Inkcite::Renderer::Style.new('.moz-text-html .crsl-thumb', ctx, { :display => 'none !important' })
180
+
181
+ styles << Inkcite::Renderer::Style.new('.crsl-wrap .crsl-thumb:hover', ctx, { :border => "2px solid #{DEFAULT_HOVER_COLOR}" })
182
+
183
+ styles << Inkcite::Renderer::Style.new('.crsl-wrap input:checked + span > span', ctx, { BORDER_COLOR => DEFAULT_HOVER_COLOR })
184
+
185
+ styles << Inkcite::Renderer::Style.new('.crsl-wrap .crsl-thumb img', ctx, { :width => '100%', :height => 'auto' })
186
+
187
+ styles << Inkcite::Renderer::Style.new('.crsl-wrap img', ctx, { MAX_HEIGHT => 'none !important' })
188
+
189
+ styles << Inkcite::Renderer::Style.new('.crsl-radio:checked + * .fallback', ctx, { :display => 'none !important', MAX_HEIGHT => px(0), :height => px(0), :overflow => 'hidden' })
190
+
191
+ end
192
+
193
+ # Configurable border color
194
+ border_color = open_opt[BORDER_COLOR]
195
+ unless border_color.blank?
196
+ border_color = hex(border_color)
197
+ styles << Inkcite::Renderer::Style.new(".crsl-#{uuid} .crsl-thumb", ctx, { BORDER_COLOR => border_color }) if DEFAULT_BORDER_COLOR != border_color
198
+ end
199
+
200
+ # Configurable hover color
201
+ hover_color = open_opt[:'hover-color']
202
+ unless hover_color.blank?
203
+ hover_color = hex(hover_color)
204
+ if DEFAULT_HOVER_COLOR != hover_color
205
+ styles << Inkcite::Renderer::Style.new(".crsl-#{uuid} input:checked + span > span", ctx, { BORDER_COLOR => hover_color })
206
+ styles << Inkcite::Renderer::Style.new(".crsl-#{uuid} .crsl-thumb:hover", ctx, { BORDER_COLOR => hover_color })
207
+ end
208
+ end
209
+
210
+ frame_checked_style_name = total_frames.times.collect { |n| ".crsl-wrap .crsl-radio-#{n + 1}:checked + span .crsl-content-#{n + 1}" }.join(",\n")
211
+ styles << Inkcite::Renderer::Style.new(frame_checked_style_name, ctx, { :display => 'block !important', MAX_HEIGHT => 'none !important', :overflow => 'visible !important' })
212
+
213
+ ctx.styles << styles.join("\n") unless styles.blank?
214
+
215
+
216
+ else
217
+
218
+ # Get a unique ID for this carousel
219
+ opt[:uuid] = uuid = ctx.unique_id :carousel
220
+
221
+ # Confirm that a unique ID prefix has been provided by the designer or
222
+ # inherit one from the unique count.
223
+ opt[:id] = "crsl#{uuid}" if opt[:id].blank?
224
+
225
+ # Initialize the array of frames that will be collected and
226
+ # assembled when this carousel close tag is encountered.
227
+ opt[:frames] = []
228
+
229
+ # Push this carousel onto the stack as the parent of the
230
+ # frames that will be enclosed.
231
+ tag_stack << opt
232
+
233
+ end
234
+
235
+ html.join("\n")
236
+ end
237
+
238
+ private
239
+
240
+ DEFAULT_HOVER_COLOR = '#444444'
241
+ DEFAULT_BORDER_COLOR = '#bbbbbb'
242
+
243
+ end
244
+ end
245
+ end
@@ -37,6 +37,16 @@ module Inkcite
37
37
  element.to_s
38
38
  end
39
39
 
40
+ def mix_height element, opt, ctx
41
+
42
+ height = opt[:height].to_i
43
+ element.style[:height] = px(height) if height > 0
44
+
45
+ mobile_height = opt[MOBILE_HEIGHT].to_i
46
+ element.mobile_style[:height] = px(mobile_height) if mobile_height > 0
47
+
48
+ end
49
+
40
50
  def mix_width element, opt, ctx
41
51
 
42
52
  width = opt[:width]
@@ -9,9 +9,7 @@ module Inkcite
9
9
  div = Element.new('div')
10
10
 
11
11
  mix_width div, opt, ctx
12
-
13
- height = opt[:height].to_i
14
- div.style[:height] = px(height) if height > 0
12
+ mix_height div, opt, ctx
15
13
 
16
14
  mix_all div, opt, ctx
17
15
  end
@@ -7,16 +7,12 @@ module Inkcite
7
7
 
8
8
  private
9
9
 
10
- # Each firework will move this many positions during the
11
- # entire animation.
12
- TOTAL_POSITIONS = 5
13
-
14
10
  # The number of hue degrees to randomly alter the hue of each spark
15
11
  HUE_RANGE = :'hue-range'
16
12
 
17
13
  # Names of the attributes controlling min and max explosion size.
18
- RADIUS_MIN = :'min-radius'
19
- RADIUS_MAX = :'max-radius'
14
+ DIAMETER_MIN = :'min-diameter'
15
+ DIAMETER_MAX = :'max-diameter'
20
16
 
21
17
  # Attributes used for color generation
22
18
  SATURATION = 100
@@ -26,9 +22,13 @@ module Inkcite
26
22
 
27
23
  count = sfx.count
28
24
 
25
+ # Make sure the total number of stops (formerly TOTAL_POSITIONS)
26
+ # is specified as an integer.
27
+ sfx[:stops] = sfx[:stops].to_i
28
+
29
29
  # Total number of firework instances multiplied by the number
30
30
  # of positions each firework will cycle through.
31
- position_count = TOTAL_POSITIONS * count
31
+ position_count = sfx[:stops] * count
32
32
  positions = sfx.equal_distribution(sfx.position_range, position_count)
33
33
 
34
34
  sfx[:x_positions] = positions
@@ -43,22 +43,30 @@ module Inkcite
43
43
  def create_explosion_animation n, hue, duration, delay, sfx
44
44
 
45
45
  # Calculate the radius size for this explosion
46
- min_radius = sfx[RADIUS_MIN].to_i
47
- max_radius = sfx[RADIUS_MAX].to_i
48
- radius_range = (min_radius..max_radius)
49
- radius = rand(radius_range).round(0)
50
- half_radius = radius / 2.0
46
+ min_diameter = sfx[DIAMETER_MIN].to_i
47
+ max_diameter = sfx[DIAMETER_MAX].to_i
48
+ diameter_range = (min_diameter..max_diameter)
51
49
 
52
50
  hue_range = (sfx[HUE_RANGE] || 40).to_i
53
51
  hue_range_2x = hue_range * 2
54
52
 
55
53
  sparks = sfx[:sparks].to_i
56
54
 
55
+ angle = 0
56
+ angle_step = 360 / sparks.to_f
57
+
57
58
  box_shadow = sparks.times.collect do |n|
58
59
 
60
+ # Pick a random angle.
61
+ angle_radians = angle * PI_OVER_180
62
+ angle += angle_step
63
+
64
+ # Pick a random radius
65
+ radius = rand(diameter_range) / 2.0
66
+
59
67
  # Pick a random position for this spark to move to
60
- x = (rand(radius) - half_radius).round(0)
61
- y = (rand(radius) - half_radius).round(0)
68
+ x = (radius * Math::cos(angle_radians)).round(0)
69
+ y = (radius * Math::sin(angle_radians)).round(0)
62
70
 
63
71
  # Randomly pick a slightly different hue for this spark
64
72
  _hue = hue + hue_range - rand(hue_range_2x)
@@ -70,7 +78,7 @@ module Inkcite
70
78
  anim = Inkcite::Animation.new(sfx.animation_class_name(n, 'bang'), sfx.ctx)
71
79
  anim.duration = duration
72
80
  anim.delay = delay if delay > 0
73
- anim.timing_function = Inkcite::Animation::EASE_OUT
81
+ anim.timing_function = Inkcite::Animation::EASE_OUT_QUART
74
82
  anim.add_keyframe 100, { BOX_SHADOW => box_shadow.join(', ') }
75
83
 
76
84
  sfx.animations << anim
@@ -78,11 +86,11 @@ module Inkcite
78
86
  anim
79
87
  end
80
88
 
81
- def create_gravity_animation sfx
89
+ def create_decay_animation sfx
82
90
 
83
- anim = Animation.new('gravity', sfx.ctx)
91
+ anim = Animation.new(DECAY_ANIMATION_NAME, sfx.ctx)
84
92
 
85
- # All fireworks fade to zero opacity and size by the end of the gravity cycle.
93
+ # All fireworks fade to zero opacity and size by the end of the decay cycle.
86
94
  keyframe = anim.add_keyframe 100, { :opacity => 0, :width => 0, :height => 0 }
87
95
 
88
96
  # Check to see if gravity has been specified for the fireworks. If so
@@ -96,9 +104,7 @@ module Inkcite
96
104
 
97
105
  def create_position_animation n, duration, delay, sfx
98
106
 
99
- # This is the percentage amount of the total animation that will
100
- # be spent in each position.
101
- keyframe_duration = (100 / TOTAL_POSITIONS.to_f)
107
+ stops = sfx[:stops]
102
108
 
103
109
  anim = Inkcite::Animation.new(sfx.animation_class_name(n, 'position'), sfx.ctx)
104
110
  anim.duration = duration
@@ -108,17 +114,27 @@ module Inkcite
108
114
  x_positions = sfx[:x_positions]
109
115
  y_positions = sfx[:y_positions]
110
116
 
117
+ # This is the percentage amount of the total animation that will
118
+ # be spent in each position.
119
+ keyframe_duration = 100.0 / stops.to_f
120
+
111
121
  percent = 0
112
- TOTAL_POSITIONS.times do |n|
122
+ stops.times do |n|
113
123
 
114
124
  # Pick a random position for this firework
115
125
  top = y_positions.delete_at(rand(y_positions.length))
116
126
  left = x_positions.delete_at(rand(x_positions.length))
117
127
 
118
- keyframe = anim.add_keyframe(percent, { :top => pct(top), :left => pct(left) })
119
- keyframe.duration = keyframe_duration - 0.1
128
+ # Calculate when the next keyframe will trigger.
129
+ next_keyframe = percent + keyframe_duration
130
+
131
+ # Calculate when this frame should end
132
+ end_percent = n < stops - 1 ? (next_keyframe - 0.1).round(1) : 100
120
133
 
121
- percent += keyframe_duration
134
+ keyframe = anim.add_keyframe(percent.round(1), { :top => pct(top), :left => pct(left) })
135
+ keyframe.end_percent = end_percent
136
+
137
+ percent = next_keyframe
122
138
  end
123
139
 
124
140
  sfx.animations << anim
@@ -150,10 +166,10 @@ module Inkcite
150
166
  box_shadow = sparks.times.collect { |n| '0 0 #fff' }
151
167
  style[BOX_SHADOW] = box_shadow.join(', ')
152
168
 
153
- # Create the global gravity animation that is consistent for all fireworks.
169
+ # Create the global decay animation that is consistent for all fireworks.
154
170
  # There is no variance in this animation so it is created and added to the
155
171
  # context only once.
156
- create_gravity_animation(sfx)
172
+ create_decay_animation(sfx)
157
173
 
158
174
  end
159
175
 
@@ -185,15 +201,15 @@ module Inkcite
185
201
  # move through each of its positions.
186
202
  position_speed = sfx.rand_speed
187
203
 
188
- # This is the speed the firework animates it's explosion and gravity
204
+ # This is the speed the firework animates it's explosion and decay
189
205
  # components - which need to repeat n-number of times based on the
190
206
  # total number of positions.
191
- explosion_speed = (position_speed / TOTAL_POSITIONS.to_f).round(2)
207
+ explosion_speed = (position_speed / sfx[:stops].to_f).round(2)
192
208
 
193
- gravity_animation = Inkcite::Animation.new('gravity', sfx.ctx)
209
+ gravity_animation = Inkcite::Animation.new(DECAY_ANIMATION_NAME, sfx.ctx)
194
210
  gravity_animation.duration = explosion_speed
195
211
  gravity_animation.delay = delay if n > 0
196
- gravity_animation.timing_function = Inkcite::Animation::EASE_IN
212
+ gravity_animation.timing_function = Inkcite::Animation::EASE_IN_CUBIC
197
213
 
198
214
  composite_animation = Inkcite::Animation::Composite.new
199
215
  composite_animation << create_explosion_animation(n, hue, explosion_speed, delay, sfx)
@@ -202,13 +218,6 @@ module Inkcite
202
218
 
203
219
  style[:animation] = composite_animation
204
220
 
205
- # # Each firework consists of three separate animations - one to animate
206
- # # the explosion, one to fade out/apply gravity and one to move the
207
- # # firework through it's fixed positions.
208
- # style[:animation] = "1s bang ease-out infinite, 1s gravity ease-in infinite, #{TOTAL_POSITIONS}s position linear infinite"
209
-
210
- # style[ANIMATION_DURATION] = "#{explosion_speed}s, #{explosion_speed}s, #{position_speed}s"
211
-
212
221
  end
213
222
 
214
223
  def defaults opt, ctx
@@ -217,15 +226,20 @@ module Inkcite
217
226
  :sparks => 50,
218
227
  :count => 2,
219
228
  :gravity => 200,
220
- RADIUS_MIN => 150,
221
- RADIUS_MAX => 400,
229
+ DIAMETER_MIN => 25,
230
+ DIAMETER_MAX => 200,
222
231
  SIZE_MIN => 10,
223
232
  SIZE_MAX => 10,
224
233
  SPEED_MIN => 5,
225
234
  SPEED_MAX => 10,
235
+ :stops => 5,
226
236
  }
227
237
  end
228
238
 
239
+ private
240
+
241
+ DECAY_ANIMATION_NAME = 'decay'
242
+
229
243
  end
230
244
  end
231
245
  end