Class: Vizcore::DSL::LayerBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/vizcore/dsl/layer_builder.rb

Overview

Builder for one render layer in a scene.

Defined Under Namespace

Classes: ShapeReference

Constant Summary collapse

NO_ARGUMENT =
Object.new.freeze
SHAPE_SCHEMA_VERSION =
2
MAPPING_SOURCE_KINDS =
%i[
  amplitude frequency_band fft_spectrum onset kick snare hihat beat beat_confidence beat_pulse beat_count bpm
].freeze
PATH_DEFAULT_DETAIL =
32
PATH_MIN_DETAIL =
4
PATH_MAX_DETAIL =
128
PATH_DEFAULT_MAX_SEGMENTS =
4096
SHAPE_TARGET_ALIASES =
{
  "translate_x" => "transform.translate.x",
  "translate_y" => "transform.translate.y",
  "rotate" => "transform.rotate",
  "rotation" => "transform.rotate",
  "scale" => "transform.scale",
  "scale_x" => "transform.scale.x",
  "scale_y" => "transform.scale.y",
  "origin_x" => "transform.origin.x",
  "origin_y" => "transform.origin.y"
}.freeze
SHAPE_STYLE_KEYS =
Vizcore::Shape::STYLE_KEYS
SHAPE_TRANSFORM_KEYS =
%i[translate rotate rotation scale origin].freeze

Instance Method Summary collapse

Constructor Details

#initialize(name:, styles: {}, defaults: {}) ⇒ LayerBuilder

Returns a new instance of LayerBuilder.

Parameters:

  • name (Symbol, String)

    layer identifier

  • styles (Hash) (defaults to: {})

    reusable layer parameter styles

  • defaults (Hash) (defaults to: {})

    default params applied before layer-specific values



55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/vizcore/dsl/layer_builder.rb', line 55

def initialize(name:, styles: {}, defaults: {})
  @name = name.to_sym
  @styles = styles
  @type = nil
  @shader = nil
  @glsl = nil
  @params = deep_dup(defaults)
  @param_schema = {}
  @mappings = []
  @shape_index_by_id = {}
  @shape_group_stack = [{}]
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Stores dynamic one-argument setters into ‘params`.



781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
# File 'lib/vizcore/dsl/layer_builder.rb', line 781

def method_missing(method_name, *args, &block)
  if @current_shape && block.nil? && args.length == 1
    @current_shape[method_name.to_sym] = args.first
    return args.first
  end

  if @current_custom_shape && block.nil? && args.length == 1
    @current_custom_shape[:params][method_name.to_sym] = args.first
    return args.first
  end

  if in_shape_group? && block.nil? && args.length == 1
    current_shape_group[method_name.to_sym] = args.first
    return args.first
  end

  if block.nil? && args.length == 1
    @params[method_name.to_sym] = args.first
    return args.first
  end

  super
end

Instance Method Details

#align(value) ⇒ Symbol

Parameters:

  • value (Symbol, String)

    text alignment (‘left`, `center`, `right`)

Returns:

  • (Symbol)

Raises:

  • (ArgumentError)


297
298
299
300
301
302
# File 'lib/vizcore/dsl/layer_builder.rb', line 297

def align(value)
  alignment = value.to_sym
  raise ArgumentError, "unsupported text align: #{value.inspect}" unless %i[left center right].include?(alignment)

  @params[:align] = alignment
end

#amplitudeHash

Returns source descriptor for overall amplitude.

Returns:

  • (Hash)

    source descriptor for overall amplitude



662
663
664
# File 'lib/vizcore/dsl/layer_builder.rb', line 662

def amplitude
  mapping_source(:amplitude)
end

#arc_to(rx, ry, rotation, large_arc, sweep, x, y) ⇒ Object



553
554
555
# File 'lib/vizcore/dsl/layer_builder.rb', line 553

def arc_to(rx, ry, rotation, large_arc, sweep, x, y)
  append_path_command("A", rx, ry, rotation, large_arc, sweep, x, y)
end

#bassHash

Returns source descriptor for the low/bass frequency band.

Returns:

  • (Hash)

    source descriptor for the low/bass frequency band



683
684
685
# File 'lib/vizcore/dsl/layer_builder.rb', line 683

def bass
  frequency_band(:low)
end

#beatHash

Returns source descriptor for beat trigger.

Returns:

  • (Hash)

    source descriptor for beat trigger



741
742
743
# File 'lib/vizcore/dsl/layer_builder.rb', line 741

def beat
  beat?
end

#beat?Hash

Returns source descriptor for beat trigger.

Returns:

  • (Hash)

    source descriptor for beat trigger



736
737
738
# File 'lib/vizcore/dsl/layer_builder.rb', line 736

def beat?
  mapping_source(:beat)
end

#beat_confidenceHash

Returns source descriptor for beat detector confidence.

Returns:

  • (Hash)

    source descriptor for beat detector confidence



746
747
748
# File 'lib/vizcore/dsl/layer_builder.rb', line 746

def beat_confidence
  mapping_source(:beat_confidence)
end

#beat_countHash

Returns source descriptor for beat counter.

Returns:

  • (Hash)

    source descriptor for beat counter



756
757
758
# File 'lib/vizcore/dsl/layer_builder.rb', line 756

def beat_count
  mapping_source(:beat_count)
end

#beat_pulseHash

Returns source descriptor for beat pulse decay value.

Returns:

  • (Hash)

    source descriptor for beat pulse decay value



751
752
753
# File 'lib/vizcore/dsl/layer_builder.rb', line 751

def beat_pulse
  mapping_source(:beat_pulse)
end

#bezier(id = nil, from:, to:, control: nil, c1: nil, c2: nil, **options) { ... } ⇒ Hash

Declare a quadratic or cubic bezier curve. The serialized primitive is a path.

Parameters:

  • id (Symbol, String, nil) (defaults to: nil)

    optional shape identifier

  • from (Array<Numeric>)

    start point

  • to (Array<Numeric>)

    end point

  • control (Array<Numeric>, nil) (defaults to: nil)

    quadratic control point

  • c1 (Array<Numeric>, nil) (defaults to: nil)

    first cubic control point

  • c2 (Array<Numeric>, nil) (defaults to: nil)

    second cubic control point

  • options (Hash)

    additional path params

Yields:

  • optional block evaluated in the shape context

Returns:

  • (Hash)


180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/vizcore/dsl/layer_builder.rb', line 180

def bezier(id = nil, from:, to:, control: nil, c1: nil, c2: nil, **options, &block)
  commands = [["M", *point_values(from)]]
  if control
    commands << ["Q", *point_values(control), *point_values(to)]
  elsif c1 && c2
    commands << ["C", *point_values(c1), *point_values(c2), *point_values(to)]
  else
    raise ArgumentError, "bezier requires either :control or both :c1 and :c2"
  end

  build_shape(:path, shape_options(id, options).merge(commands: commands), schema_version: true, &block)
end

#blend(value) ⇒ Symbol

Parameters:

  • value (Symbol, String)

    layer compositing mode

Returns:

  • (Symbol)


373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
# File 'lib/vizcore/dsl/layer_builder.rb', line 373

def blend(value)
  if @current_shape
    @current_shape[:blend] = value.to_sym
    mark_shape_schema_version!
    return @current_shape
  end

  if @current_custom_shape
    current_custom_shape_style[:blend] = value.to_sym
    return @current_custom_shape
  end

  if in_shape_group?
    current_shape_group[:blend] = value.to_sym
    return current_shape_group
  end

  @params[:blend] = value.to_sym
end

#bpmHash

Returns source descriptor for estimated BPM.

Returns:

  • (Hash)

    source descriptor for estimated BPM



761
762
763
# File 'lib/vizcore/dsl/layer_builder.rb', line 761

def bpm
  mapping_source(:bpm)
end

#circle(id = nil, **options) { ... } ⇒ Hash

Declare a 2D circle/ring primitive for a shape layer.

Parameters:

  • options (Hash)

    shape params such as ‘count`, `radius`, `x`, and `y`

Yields:

  • optional block evaluated in the shape context

Returns:

  • (Hash)


114
115
116
# File 'lib/vizcore/dsl/layer_builder.rb', line 114

def circle(id = nil, **options, &block)
  build_shape(:circle, shape_options(id, options), &block)
end

#closeObject



557
558
559
# File 'lib/vizcore/dsl/layer_builder.rb', line 557

def close
  append_path_command("Z")
end

#content(value) ⇒ String

Parameters:

  • value (String)

    text content

Returns:

  • (String)


279
280
281
# File 'lib/vizcore/dsl/layer_builder.rb', line 279

def content(value)
  @params[:content] = value.to_s
end

#count(value) ⇒ Integer

Parameters:

  • value (Integer)

    particle count or similar numeric parameter

Returns:

  • (Integer)


273
274
275
# File 'lib/vizcore/dsl/layer_builder.rb', line 273

def count(value)
  @params[:count] = Integer(value)
end

#cubic_to(c1x, c1y, c2x, c2y, x, y) ⇒ Object



541
542
543
# File 'lib/vizcore/dsl/layer_builder.rb', line 541

def cubic_to(c1x, c1y, c2x, c2y, x, y)
  append_path_command("C", c1x, c1y, c2x, c2y, x, y)
end

#custom_shape(renderer, **options) { ... } ⇒ Array<Hash>

Expand a registered Ruby custom shape into normal shape primitives.

Parameters:

  • renderer (Symbol, String, Class, Module, #call)

    registered shape name or renderer

  • options (Hash)

    custom shape params

Yields:

  • optional block applied to each generated primitive

Returns:

  • (Array<Hash>)

Raises:

  • (ArgumentError)


209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/vizcore/dsl/layer_builder.rb', line 209

def custom_shape(renderer, **options, &block)
  mark_shape_schema_version!
  shape_id = options.delete(:id)
  dynamic = options.delete(:dynamic)
  static = options.delete(:static)
  raise ArgumentError, "custom_shape cannot be both static and dynamic" if dynamic && static

  dynamic = true if static == false
  return append_dynamic_custom_shape(renderer, options, shape_id: shape_id, &block) if dynamic

  primitives = expand_custom_shape(renderer, options, shape_id: shape_id, cache: !!static)
  raise ArgumentError, "custom_shape produced no primitives" if primitives.empty?
  raise ArgumentError, "custom_shape id can only be assigned when one primitive is produced" if shape_id && primitives.length > 1

  @type ||= :shape
  @params[:shapes] ||= []
  primitives.map do |primitive|
    primitive[:id] ||= shape_id.to_sym if shape_id
    append_expanded_shape(primitive, &block)
  end
end

#draw { ... } ⇒ Array<Hash>

Group shape primitives in a block for readability.

Yields:

  • shape declarations

Returns:

  • (Array<Hash>)


256
257
258
259
260
# File 'lib/vizcore/dsl/layer_builder.rb', line 256

def draw(&block)
  @type ||= :shape
  instance_eval(&block) if block
  @params[:shapes] || []
end

#evaluate { ... } ⇒ Vizcore::DSL::LayerBuilder

Evaluate a layer block.

Yields:

  • Layer DSL methods

Returns:



72
73
74
75
# File 'lib/vizcore/dsl/layer_builder.rb', line 72

def evaluate(&block)
  instance_eval(&block) if block
  self
end

#fft_spectrumHash

Returns source descriptor for FFT spectrum array.

Returns:

  • (Hash)

    source descriptor for FFT spectrum array



703
704
705
# File 'lib/vizcore/dsl/layer_builder.rb', line 703

def fft_spectrum
  mapping_source(:fft_spectrum)
end

#file(path) ⇒ String

Parameters:

  • path (String, Pathname)

    asset file path used by media-like layers

Returns:

  • (String)


105
106
107
# File 'lib/vizcore/dsl/layer_builder.rb', line 105

def file(path)
  @params[:file] = path.to_s
end

#fill(value) ⇒ String

Parameters:

  • value (String)

    text fill color

Returns:

  • (String)


312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
# File 'lib/vizcore/dsl/layer_builder.rb', line 312

def fill(value)
  if @current_shape
    @current_shape[:fill] = value.to_s
    mark_shape_schema_version!
    return @current_shape
  end

  if @current_custom_shape
    current_custom_shape_style[:fill] = value.to_s
    return @current_custom_shape
  end

  if in_shape_group?
    current_shape_group[:fill] = value.to_s
    return current_shape_group
  end

  @params[:color] = value.to_s
end

#font(value) ⇒ String

Parameters:

  • value (String)

    text font family

Returns:

  • (String)


306
307
308
# File 'lib/vizcore/dsl/layer_builder.rb', line 306

def font(value)
  @params[:font] = value.to_s
end

#font_size(value) ⇒ Integer

Parameters:

  • value (Integer)

    font size in pixels

Returns:

  • (Integer)


285
286
287
# File 'lib/vizcore/dsl/layer_builder.rb', line 285

def font_size(value)
  @params[:font_size] = Integer(value)
end

#frequency_band(name) ⇒ Hash

Returns source descriptor for a frequency band.

Parameters:

  • name (Symbol, String)

    band key (‘sub`, `low`, `mid`, `high`)

Returns:

  • (Hash)

    source descriptor for a frequency band



668
669
670
# File 'lib/vizcore/dsl/layer_builder.rb', line 668

def frequency_band(name)
  mapping_source(:frequency_band, band: name.to_sym)
end

#glsl(path) ⇒ String

Parameters:

  • path (String, Pathname)

    custom fragment shader path

Returns:

  • (String)


98
99
100
101
# File 'lib/vizcore/dsl/layer_builder.rb', line 98

def glsl(path)
  @glsl = path.to_s
  @type ||= :shader
end

#group(_id = nil, **attrs) { ... } ⇒ Array<Hash>

Apply shared style and transform to shape primitives declared in the block.

Group attributes are flattened into child primitives so the frontend only needs to render regular shape primitives.

Parameters:

  • id (Symbol, String, nil)

    optional group identifier, currently documentation-only

  • attrs (Hash)

    initial group style/transform attrs

Yields:

  • shape declarations

Returns:

  • (Array<Hash>)


240
241
242
243
244
245
246
247
248
249
250
# File 'lib/vizcore/dsl/layer_builder.rb', line 240

def group(_id = nil, **attrs, &block)
  raise ArgumentError, "group requires a block" unless block

  mark_shape_schema_version!
  @type ||= :shape
  @shape_group_stack << merge_shape_group(current_shape_group, normalize_shape_group(attrs))
  instance_eval(&block)
  @params[:shapes] || []
ensure
  @shape_group_stack.pop if @shape_group_stack.length > 1
end

#highHash

Returns source descriptor for the high frequency band.

Returns:

  • (Hash)

    source descriptor for the high frequency band



693
694
695
# File 'lib/vizcore/dsl/layer_builder.rb', line 693

def high
  frequency_band(:high)
end

#hihat(value = NO_ARGUMENT) ⇒ Hash

Returns source descriptor for high-band percussive confidence.

Returns:

  • (Hash)

    source descriptor for high-band percussive confidence



729
730
731
732
733
# File 'lib/vizcore/dsl/layer_builder.rb', line 729

def hihat(value = NO_ARGUMENT)
  return @params[:hihat] = value unless value.equal?(NO_ARGUMENT)

  mapping_source(:hihat)
end

#horizontal_to(x) ⇒ Object



545
546
547
# File 'lib/vizcore/dsl/layer_builder.rb', line 545

def horizontal_to(x)
  append_path_command("H", x)
end

#kick(value = NO_ARGUMENT) ⇒ Hash

Returns source descriptor for low-band percussive confidence.

Returns:

  • (Hash)

    source descriptor for low-band percussive confidence



715
716
717
718
719
# File 'lib/vizcore/dsl/layer_builder.rb', line 715

def kick(value = NO_ARGUMENT)
  return @params[:kick] = value unless value.equal?(NO_ARGUMENT)

  mapping_source(:kick)
end

#letter_spacing(value) ⇒ Float

Parameters:

  • value (Numeric)

    extra spacing between text glyphs in pixels

Returns:

  • (Float)


291
292
293
# File 'lib/vizcore/dsl/layer_builder.rb', line 291

def letter_spacing(value)
  @params[:letter_spacing] = normalize_non_negative_param_number(value, :letter_spacing)
end

#line(id = nil, **options) { ... } ⇒ Hash

Declare a 2D line primitive for a shape layer.

Parameters:

  • options (Hash)

    shape params such as ‘x1`, `y1`, `x2`, and `y2`

Yields:

  • optional block evaluated in the shape context

Returns:

  • (Hash)


123
124
125
# File 'lib/vizcore/dsl/layer_builder.rb', line 123

def line(id = nil, **options, &block)
  build_shape(:line, shape_options(id, options), &block)
end

#line_to(x, y) ⇒ Object



533
534
535
# File 'lib/vizcore/dsl/layer_builder.rb', line 533

def line_to(x, y)
  append_path_command("L", x, y)
end

#lowHash

Returns source descriptor for the low/bass frequency band.

Returns:

  • (Hash)

    source descriptor for the low/bass frequency band



678
679
680
# File 'lib/vizcore/dsl/layer_builder.rb', line 678

def low
  frequency_band(:low)
end

#map(definition = nil, **options, &block) ⇒ void

This method returns an undefined value.

Map analysis source(s) to layer parameter target(s).

Parameters:

  • definition (Hash, Symbol, String) (defaults to: nil)

    mapping pairs or a single source

Raises:

  • (ArgumentError)

    when the mapping is empty or invalid



612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
# File 'lib/vizcore/dsl/layer_builder.rb', line 612

def map(definition = nil, **options, &block)
  definition, options = normalize_custom_shape_mapping(definition, options) if @custom_shape_target_prefix
  definition, options = normalize_shape_mapping(definition, options) if @shape_target_prefix

  if options.key?(:to)
    transform_options = options.dup
    to = transform_options.delete(:to)
    transform_options = evaluate_transform_block(transform_options, &block) if block
    @mappings << build_mapping(
      source: normalize_source(definition),
      target: to,
      transform: normalize_transform(**transform_options)
    )
    return
  end

  mapping = definition.nil? ? options : Hash(definition)
  raise ArgumentError, "map requires at least one mapping pair" if mapping.empty?
  raise ArgumentError, "map block syntax supports one mapping pair" if block && mapping.length != 1

  mapping.each do |source, target|
    target_name, transform = normalize_target(target)
    transform = normalize_transform(**evaluate_transform_block(transform, &block)) if block
    @mappings << build_mapping(source: normalize_source(source), target: target_name, transform: transform)
  end
end

#midHash

Returns source descriptor for the mid frequency band.

Returns:

  • (Hash)

    source descriptor for the mid frequency band



688
689
690
# File 'lib/vizcore/dsl/layer_builder.rb', line 688

def mid
  frequency_band(:mid)
end

#move_to(x, y) ⇒ Object



529
530
531
# File 'lib/vizcore/dsl/layer_builder.rb', line 529

def move_to(x, y)
  append_path_command("M", x, y)
end

#onset(band = nil) ⇒ Hash

Returns source descriptor for positive audio feature changes.

Parameters:

  • band (Symbol, String, nil) (defaults to: nil)

    optional band-specific onset key

Returns:

  • (Hash)

    source descriptor for positive audio feature changes



709
710
711
712
# File 'lib/vizcore/dsl/layer_builder.rb', line 709

def onset(band = nil)
  options = band.nil? ? {} : { band: band.to_sym }
  mapping_source(:onset, **options)
end

#opacity(value) ⇒ Float, Hash

Set layer or shape opacity.

Parameters:

  • value (Numeric)

Returns:

  • (Float, Hash)


397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
# File 'lib/vizcore/dsl/layer_builder.rb', line 397

def opacity(value)
  if @current_shape
    @current_shape[:opacity] = normalize_param_number(value, :opacity)
    mark_shape_schema_version!
    return @current_shape
  end

  if @current_custom_shape
    current_custom_shape_style[:opacity] = normalize_param_number(value, :opacity)
    return @current_custom_shape
  end

  if in_shape_group?
    current_shape_group[:opacity] = current_shape_group.key?(:opacity) ? normalize_param_number(current_shape_group[:opacity], :opacity) * normalize_param_number(value, :opacity) : normalize_param_number(value, :opacity)
    return current_shape_group
  end

  @params[:opacity] = normalize_param_number(value, :opacity)
end

#origin(*args, x: nil, y: nil) ⇒ Hash

Set a shape/layer transform origin.

Parameters:

  • args (Array<Numeric>)
  • x (Numeric, nil) (defaults to: nil)
  • y (Numeric, nil) (defaults to: nil)

Returns:

  • (Hash)


499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
# File 'lib/vizcore/dsl/layer_builder.rb', line 499

def origin(*args, x: nil, y: nil)
  values = normalize_xy_args(args, x: x, y: y, name: :origin)
  if @current_shape
    current_shape_transform[:origin] = values
    return @current_shape
  end

  if @current_custom_shape
    current_custom_shape_transform[:origin] = values
    return @current_custom_shape
  end

  if in_shape_group?
    current_shape_group_transform[:origin] = values
    return current_shape_group
  end

  @params[:origin] = values
end

#palette(*colors) ⇒ Array<String>

Store an ordered color palette for this layer.

Parameters:

  • colors (Array<String, Array<String>>)

    color values such as “#00ffff”

Returns:

  • (Array<String>)

Raises:

  • (ArgumentError)

    when no non-blank colors are supplied



566
567
568
# File 'lib/vizcore/dsl/layer_builder.rb', line 566

def palette(*colors)
  @params[:palette] = normalize_palette(colors)
end

#param(name, default: nil, range: nil, min: nil, max: nil, step: nil) ⇒ Hash

Declare numeric metadata for a shader/layer parameter.

Parameters:

  • name (Symbol, String)

    parameter name exposed as ‘u_param_<name>` for shaders

  • default (Numeric, nil) (defaults to: nil)

    default value stored in layer params

  • range (Range, Array, nil) (defaults to: nil)

    allowed numeric range

  • min (Numeric, nil) (defaults to: nil)

    allowed minimum when ‘range` is not used

  • max (Numeric, nil) (defaults to: nil)

    allowed maximum when ‘range` is not used

  • step (Numeric, nil) (defaults to: nil)

    preferred UI step

Returns:

  • (Hash)


590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
# File 'lib/vizcore/dsl/layer_builder.rb', line 590

def param(name, default: nil, range: nil, min: nil, max: nil, step: nil)
  key = normalize_param_name(name)
  range_min, range_max = normalize_range(range, context: "param")
  min = range_min if min.nil?
  max = range_max if max.nil?

   = { name: key }
  [:default] = normalize_param_number(default, :default) unless default.nil?
  [:min] = normalize_param_number(min, :min) unless min.nil?
  [:max] = normalize_param_number(max, :max) unless max.nil?
  [:step] = normalize_param_number(step, :step) unless step.nil?
  validate_param_range!()

  @params[key] = [:default] if .key?(:default)
  @param_schema[key] = 
end

#path(id = nil, **options) { ... } ⇒ Hash

Declare a path primitive using SVG-like path commands.

Parameters:

  • id (Symbol, String, nil) (defaults to: nil)

    optional shape identifier

  • options (Hash)

    path params such as ‘detail`

Yields:

  • block containing path commands and shape styling

Returns:

  • (Hash)


163
164
165
166
167
# File 'lib/vizcore/dsl/layer_builder.rb', line 163

def path(id = nil, **options, &block)
  shape = shape_options(id, options)
  shape[:commands] ||= []
  build_shape(:path, shape, schema_version: true, &block)
end

#polygon(id = nil, **options) { ... } ⇒ Hash

Declare a closed polygon primitive for a shape layer.

Parameters:

  • id (Symbol, String, nil) (defaults to: nil)

    optional shape identifier

  • options (Hash)

    shape params including ‘points`

Yields:

  • optional block evaluated in the shape context

Returns:

  • (Hash)


143
144
145
# File 'lib/vizcore/dsl/layer_builder.rb', line 143

def polygon(id = nil, **options, &block)
  build_shape(:polygon, shape_options(id, options), schema_version: true, &block)
end

#polyline(id = nil, **options) { ... } ⇒ Hash

Declare an open polyline primitive for a shape layer.

Parameters:

  • id (Symbol, String, nil) (defaults to: nil)

    optional shape identifier

  • options (Hash)

    shape params including ‘points`

Yields:

  • optional block evaluated in the shape context

Returns:

  • (Hash)


153
154
155
# File 'lib/vizcore/dsl/layer_builder.rb', line 153

def polyline(id = nil, **options, &block)
  build_shape(:polyline, shape_options(id, options).merge(closed: false), schema_version: true, &block)
end

#quad_to(cx, cy, x, y) ⇒ Object



537
538
539
# File 'lib/vizcore/dsl/layer_builder.rb', line 537

def quad_to(cx, cy, x, y)
  append_path_command("Q", cx, cy, x, y)
end

#react_to(source_value) { ... } ⇒ void

This method returns an undefined value.

High-level mapping DSL for describing audio reactions inside a layer.

Parameters:

  • source_value (Hash, Symbol, String)

    analysis source descriptor

Yields:

  • Reaction block with ‘change` and `trigger`

Raises:

  • (ArgumentError)

    when no reaction block is provided



645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
# File 'lib/vizcore/dsl/layer_builder.rb', line 645

def react_to(source_value, &block)
  raise ArgumentError, "react_to requires a block" unless block

  source_descriptor = normalize_source(source_value)
  reaction = ReactionBuilder.new(
    mapping_factory: lambda do |target, transform_options|
      build_mapping(
        source: source_descriptor,
        target: target,
        transform: normalize_transform(**transform_options)
      )
    end
  )
  @mappings.concat(reaction.evaluate(&block))
end

#rect(id = nil, **options) { ... } ⇒ Hash

Declare a 2D rectangle primitive for a shape layer.

Parameters:

  • id (Symbol, String, nil) (defaults to: nil)

    optional shape identifier

  • options (Hash)

    shape params such as ‘x`, `y`, `width`, `height`, and `radius`

Yields:

  • optional block evaluated in the shape context

Returns:

  • (Hash)


133
134
135
# File 'lib/vizcore/dsl/layer_builder.rb', line 133

def rect(id = nil, **options, &block)
  build_shape(:rect, shape_options(id, options), schema_version: true, &block)
end

#respond_to_missing?(method_name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


805
806
807
# File 'lib/vizcore/dsl/layer_builder.rb', line 805

def respond_to_missing?(method_name, include_private = false)
  !!@current_custom_shape || @params.key?(method_name.to_sym) || super
end

#rotate(value) ⇒ Float, Hash

Set a shape/layer rotation transform in degrees.

Parameters:

  • value (Numeric)

Returns:

  • (Float, Hash)


447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
# File 'lib/vizcore/dsl/layer_builder.rb', line 447

def rotate(value)
  rotation = normalize_param_number(value, :rotate)
  if @current_shape
    current_shape_transform[:rotate] = rotation
    return @current_shape
  end

  if @current_custom_shape
    current_custom_shape_transform[:rotate] = normalize_param_number(current_custom_shape_transform[:rotate] || 0, :rotate) + rotation
    return @current_custom_shape
  end

  if in_shape_group?
    current_shape_group_transform[:rotate] = normalize_param_number(current_shape_group_transform[:rotate] || 0, :rotate) + rotation
    return current_shape_group
  end

  @params[:rotate] = rotation
end

#scale(value = NO_ARGUMENT, x: nil, y: nil) ⇒ Float, Hash

Set a shape/layer scale transform.

Parameters:

  • value (Numeric) (defaults to: NO_ARGUMENT)
  • x (Numeric, nil) (defaults to: nil)
  • y (Numeric, nil) (defaults to: nil)

Returns:

  • (Float, Hash)


473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
# File 'lib/vizcore/dsl/layer_builder.rb', line 473

def scale(value = NO_ARGUMENT, x: nil, y: nil)
  scale_value = normalize_scale_args(value, x: x, y: y)
  if @current_shape
    current_shape_transform[:scale] = scale_value
    return @current_shape
  end

  if @current_custom_shape
    current_custom_shape_transform[:scale] = multiply_shape_scale(current_custom_shape_transform[:scale], scale_value)
    return @current_custom_shape
  end

  if in_shape_group?
    current_shape_group_transform[:scale] = multiply_shape_scale(current_shape_group_transform[:scale], scale_value)
    return current_shape_group
  end

  @params[:scale] = scale_value
end

#shader(value, reload: nil) ⇒ Symbol

Parameters:

  • value (Symbol, String)

    built-in shader key or custom GLSL path

  • reload (Boolean, nil) (defaults to: nil)

    accepted for custom shader path compatibility

Returns:

  • (Symbol)


86
87
88
89
90
91
92
93
94
# File 'lib/vizcore/dsl/layer_builder.rb', line 86

def shader(value, reload: nil)
  if shader_path?(value)
    @glsl = value.to_s
    @params[:shader_reload] = !!reload unless reload.nil?
  else
    @shader = value.to_sym
  end
  @type ||= :shader
end

#shadow(color: nil, blur: nil) ⇒ Hash

Parameters:

  • color (String, nil) (defaults to: nil)

    text shadow color

  • blur (Numeric, nil) (defaults to: nil)

    text shadow blur in pixels

Returns:

  • (Hash)


365
366
367
368
369
# File 'lib/vizcore/dsl/layer_builder.rb', line 365

def shadow(color: nil, blur: nil)
  @params[:shadow_color] = color.to_s unless color.nil?
  @params[:shadow_blur] = normalize_non_negative_param_number(blur, :shadow_blur) unless blur.nil?
  @params
end

#shape(id) ⇒ ShapeReference

Return a reference object for mapping to a named shape.

Parameters:

  • id (Symbol, String)

Returns:



523
524
525
526
527
# File 'lib/vizcore/dsl/layer_builder.rb', line 523

def shape(id)
  key = id.to_sym
  index = @shape_index_by_id.fetch(key) { raise ArgumentError, "unknown shape id: #{key.inspect}" }
  ShapeReference.new("shapes.#{index}")
end

#snare(value = NO_ARGUMENT) ⇒ Hash

Returns source descriptor for mid-band percussive confidence.

Returns:

  • (Hash)

    source descriptor for mid-band percussive confidence



722
723
724
725
726
# File 'lib/vizcore/dsl/layer_builder.rb', line 722

def snare(value = NO_ARGUMENT)
  return @params[:snare] = value unless value.equal?(NO_ARGUMENT)

  mapping_source(:snare)
end

#source(value, **options) ⇒ Symbol, Hash

Parameters:

  • value (Symbol, String)

    input source for media-like layers

Returns:

  • (Symbol, Hash)


264
265
266
267
268
269
# File 'lib/vizcore/dsl/layer_builder.rb', line 264

def source(value, **options)
  source_name = value.to_sym
  return mapping_source(source_name, **options) if options.any? || MAPPING_SOURCE_KINDS.include?(source_name)

  @params[:source] = source_name
end

#star(id = nil, **options) { ... } ⇒ Hash

Declare a star polygon primitive for a shape layer.

Parameters:

  • id (Symbol, String, nil) (defaults to: nil)

    optional shape identifier

  • options (Hash)

    shape params such as ‘points`, `radius`, and `inner_radius`

Yields:

  • optional block evaluated in the shape context

Returns:

  • (Hash)


199
200
201
# File 'lib/vizcore/dsl/layer_builder.rb', line 199

def star(id = nil, **options, &block)
  build_shape(:star, shape_options(id, options), schema_version: true, &block)
end

#stroke(value = NO_ARGUMENT, width: nil, color: nil) ⇒ Hash

Parameters:

  • width (Numeric, nil) (defaults to: nil)

    text stroke width in pixels

  • color (String, nil) (defaults to: nil)

    text stroke color

Returns:

  • (Hash)


335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
# File 'lib/vizcore/dsl/layer_builder.rb', line 335

def stroke(value = NO_ARGUMENT, width: nil, color: nil)
  if @current_shape
    @current_shape[:stroke] = normalize_non_negative_param_number(value, :stroke) unless value.equal?(NO_ARGUMENT)
    @current_shape[:stroke_width] = normalize_non_negative_param_number(width, :stroke_width) unless width.nil?
    @current_shape[:stroke_color] = color.to_s unless color.nil?
    return @current_shape
  end

  if @current_custom_shape
    current_custom_shape_style[:stroke] = normalize_non_negative_param_number(value, :stroke) unless value.equal?(NO_ARGUMENT)
    current_custom_shape_style[:stroke_width] = normalize_non_negative_param_number(width, :stroke_width) unless width.nil?
    current_custom_shape_style[:stroke_color] = color.to_s unless color.nil?
    return @current_custom_shape
  end

  if in_shape_group?
    current_shape_group[:stroke] = normalize_non_negative_param_number(value, :stroke) unless value.equal?(NO_ARGUMENT)
    current_shape_group[:stroke_width] = normalize_non_negative_param_number(width, :stroke_width) unless width.nil?
    current_shape_group[:stroke_color] = color.to_s unless color.nil?
    return current_shape_group
  end

  @params[:stroke_width] = normalize_non_negative_param_number(width, :stroke_width) unless width.nil?
  @params[:stroke_color] = color.to_s unless color.nil?
  @params
end

#subHash

Returns source descriptor for the sub-bass frequency band.

Returns:

  • (Hash)

    source descriptor for the sub-bass frequency band



673
674
675
# File 'lib/vizcore/dsl/layer_builder.rb', line 673

def sub
  frequency_band(:sub)
end

#to_hHash

Returns serialized layer payload.

Returns:

  • (Hash)

    serialized layer payload



766
767
768
769
770
771
772
773
774
775
776
777
# File 'lib/vizcore/dsl/layer_builder.rb', line 766

def to_h
  layer = {
    name: @name,
    type: resolved_type,
    params: @params.dup
  }
  layer[:shader] = @shader if @shader
  layer[:glsl] = @glsl if @glsl
  layer[:param_schema] = @param_schema.values.map(&:dup) unless @param_schema.empty?
  layer[:mappings] = @mappings.map { |mapping| mapping.dup } unless @mappings.empty?
  layer
end

#translate(*args, x: nil, y: nil) ⇒ Hash

Set a shape/layer translation transform.

Parameters:

  • args (Array<Numeric>)
  • x (Numeric, nil) (defaults to: nil)
  • y (Numeric, nil) (defaults to: nil)

Returns:

  • (Hash)


423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
# File 'lib/vizcore/dsl/layer_builder.rb', line 423

def translate(*args, x: nil, y: nil)
  values = normalize_xy_args(args, x: x, y: y, name: :translate)
  if @current_shape
    current_shape_transform[:translate] = values
    return @current_shape
  end

  if @current_custom_shape
    current_custom_shape_transform[:translate] = add_shape_xy(current_custom_shape_transform[:translate], values)
    return @current_custom_shape
  end

  if in_shape_group?
    current_shape_group_transform[:translate] = add_shape_xy(current_shape_group_transform[:translate], values)
    return current_shape_group
  end

  @params[:translate] = values
end

#trebleHash

Returns source descriptor for the high/treble frequency band.

Returns:

  • (Hash)

    source descriptor for the high/treble frequency band



698
699
700
# File 'lib/vizcore/dsl/layer_builder.rb', line 698

def treble
  frequency_band(:high)
end

#type(value) ⇒ Symbol

Parameters:

  • value (Symbol, String)

    layer type (‘shader`, `particle_field`, etc.)

Returns:

  • (Symbol)


79
80
81
# File 'lib/vizcore/dsl/layer_builder.rb', line 79

def type(value)
  @type = value.to_sym
end

#use_style(name) ⇒ Hash

Apply a named style by merging its params into this layer.

Parameters:

  • name (Symbol, String)

    style identifier

Returns:

  • (Hash)

    applied style params

Raises:

  • (ArgumentError)

    when the style is unknown



575
576
577
578
579
# File 'lib/vizcore/dsl/layer_builder.rb', line 575

def use_style(name)
  style_name = name.to_sym
  style_params = @styles.fetch(style_name) { raise ArgumentError, "unknown style: #{style_name}" }
  @params.merge!(deep_dup(style_params))
end

#vertical_to(y) ⇒ Object



549
550
551
# File 'lib/vizcore/dsl/layer_builder.rb', line 549

def vertical_to(y)
  append_path_command("V", y)
end