Class: AnimateIt::Scene
- Inherits:
-
Object
- Object
- AnimateIt::Scene
- Includes:
- AnimationHelpers, ViewHelpers
- Defined in:
- lib/animate_it/scene.rb
Class Attribute Summary collapse
-
.composition_class ⇒ Object
Composition class this scene belongs to.
-
.current_frame ⇒ Object
Set automatically at the start of every
renderto the scene's current local_frame.
Instance Attribute Summary collapse
-
#context ⇒ Object
readonly
Returns the value of attribute context.
-
#props ⇒ Object
readonly
Returns the value of attribute props.
-
#view_context ⇒ Object
readonly
Returns the value of attribute view_context.
Class Method Summary collapse
-
.animate(name, &block) ⇒ Object
Declare an animatable element by name.
- .animations ⇒ Object
-
.canvas_class(value = nil) ⇒ Object
Outer wrapper class for the scene's content.
-
.disable_fragment_caching! ⇒ Object
Toggles fragment caching off for the rendering controller before
bodyruns. -
.fixtures(seed: nil, &block) ⇒ Object
Declare a class-level fixture builder.
- .fragment_caching_disabled? ⇒ Boolean
- .reset_fixtures! ⇒ Object
-
.stub_methods(object, **stubs) ⇒ Object
Class-side mirror of ViewHelpers#stub_methods so class-method fixture builders (which run before any Scene instance exists) can also use the helper to define singleton-method stubs on build_stubbed records.
-
.template(name = nil) ⇒ Object
Sidecar template name.
Instance Method Summary collapse
-
#animation_vars(**extras) ⇒ Object
CSS var bag computed from this frame's animations.
-
#body ⇒ Object
Default markup: canvas wrapper + sidecar template + auto-generated animation CSS.
-
#expose(*keys, from: nil, **ivars) ⇒ Object
Set ivars on the view_context so templates rendered via
render_scene_template/view_context.render(template:)can read them as@foo. -
#initialize(context:, props:) ⇒ Scene
constructor
A new instance of Scene.
-
#render(view_context) ⇒ Object
Stash view_context so helpers (
tag,safe_join,capture) work, then callbodyfor the actual markup. -
#with_canvas(&block) ⇒ Object
Convenience: when a subclass overrides
renderit can call this to get the same wrapper + animation-var div around custom content.
Methods included from ViewHelpers
#absolute_fill, #build_factory, #build_stubbed, #motion_asset, #motion_image, #render_partial, #render_scene_template, #render_template, #stub_methods, #style
Methods included from AnimationHelpers
#act_local, #at_act, #at_global, #beat_end, #beat_frame, #beat_range, #fade, #freeze_frame, #interpolate_range, #loop_frame, #loop_iteration, #press, #pulse, #slide
Constructor Details
#initialize(context:, props:) ⇒ Scene
Returns a new instance of Scene.
8 9 10 11 |
# File 'lib/animate_it/scene.rb', line 8 def initialize(context:, props:) @context = context @props = props end |
Class Attribute Details
.composition_class ⇒ Object
Composition class this scene belongs to. Set by the engine when the
scene is mounted via composition.scene MyScene / single-scene
auto-mount; lets animation property procs reach Composition.beats.
53 54 55 |
# File 'lib/animate_it/scene.rb', line 53 def composition_class @composition_class end |
.current_frame ⇒ Object
Set automatically at the start of every render to the scene's
current local_frame. Fixture closures (e.g. a singleton-method
stub that needs to vary by frame) can call MyScene.current_frame
without the scene having to remember to assign it in body.
59 60 61 |
# File 'lib/animate_it/scene.rb', line 59 def current_frame @current_frame end |
Instance Attribute Details
#context ⇒ Object (readonly)
Returns the value of attribute context.
6 7 8 |
# File 'lib/animate_it/scene.rb', line 6 def context @context end |
#props ⇒ Object (readonly)
Returns the value of attribute props.
6 7 8 |
# File 'lib/animate_it/scene.rb', line 6 def props @props end |
#view_context ⇒ Object (readonly)
Returns the value of attribute view_context.
6 7 8 |
# File 'lib/animate_it/scene.rb', line 6 def view_context @view_context end |
Class Method Details
.animate(name, &block) ⇒ Object
Declare an animatable element by name. Animation properties are attached via the block:
animate :step_1 do
fade during: 10..30
during: 10..30, from: 16
end
The framework auto-generates the [data-anim="step_1"] CSS rules
and the per-frame CSS variables — no :css block in the HAML.
42 43 44 |
# File 'lib/animate_it/scene.rb', line 42 def animate(name, &block) animations.add(name, block) end |
.animations ⇒ Object
46 47 48 |
# File 'lib/animate_it/scene.rb', line 46 def animations @animations ||= AnimationSet.new end |
.canvas_class(value = nil) ⇒ Object
Outer wrapper class for the scene's content. Defaults to "hero-render-canvas" (the convention used by all current heros).
27 28 29 30 |
# File 'lib/animate_it/scene.rb', line 27 def canvas_class(value = nil) @canvas_class = value.to_s if value @canvas_class ||= "hero-render-canvas" end |
.disable_fragment_caching! ⇒ Object
Toggles fragment caching off for the rendering controller before
body runs. Defeats the dev-environment cache do ... end blocks
in production partials that key on stable record updated_ats and
would otherwise reuse frame 1's HTML for every subsequent frame.
105 106 107 |
# File 'lib/animate_it/scene.rb', line 105 def disable_fragment_caching! @disable_fragment_caching = true end |
.fixtures(seed: nil, &block) ⇒ Object
Declare a class-level fixture builder. With a block, registers the
builder lazily (no work done at class load). Without a block,
invokes the registered builder once behind a mutex — Faker::Config.random
is reset to Random.new(seed) first (when seed: was given) and
FactoryBot.find_definitions is invoked if no factories are loaded.
Subsequent calls return the memoized hash.
class HeroScene < AnimateIt::Scene
fixtures(seed: 42) do
company = build_stubbed_company
{ company:, job: build_stubbed_job(company) }
end
end
HeroScene.fixtures # → builds once, returns hash
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/animate_it/scene.rb', line 76 def fixtures(seed: nil, &block) if block @fixtures_block = block @fixtures_seed = seed return nil end return @fixtures_value if defined?(@fixtures_value) && @fixtures_value @fixtures_mutex ||= Mutex.new @fixtures_mutex.synchronize do next @fixtures_value if @fixtures_value FactoryBot.find_definitions if defined?(FactoryBot) && FactoryBot.factories.none? Faker::Config.random = Random.new(@fixtures_seed) if defined?(Faker) && @fixtures_seed @fixtures_value = @fixtures_block&.call end end |
.fragment_caching_disabled? ⇒ Boolean
109 110 111 |
# File 'lib/animate_it/scene.rb', line 109 def fragment_caching_disabled? @disable_fragment_caching == true end |
.reset_fixtures! ⇒ Object
95 96 97 98 99 |
# File 'lib/animate_it/scene.rb', line 95 def reset_fixtures! return unless @fixtures_mutex @fixtures_mutex.synchronize { @fixtures_value = nil } end |
.stub_methods(object, **stubs) ⇒ Object
Class-side mirror of ViewHelpers#stub_methods so class-method fixture builders (which run before any Scene instance exists) can also use the helper to define singleton-method stubs on build_stubbed records.
117 118 119 120 121 122 123 |
# File 'lib/animate_it/scene.rb', line 117 def stub_methods(object, **stubs) stubs.each do |name, value| body = value.respond_to?(:call) ? value : ->(*) { value } object.define_singleton_method(name) { |*args| body.call(*args) } end object end |
.template(name = nil) ⇒ Object
Sidecar template name. Defaults to "canvas" — i.e. a scene whose
composition is MyHero looks for app/videos/my_hero/canvas.html.haml.
Override to point to a sibling template instead.
20 21 22 23 |
# File 'lib/animate_it/scene.rb', line 20 def template(name = nil) @template = name.to_s if name @template ||= "canvas" end |
Instance Method Details
#animation_vars(**extras) ⇒ Object
CSS var bag computed from this frame's animations. Available inside custom render methods that want extra inline styles.
190 191 192 |
# File 'lib/animate_it/scene.rb', line 190 def animation_vars(**extras) Style.vars(**self.class.animations.vars_for(self), **extras) end |
#body ⇒ Object
Default markup: canvas wrapper + sidecar template + auto-generated animation CSS. Override in a subclass when the composition is programmatic (no sidecar template) or has multiple acts.
164 165 166 167 168 169 170 171 172 173 |
# File 'lib/animate_it/scene.rb', line 164 def body tag.div(class: self.class.canvas_class, style: canvas_style) do absolute_fill(style: animation_var_style) do parts = [] parts << generated_animation_styles if self.class.animations.elements.any? parts << render_scene_template(self.class.template) view_context.safe_join(parts) end end end |
#expose(*keys, from: nil, **ivars) ⇒ Object
Set ivars on the view_context so templates rendered via
render_scene_template / view_context.render(template:) can read
them as @foo. ActionView's assigns: keyword doesn't propagate
through template-level renders, so we push ivars directly onto the
same view context the template will be evaluated against.
expose(:job, :user, from: fixtures, top_match: matches.first)
The positional keys are pulled from the from: hash by name; the
keyword args are set verbatim.
156 157 158 159 |
# File 'lib/animate_it/scene.rb', line 156 def expose(*keys, from: nil, **ivars) keys.each { |k| view_context.instance_variable_set("@#{k}", from[k]) } if from ivars.each { |k, v| view_context.instance_variable_set("@#{k}", v) } end |
#render(view_context) ⇒ Object
Stash view_context so helpers (tag, safe_join, capture) work,
then call body for the actual markup. Subclasses should override
body (no args) — view_context is already available via the
accessor.
The framework's filmstrip + frame controllers call render(view_context);
don't override that signature unless you really need to.
135 136 137 138 139 140 141 142 143 144 |
# File 'lib/animate_it/scene.rb', line 135 def render(view_context) @view_context = view_context self.class.current_frame = local_frame if self.class.fragment_caching_disabled? && view_context.respond_to?(:controller) && view_context.controller.respond_to?(:perform_caching=) view_context.controller.perform_caching = false end body end |
#with_canvas(&block) ⇒ Object
Convenience: when a subclass overrides render it can call this to
get the same wrapper + animation-var div around custom content.
177 178 179 180 181 182 183 184 185 186 |
# File 'lib/animate_it/scene.rb', line 177 def with_canvas(&block) tag.div(class: self.class.canvas_class, style: canvas_style) do absolute_fill(style: animation_var_style) do parts = [] parts << generated_animation_styles if self.class.animations.elements.any? parts << view_context.capture(&block) if block view_context.safe_join(parts) end end end |