inkcite 1.13.0 → 1.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/inkcite.gemspec +1 -0
- data/lib/inkcite.rb +1 -1
- data/lib/inkcite/cli/server.rb +31 -6
- data/lib/inkcite/facade.rb +6 -0
- data/lib/inkcite/{animation.rb → facade/animation.rb} +19 -56
- data/lib/inkcite/{renderer → facade}/element.rb +0 -0
- data/lib/inkcite/facade/keyframe.rb +83 -0
- data/lib/inkcite/{renderer → facade}/style.rb +4 -0
- data/lib/inkcite/minifier.rb +141 -57
- data/lib/inkcite/parser.rb +1 -1
- data/lib/inkcite/renderer.rb +2 -2
- data/lib/inkcite/renderer/background.rb +1 -1
- data/lib/inkcite/renderer/base.rb +1 -1
- data/lib/inkcite/renderer/container_base.rb +3 -4
- data/lib/inkcite/renderer/fireworks.rb +231 -0
- data/lib/inkcite/renderer/in_browser.rb +1 -2
- data/lib/inkcite/renderer/responsive.rb +29 -2
- data/lib/inkcite/renderer/snow.rb +1 -1
- data/lib/inkcite/renderer/special_effect.rb +66 -29
- data/lib/inkcite/renderer/table_base.rb +6 -0
- data/lib/inkcite/renderer/td.rb +7 -2
- data/lib/inkcite/renderer/video_preview.rb +7 -1
- data/lib/inkcite/util.rb +56 -0
- data/lib/inkcite/version.rb +1 -1
- data/lib/inkcite/view.rb +42 -1
- data/test/animation_spec.rb +38 -5
- data/test/renderer/div_spec.rb +30 -0
- data/test/renderer/td_spec.rb +25 -0
- data/test/renderer/video_preview_spec.rb +1 -1
- data/test/util_spec.rb +11 -0
- metadata +24 -5
data/lib/inkcite/parser.rb
CHANGED
@@ -22,7 +22,7 @@ module Inkcite
|
|
22
22
|
# Provide the block with the area that was matched, sans wrapper brackets.
|
23
23
|
# Replace the brackets and original value with the block's results.
|
24
24
|
result = yield(match[1].to_s) || EMPTY_STRING
|
25
|
-
str[offset.first, offset.last - offset.first] = result
|
25
|
+
str[offset.first, offset.last - offset.first] = result.to_s
|
26
26
|
|
27
27
|
# Ensure we don't infinite loop.
|
28
28
|
failsafe += 1
|
data/lib/inkcite/renderer.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
require_relative 'renderer/base'
|
2
|
-
require_relative 'renderer/element'
|
3
2
|
require_relative 'renderer/responsive'
|
4
3
|
require_relative 'renderer/container_base'
|
5
4
|
require_relative 'renderer/special_effect'
|
6
5
|
require_relative 'renderer/image_base'
|
7
6
|
require_relative 'renderer/table_base'
|
8
|
-
require_relative 'renderer/style'
|
9
7
|
|
10
8
|
require_relative 'renderer/background'
|
11
9
|
require_relative 'renderer/button'
|
12
10
|
require_relative 'renderer/div'
|
11
|
+
require_relative 'renderer/fireworks'
|
13
12
|
require_relative 'renderer/footnote'
|
14
13
|
require_relative 'renderer/google_analytics'
|
15
14
|
require_relative 'renderer/image'
|
@@ -174,6 +173,7 @@ module Inkcite
|
|
174
173
|
:button => Button.new,
|
175
174
|
:div => Div.new,
|
176
175
|
:facebook => Social::Facebook.new,
|
176
|
+
:fireworks => Fireworks.new,
|
177
177
|
:footnote => Footnote.new,
|
178
178
|
:footnotes => Footnotes.new,
|
179
179
|
:google => GoogleAnalytics.new,
|
@@ -145,7 +145,7 @@ module Inkcite
|
|
145
145
|
BACKGROUND_POSITION, :border, BORDER_BOTTOM, BORDER_LEFT, BORDER_RADIUS, BORDER_RIGHT,
|
146
146
|
BORDER_SPACING, BORDER_TOP, :mobile, MOBILE_BGCOLOR, MOBILE_BACKGROUND, MOBILE_BACKGROUND_COLOR,
|
147
147
|
MOBILE_BACKGROUND_IMAGE, MOBILE_BACKGROUND_REPEAT, MOBILE_BACKGROUND_POSITION, MOBILE_PADDING,
|
148
|
-
MOBILE_SRC, MOBILE_BACKGROUND_SIZE
|
148
|
+
MOBILE_SRC, MOBILE_BACKGROUND_SIZE, MOBILE_WIDTH
|
149
149
|
]
|
150
150
|
|
151
151
|
end
|
@@ -168,7 +168,7 @@ module Inkcite
|
|
168
168
|
dir_opt_key = add_directional_suffix(opt_key, dir)
|
169
169
|
dir_css_key = add_directional_suffix(css_key, dir)
|
170
170
|
value = opt[dir_opt_key]
|
171
|
-
next if
|
171
|
+
next if value.blank?
|
172
172
|
|
173
173
|
value = px(value) if as_px
|
174
174
|
into[dir_css_key] = value
|
@@ -18,10 +18,6 @@ module Inkcite
|
|
18
18
|
padding = opt[:padding]
|
19
19
|
element.style[:padding] = px(padding) unless none?(padding)
|
20
20
|
|
21
|
-
# Supports custom padding on mobile - e.g. mobile-padding="15px 5px"
|
22
|
-
mobile_padding = opt[MOBILE_PADDING]
|
23
|
-
element.mobile_style[:padding] = px(mobile_padding) unless none?(mobile_padding)
|
24
|
-
|
25
21
|
# Vertical alignment - top, middle, bottom.
|
26
22
|
valign = opt[:valign]
|
27
23
|
element.style[VERTICAL_ALIGN] = valign unless none?(valign)
|
@@ -33,6 +29,9 @@ module Inkcite
|
|
33
29
|
# style to the element.
|
34
30
|
element.style[WHITE_SPACE] = :nowrap if opt[:nowrap]
|
35
31
|
|
32
|
+
# Support for mobile-padding and mobile-padding-(direction)
|
33
|
+
mix_mobile_padding element, opt, ctx
|
34
|
+
|
36
35
|
mix_responsive element, opt, ctx
|
37
36
|
|
38
37
|
element.to_s
|
@@ -0,0 +1,231 @@
|
|
1
|
+
module Inkcite
|
2
|
+
module Renderer
|
3
|
+
|
4
|
+
# Animated CSS fireworks special effect based on the technique
|
5
|
+
# by Eddie Lin https://codepen.io/yshlin/pen/ylDEk
|
6
|
+
class Fireworks < SpecialEffect
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
# Each firework will move this many positions during the
|
11
|
+
# entire animation.
|
12
|
+
TOTAL_POSITIONS = 5
|
13
|
+
|
14
|
+
# The number of hue degrees to randomly alter the hue of each spark
|
15
|
+
HUE_RANGE = :'hue-range'
|
16
|
+
|
17
|
+
# Names of the attributes controlling min and max explosion size.
|
18
|
+
RADIUS_MIN = :'min-radius'
|
19
|
+
RADIUS_MAX = :'max-radius'
|
20
|
+
|
21
|
+
# Attributes used for color generation
|
22
|
+
SATURATION = 100
|
23
|
+
LUMINANCE = 50
|
24
|
+
|
25
|
+
def config_effect_context sfx
|
26
|
+
|
27
|
+
count = sfx.count
|
28
|
+
|
29
|
+
# Total number of firework instances multiplied by the number
|
30
|
+
# of positions each firework will cycle through.
|
31
|
+
position_count = TOTAL_POSITIONS * count
|
32
|
+
positions = sfx.equal_distribution(sfx.position_range, position_count)
|
33
|
+
|
34
|
+
sfx[:x_positions] = positions
|
35
|
+
sfx[:y_positions] = positions.dup
|
36
|
+
|
37
|
+
# Equal distribution of hues based on the number of fireworks
|
38
|
+
# if the rainbow option is selected
|
39
|
+
sfx[:hues] = sfx.equal_distribution(0..360, count)
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_explosion_animation n, hue, duration, delay, sfx
|
44
|
+
|
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
|
51
|
+
|
52
|
+
hue_range = (sfx[HUE_RANGE] || 40).to_i
|
53
|
+
hue_range_2x = hue_range * 2
|
54
|
+
|
55
|
+
sparks = sfx[:sparks].to_i
|
56
|
+
|
57
|
+
box_shadow = sparks.times.collect do |n|
|
58
|
+
|
59
|
+
# 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)
|
62
|
+
|
63
|
+
# Randomly pick a slightly different hue for this spark
|
64
|
+
_hue = hue + hue_range - rand(hue_range_2x)
|
65
|
+
color = Inkcite::Util::hsl_to_color(_hue, SATURATION, LUMINANCE)
|
66
|
+
|
67
|
+
"#{px(x)} #{px(y)} #{color}"
|
68
|
+
end
|
69
|
+
|
70
|
+
anim = Inkcite::Animation.new(sfx.animation_class_name(n, 'bang'), sfx.ctx)
|
71
|
+
anim.duration = duration
|
72
|
+
anim.delay = delay if delay > 0
|
73
|
+
anim.timing_function = Inkcite::Animation::EASE_OUT
|
74
|
+
anim.add_keyframe 100, { BOX_SHADOW => box_shadow.join(', ') }
|
75
|
+
|
76
|
+
sfx.animations << anim
|
77
|
+
|
78
|
+
anim
|
79
|
+
end
|
80
|
+
|
81
|
+
def create_gravity_animation sfx
|
82
|
+
|
83
|
+
anim = Animation.new('gravity', sfx.ctx)
|
84
|
+
|
85
|
+
# All fireworks fade to zero opacity and size by the end of the gravity cycle.
|
86
|
+
keyframe = anim.add_keyframe 100, { :opacity => 0, :width => 0, :height => 0 }
|
87
|
+
|
88
|
+
# Check to see if gravity has been specified for the fireworks. If so
|
89
|
+
# apply it as a vertical translation (positive equals downward)
|
90
|
+
gravity = sfx[:gravity].to_i
|
91
|
+
keyframe[:transform] = "translateY(#{px(gravity)})" if gravity != 0
|
92
|
+
|
93
|
+
sfx.animations << anim
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
def create_position_animation n, duration, delay, sfx
|
98
|
+
|
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)
|
102
|
+
|
103
|
+
anim = Inkcite::Animation.new(sfx.animation_class_name(n, 'position'), sfx.ctx)
|
104
|
+
anim.duration = duration
|
105
|
+
anim.delay = delay if delay > 0
|
106
|
+
anim.timing_function = Inkcite::Animation::LINEAR
|
107
|
+
|
108
|
+
x_positions = sfx[:x_positions]
|
109
|
+
y_positions = sfx[:y_positions]
|
110
|
+
|
111
|
+
percent = 0
|
112
|
+
TOTAL_POSITIONS.times do |n|
|
113
|
+
|
114
|
+
# Pick a random position for this firework
|
115
|
+
top = y_positions.delete_at(rand(y_positions.length))
|
116
|
+
left = x_positions.delete_at(rand(x_positions.length))
|
117
|
+
|
118
|
+
keyframe = anim.add_keyframe(percent, { :top => pct(top), :left => pct(left) })
|
119
|
+
keyframe.duration = keyframe_duration - 0.1
|
120
|
+
|
121
|
+
percent += keyframe_duration
|
122
|
+
end
|
123
|
+
|
124
|
+
sfx.animations << anim
|
125
|
+
|
126
|
+
anim
|
127
|
+
end
|
128
|
+
|
129
|
+
protected
|
130
|
+
|
131
|
+
def config_all_children style, sfx
|
132
|
+
|
133
|
+
# If all of the sparks in the firework have the same size
|
134
|
+
# (e.g. min-size equals max-size) then save some CSS space
|
135
|
+
# by defining it once for all children.
|
136
|
+
if sfx.same_size?
|
137
|
+
style[:width] = px(sfx.min_size)
|
138
|
+
style[:height] = px(sfx.min_size)
|
139
|
+
end
|
140
|
+
|
141
|
+
# Make sure all explosions start off-screen.
|
142
|
+
style[:top] = "-#{px(sfx.max_size)}"
|
143
|
+
|
144
|
+
style[BORDER_RADIUS] = '50%'
|
145
|
+
|
146
|
+
sparks = sfx[:sparks].to_i
|
147
|
+
|
148
|
+
# All sparks start with a box shadow at their exact center,
|
149
|
+
# all in white.
|
150
|
+
box_shadow = sparks.times.collect { |n| '0 0 #fff' }
|
151
|
+
style[BOX_SHADOW] = box_shadow.join(', ')
|
152
|
+
|
153
|
+
# Create the global gravity animation that is consistent for all fireworks.
|
154
|
+
# There is no variance in this animation so it is created and added to the
|
155
|
+
# context only once.
|
156
|
+
create_gravity_animation(sfx)
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
def config_child n, child, style, animation, sfx
|
161
|
+
|
162
|
+
# If all of the fireworks are different possible sizes
|
163
|
+
# then pick a random size for this child.
|
164
|
+
unless sfx.same_size?
|
165
|
+
size = sfx.rand_size
|
166
|
+
style[:width] = px(size)
|
167
|
+
style[:height] = px(size)
|
168
|
+
end
|
169
|
+
|
170
|
+
# If rainbow is specified, choose the next color in the array - otherwise
|
171
|
+
# choose a random hue unless a specific one has been specified.
|
172
|
+
hue = sfx[:rainbow] ? sfx[:hues][n] : (sfx[:hue] || rand(360)).to_i
|
173
|
+
|
174
|
+
# Randomly pick a color for this explosion by choosing a
|
175
|
+
# random hue and then converting it to a hex color
|
176
|
+
color = Inkcite::Util::hsl_to_color(hue, 100, 50)
|
177
|
+
style[BACKGROUND_COLOR] = color
|
178
|
+
|
179
|
+
# After the first child, each firework should have a random
|
180
|
+
# delay before its animation starts - giving the different
|
181
|
+
# fireworks a staggered launch.
|
182
|
+
delay = n > 0 ? 0.25 + rand(sfx.count).round(2) : 0
|
183
|
+
|
184
|
+
# This is the total amount of time it will take the firework to
|
185
|
+
# move through each of its positions.
|
186
|
+
position_speed = sfx.rand_speed
|
187
|
+
|
188
|
+
# This is the speed the firework animates it's explosion and gravity
|
189
|
+
# components - which need to repeat n-number of times based on the
|
190
|
+
# total number of positions.
|
191
|
+
explosion_speed = (position_speed / TOTAL_POSITIONS.to_f).round(2)
|
192
|
+
|
193
|
+
gravity_animation = Inkcite::Animation.new('gravity', sfx.ctx)
|
194
|
+
gravity_animation.duration = explosion_speed
|
195
|
+
gravity_animation.delay = delay if n > 0
|
196
|
+
gravity_animation.timing_function = Inkcite::Animation::EASE_IN
|
197
|
+
|
198
|
+
composite_animation = Inkcite::Animation::Composite.new
|
199
|
+
composite_animation << create_explosion_animation(n, hue, explosion_speed, delay, sfx)
|
200
|
+
composite_animation << gravity_animation
|
201
|
+
composite_animation << create_position_animation(n, position_speed, delay, sfx)
|
202
|
+
|
203
|
+
style[:animation] = composite_animation
|
204
|
+
|
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
|
+
end
|
213
|
+
|
214
|
+
def defaults opt, ctx
|
215
|
+
{
|
216
|
+
:bgcolor => '#000000',
|
217
|
+
:sparks => 50,
|
218
|
+
:count => 2,
|
219
|
+
:gravity => 200,
|
220
|
+
RADIUS_MIN => 150,
|
221
|
+
RADIUS_MAX => 400,
|
222
|
+
SIZE_MIN => 10,
|
223
|
+
SIZE_MAX => 10,
|
224
|
+
SPEED_MIN => 5,
|
225
|
+
SPEED_MAX => 10,
|
226
|
+
}
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
module Inkcite
|
3
2
|
module Renderer
|
4
3
|
class InBrowser < Base
|
@@ -20,7 +19,7 @@ module Inkcite
|
|
20
19
|
color = opt[:color]
|
21
20
|
|
22
21
|
# Optional call-to-action override - otherwise defaults to view in browser.
|
23
|
-
cta = opt[:cta] || ctx.production?? 'View
|
22
|
+
cta = opt[:cta] || ctx.production?? 'View in Browser' : 'Preview in Browser'
|
24
23
|
|
25
24
|
id = opt[:id] || 'in-browser'
|
26
25
|
|
@@ -28,8 +28,9 @@ module Inkcite
|
|
28
28
|
MOBILE_SRC = :'mobile-src'
|
29
29
|
|
30
30
|
# Other mobile-specific properties
|
31
|
+
MOBILE_HEIGHT = :'mobile-height'
|
31
32
|
MOBILE_PADDING = :'mobile-padding'
|
32
|
-
|
33
|
+
MOBILE_WIDTH = :'mobile-width'
|
33
34
|
|
34
35
|
class Rule
|
35
36
|
|
@@ -241,8 +242,28 @@ module Inkcite
|
|
241
242
|
mix_directional element, element.mobile_style, opt, ctx, MOBILE_MARGIN, :margin, true
|
242
243
|
end
|
243
244
|
|
245
|
+
def mix_mobile_padding element, opt, ctx
|
246
|
+
mix_directional element, element.mobile_style, opt, ctx, MOBILE_PADDING, :padding, true
|
247
|
+
end
|
248
|
+
|
249
|
+
# A separate method for mixing in text alignment because the table cell
|
250
|
+
# helper handles alignment different from normal container elements.
|
251
|
+
def mix_mobile_text_align element, opt, ctx
|
252
|
+
|
253
|
+
# Support for mobile-text-align
|
254
|
+
align = opt[MOBILE_TEXT_ALIGN]
|
255
|
+
element.mobile_style[TEXT_ALIGN] = align unless none?(align)
|
256
|
+
|
257
|
+
end
|
258
|
+
|
244
259
|
def mix_responsive element, opt, ctx, klass=nil
|
245
260
|
|
261
|
+
mobile_style = opt[MOBILE_STYLE]
|
262
|
+
ctx.error 'mobile-style is no longer supported', { :element => element.to_s, MOBILE_STYLE => mobile_style } unless mobile_style.blank?
|
263
|
+
|
264
|
+
mobile_display = opt[MOBILE_DISPLAY]
|
265
|
+
element.mobile_style[:display] = mobile_display unless none?(mobile_display)
|
266
|
+
|
246
267
|
# Apply the "mobile" attribute or use the override if one was provided.
|
247
268
|
mix_responsive_klass element, opt, ctx, klass || opt[:mobile]
|
248
269
|
|
@@ -398,6 +419,11 @@ module Inkcite
|
|
398
419
|
|
399
420
|
end
|
400
421
|
|
422
|
+
def mix_text_align element, opt, ctx
|
423
|
+
super
|
424
|
+
mix_mobile_text_align element, opt, ctx
|
425
|
+
end
|
426
|
+
|
401
427
|
def unique_klass ctx
|
402
428
|
'm%1d' % ctx.unique_id(:m)
|
403
429
|
end
|
@@ -406,9 +432,10 @@ module Inkcite
|
|
406
432
|
|
407
433
|
# Attribute used to declare custom mobile styles for an element.
|
408
434
|
MOBILE_BORDER = :'mobile-border'
|
435
|
+
MOBILE_DISPLAY = :'mobile-display'
|
409
436
|
MOBILE_MARGIN = :'mobile-margin'
|
410
437
|
MOBILE_STYLE = :'mobile-style'
|
411
|
-
|
438
|
+
MOBILE_TEXT_ALIGN = :'mobile-text-align'
|
412
439
|
|
413
440
|
# Universal CSS selector.
|
414
441
|
UNIVERSAL = '*'
|
@@ -6,7 +6,7 @@ module Inkcite
|
|
6
6
|
# common to special effects like snow and sparkle.
|
7
7
|
class EffectContext
|
8
8
|
|
9
|
-
attr_reader :uuid
|
9
|
+
attr_reader :uuid, :animations
|
10
10
|
|
11
11
|
# Expose the opt and ctx attributes
|
12
12
|
attr_reader :opt, :ctx
|
@@ -31,14 +31,26 @@ module Inkcite
|
|
31
31
|
# this special effect.
|
32
32
|
@uuid = ctx.unique_id(:sfx)
|
33
33
|
|
34
|
+
# Will hold all of the Animations while the children are
|
35
|
+
# assembled and then added to the styles array at the end
|
36
|
+
# so that all keyframes are together in the source.
|
37
|
+
@animations = []
|
38
|
+
|
34
39
|
end
|
35
40
|
|
36
41
|
def all_children_class_name
|
37
42
|
obfuscate_class_names? ? "sfx#{@uuid}c" : "#{@tag}#{@uuid}-children"
|
38
43
|
end
|
39
44
|
|
40
|
-
def animation_class_name child_index
|
41
|
-
|
45
|
+
def animation_class_name child_index, suffix=nil
|
46
|
+
|
47
|
+
base = obfuscate_class_names? ? "#{@tag}#{@uuid}-anim#{child_index + 1}" : "sfx#{@uuid}a#{child_index + 1}"
|
48
|
+
unless suffix.blank?
|
49
|
+
base << '-'
|
50
|
+
base << (obfuscate_class_names? ? suffix[0] : suffix)
|
51
|
+
end
|
52
|
+
|
53
|
+
base
|
42
54
|
end
|
43
55
|
|
44
56
|
def child_class_name child_index
|
@@ -53,19 +65,19 @@ module Inkcite
|
|
53
65
|
# of snowflakes or sparkles in the animation. :flakes and :sparks are
|
54
66
|
# technically deprecated.
|
55
67
|
def count
|
56
|
-
|
68
|
+
@opt[:count].to_i
|
57
69
|
end
|
58
70
|
|
59
|
-
def equal_distribution qty
|
71
|
+
def equal_distribution range, qty
|
60
72
|
|
61
73
|
# Space the children generally equally across the width of the
|
62
74
|
# container div. Random distribution sometimes ends up with
|
63
75
|
# children clumped at one edge or the other.
|
64
|
-
spacing =
|
76
|
+
spacing = (range.last - range.first) / qty.to_f
|
65
77
|
|
66
78
|
# Now build up a pool of equally-spaced starting positions.
|
67
79
|
# TODO: This is probably a perfect spot to use inject()
|
68
|
-
start_left = spacing / 2.0
|
80
|
+
start_left = range.first + (spacing / 2.0)
|
69
81
|
|
70
82
|
# This array will hold all of the positions
|
71
83
|
positions = [start_left]
|
@@ -74,13 +86,17 @@ module Inkcite
|
|
74
86
|
# spacing and push onto the list.
|
75
87
|
(qty - 1).times { |f| positions << start_left += spacing }
|
76
88
|
|
77
|
-
positions
|
89
|
+
positions.collect { |p| p.round(0) }
|
78
90
|
end
|
79
91
|
|
80
92
|
def height
|
81
93
|
@opt[:height].to_i
|
82
94
|
end
|
83
95
|
|
96
|
+
def insets
|
97
|
+
@opt[:insets].to_i
|
98
|
+
end
|
99
|
+
|
84
100
|
def max_opacity
|
85
101
|
@opt[OPACITY_MAX].to_f
|
86
102
|
end
|
@@ -106,7 +122,7 @@ module Inkcite
|
|
106
122
|
end
|
107
123
|
|
108
124
|
def obfuscate_class_names?
|
109
|
-
|
125
|
+
@ctx.production?
|
110
126
|
end
|
111
127
|
|
112
128
|
def opacity_range
|
@@ -137,6 +153,10 @@ module Inkcite
|
|
137
153
|
(-270..270)
|
138
154
|
end
|
139
155
|
|
156
|
+
def same_size?
|
157
|
+
min_size == max_size
|
158
|
+
end
|
159
|
+
|
140
160
|
def size_range
|
141
161
|
(min_size..max_size)
|
142
162
|
end
|
@@ -159,18 +179,24 @@ module Inkcite
|
|
159
179
|
@src
|
160
180
|
end
|
161
181
|
|
182
|
+
def position_range
|
183
|
+
min = POSITION_FLOOR + insets
|
184
|
+
max = POSITION_CEIL - insets
|
185
|
+
(min..max)
|
186
|
+
end
|
187
|
+
|
162
188
|
# Creates a permanent list of positions (as percentages of the wrap container's
|
163
189
|
# total width) which can be used for starting or ending position to equally
|
164
190
|
# space animated elements.
|
165
191
|
def positions_x
|
166
|
-
@positions_x ||= equal_distribution(count)
|
192
|
+
@positions_x ||= equal_distribution(position_range, count)
|
167
193
|
end
|
168
194
|
|
169
195
|
# Creates a permanent list of positions (as percentages of the wrap container's
|
170
196
|
# total height) which can be used for starting or ending position to equally
|
171
197
|
# space animated elements.
|
172
198
|
def positions_y
|
173
|
-
@positions_y ||= equal_distribution(count)
|
199
|
+
@positions_y ||= equal_distribution(position_range, count)
|
174
200
|
end
|
175
201
|
|
176
202
|
def start_time child_index
|
@@ -247,6 +273,10 @@ module Inkcite
|
|
247
273
|
# at the same time.
|
248
274
|
create_child_elements html, styles, sfx
|
249
275
|
|
276
|
+
# Append all of the Keyframes to the end of the styles, now that
|
277
|
+
# the individual children are configured.
|
278
|
+
sfx.animations.each { |a| styles << a.to_keyframe_css }
|
279
|
+
|
250
280
|
# Push the completed list of styles into the context's stack.
|
251
281
|
ctx.styles << styles.join("\n")
|
252
282
|
|
@@ -274,10 +304,14 @@ module Inkcite
|
|
274
304
|
OPACITY_MAX = :'max-opacity'
|
275
305
|
OPACITY_CEIL = 1.0
|
276
306
|
|
307
|
+
# Static constants for animation-specific CSS
|
308
|
+
ANIMATION_DELAY = :'animation-delay'
|
309
|
+
ANIMATION_DURATION = :'animation-duration'
|
310
|
+
|
277
311
|
# The extending class can override this method to perform any
|
278
312
|
# additional configuration on the style that affects all
|
279
313
|
# children in the animation.
|
280
|
-
def
|
314
|
+
def config_all_children style, sfx
|
281
315
|
# This space left intentionally blank
|
282
316
|
end
|
283
317
|
|
@@ -333,7 +367,7 @@ module Inkcite
|
|
333
367
|
|
334
368
|
# Provide the extending class with a chance to apply additional
|
335
369
|
# styles to all children.
|
336
|
-
|
370
|
+
config_all_children style, sfx
|
337
371
|
|
338
372
|
styles << style
|
339
373
|
|
@@ -343,11 +377,6 @@ module Inkcite
|
|
343
377
|
# CSS classes to them allowing each to be sized, animated uniquely.
|
344
378
|
def create_child_elements html, styles, sfx
|
345
379
|
|
346
|
-
# Will hold all of the Animations while the children are
|
347
|
-
# assembled and then added to the styles array at the end
|
348
|
-
# so that all keyframes are together in the source.
|
349
|
-
animations = []
|
350
|
-
|
351
380
|
sfx.count.times do |n|
|
352
381
|
|
353
382
|
child_class_name = sfx.child_class_name(n)
|
@@ -365,20 +394,28 @@ module Inkcite
|
|
365
394
|
# and its style.
|
366
395
|
config_child n, child, style, animation, sfx
|
367
396
|
|
368
|
-
#
|
369
|
-
# style - this adds itself with the appropriate browser prefixes.
|
370
|
-
style[:animation] = animation
|
371
|
-
|
372
|
-
# Inject the various pieces into the appropriate lists.
|
397
|
+
# Add the child's HTML element into the email.
|
373
398
|
html << child.to_s + '</div>'
|
374
|
-
styles << style
|
375
|
-
animations << animation
|
376
399
|
|
377
|
-
|
400
|
+
# If the extending class actually defined an animation for this child
|
401
|
+
# then assign it and add it to the list of animations to be appended
|
402
|
+
# after the styles are injected.
|
403
|
+
unless animation.blank?
|
378
404
|
|
379
|
-
|
380
|
-
|
381
|
-
|
405
|
+
sfx.animations << animation
|
406
|
+
|
407
|
+
# If the extending class didn't assign the animation already, then
|
408
|
+
# assign it to the child's style - this adds itself with the appropriate
|
409
|
+
# browser prefixes.
|
410
|
+
style[:animation] = animation if style[:animation].blank?
|
411
|
+
|
412
|
+
end
|
413
|
+
|
414
|
+
# Append the child's custom style, unless blank (meaning the extending
|
415
|
+
# class did not customize the child's styles directly).
|
416
|
+
styles << style unless style.blank?
|
417
|
+
|
418
|
+
end
|
382
419
|
|
383
420
|
end
|
384
421
|
|