vizcore 1.0.0 → 1.1.0
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.
- checksums.yaml +4 -4
- data/README.md +66 -648
- data/docs/assets/playground-worker.js +373 -0
- data/docs/assets/playground.css +440 -0
- data/docs/assets/playground.js +652 -0
- data/docs/index.html +2 -1
- data/docs/playground.html +81 -0
- data/docs/shape_dsl.md +269 -0
- data/frontend/index.html +26 -0
- data/frontend/src/custom-shape-param-controls.js +106 -0
- data/frontend/src/main.js +268 -0
- data/frontend/src/mapping-target-selector.js +109 -0
- data/frontend/src/renderer/engine.js +10 -1
- data/frontend/src/renderer/layer-manager.js +18 -4
- data/frontend/src/shape-editor-controls.js +157 -0
- data/frontend/src/visuals/geometry.js +425 -27
- data/frontend/src/visuals/shape-renderer.js +475 -0
- data/frontend/src/visuals/svg-arc.js +104 -0
- data/lib/vizcore/cli/dsl_reference.rb +1 -1
- data/lib/vizcore/cli/scene_validator.rb +92 -0
- data/lib/vizcore/dsl/layer_builder.rb +795 -7
- data/lib/vizcore/dsl/mapping_resolver.rb +158 -4
- data/lib/vizcore/layer_catalog.rb +4 -2
- data/lib/vizcore/renderer/scene_frame_source.rb +14 -1
- data/lib/vizcore/renderer/snapshot_renderer.rb +507 -15
- data/lib/vizcore/server/frame_broadcaster.rb +53 -4
- data/lib/vizcore/server/runner.rb +21 -0
- data/lib/vizcore/shape.rb +719 -0
- data/lib/vizcore/version.rb +1 -1
- data/lib/vizcore.rb +1 -0
- data/sig/vizcore.rbs +100 -1
- metadata +12 -1
|
@@ -19,6 +19,7 @@ module Vizcore
|
|
|
19
19
|
SUPPORTED_BLEND_MODES = Vizcore::LayerCatalog::BLEND_MODES
|
|
20
20
|
SUPPORTED_POST_EFFECTS = Vizcore::LayerCatalog::POST_EFFECTS
|
|
21
21
|
SUPPORTED_VJ_EFFECTS = Vizcore::LayerCatalog::VJ_EFFECTS
|
|
22
|
+
SUPPORTED_SHAPE_KINDS = %i[circle line rect polygon polyline path star].freeze
|
|
22
23
|
|
|
23
24
|
Issue = Struct.new(:severity, :message, keyword_init: true) do
|
|
24
25
|
def error?
|
|
@@ -113,6 +114,7 @@ module Vizcore
|
|
|
113
114
|
issues << warn("scene #{scene_name} layer #{layer_name} has an empty GLSL file") if layer[:glsl] && glsl_source.to_s.empty?
|
|
114
115
|
validate_blend_mode(layer, scene_name, layer_name, issues)
|
|
115
116
|
validate_layer_effects(layer, scene_name, layer_name, issues)
|
|
117
|
+
validate_shape_layer(layer, scene_name, layer_name, issues)
|
|
116
118
|
validate_mappings(Array(layer[:mappings]), scene_name, layer_name, issues)
|
|
117
119
|
end
|
|
118
120
|
|
|
@@ -130,10 +132,100 @@ module Vizcore
|
|
|
130
132
|
validate_effect_name(params[:vj_effect], SUPPORTED_VJ_EFFECTS, "vj_effect", scene_name, layer_name, issues)
|
|
131
133
|
end
|
|
132
134
|
|
|
135
|
+
def validate_shape_layer(layer, scene_name, layer_name, issues)
|
|
136
|
+
params = layer[:params] || {}
|
|
137
|
+
return unless shape_layer?(layer) || shape_value(params, :shapes)
|
|
138
|
+
|
|
139
|
+
Array(shape_value(params, :shapes)).each_with_index do |shape, index|
|
|
140
|
+
values = shape_hash(shape)
|
|
141
|
+
label = shape_label(values, index)
|
|
142
|
+
validate_shape_kind(values, label, scene_name, layer_name, issues)
|
|
143
|
+
validate_shape_fallback_fill(values, label, scene_name, layer_name, issues)
|
|
144
|
+
validate_shape_opacity(values, label, scene_name, layer_name, issues)
|
|
145
|
+
validate_shape_scale(values, label, scene_name, layer_name, issues)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def validate_shape_kind(shape, label, scene_name, layer_name, issues)
|
|
150
|
+
kind = shape_value(shape, :kind)&.to_sym
|
|
151
|
+
return if SUPPORTED_SHAPE_KINDS.include?(kind)
|
|
152
|
+
|
|
153
|
+
issues << warn("scene #{scene_name} layer #{layer_name} shape #{label} uses unsupported kind: #{kind || "missing"}")
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def validate_shape_fallback_fill(shape, label, scene_name, layer_name, issues)
|
|
157
|
+
fill = shape_value(shape, :fill)
|
|
158
|
+
return if fill.nil? || fill.to_s.empty?
|
|
159
|
+
|
|
160
|
+
issues << warn("scene #{scene_name} layer #{layer_name} shape #{label} fill may be ignored by line fallback")
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def validate_shape_opacity(shape, label, scene_name, layer_name, issues)
|
|
164
|
+
opacity = numeric_shape_value(shape_value(shape, :opacity))
|
|
165
|
+
return unless opacity && (opacity.negative? || opacity > 1)
|
|
166
|
+
|
|
167
|
+
issues << warn("scene #{scene_name} layer #{layer_name} shape #{label} opacity #{opacity} is outside 0..1; renderer will clamp")
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def validate_shape_scale(shape, label, scene_name, layer_name, issues)
|
|
171
|
+
scale_values(shape).each do |scale|
|
|
172
|
+
next unless scale
|
|
173
|
+
|
|
174
|
+
if scale.zero?
|
|
175
|
+
issues << warn("scene #{scene_name} layer #{layer_name} shape #{label} scale includes 0; shape may collapse")
|
|
176
|
+
elsif scale.abs > 8
|
|
177
|
+
issues << warn("scene #{scene_name} layer #{layer_name} shape #{label} scale #{scale} is extreme; renderer will clamp")
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
133
182
|
def supported_layer_types
|
|
134
183
|
Vizcore::LayerCatalog.supported_types
|
|
135
184
|
end
|
|
136
185
|
|
|
186
|
+
def shape_layer?(layer)
|
|
187
|
+
%w[shape shapes shape_layer].include?((layer[:type] || layer["type"]).to_s)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def shape_label(shape, index)
|
|
191
|
+
id = shape_value(shape, :id)
|
|
192
|
+
id ? "`#{id}`" : "##{index + 1}"
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def scale_values(shape)
|
|
196
|
+
transform = Hash(shape_value(shape, :transform) || {})
|
|
197
|
+
scale = shape_value(transform, :scale) || shape_value(shape, :scale)
|
|
198
|
+
case scale
|
|
199
|
+
when Hash
|
|
200
|
+
[numeric_shape_value(shape_value(scale, :x)), numeric_shape_value(shape_value(scale, :y))]
|
|
201
|
+
when Array
|
|
202
|
+
[numeric_shape_value(scale[0]), numeric_shape_value(scale[1])]
|
|
203
|
+
else
|
|
204
|
+
[numeric_shape_value(scale)]
|
|
205
|
+
end
|
|
206
|
+
rescue TypeError
|
|
207
|
+
[]
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def numeric_shape_value(value)
|
|
211
|
+
return nil if value.nil?
|
|
212
|
+
|
|
213
|
+
numeric = Float(value)
|
|
214
|
+
numeric if numeric.finite?
|
|
215
|
+
rescue ArgumentError, TypeError
|
|
216
|
+
nil
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def shape_hash(value)
|
|
220
|
+
Hash(value)
|
|
221
|
+
rescue TypeError
|
|
222
|
+
{}
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def shape_value(hash, key)
|
|
226
|
+
hash[key] || hash[key.to_s]
|
|
227
|
+
end
|
|
228
|
+
|
|
137
229
|
def validate_effect_name(value, supported, field, scene_name, layer_name, issues)
|
|
138
230
|
return unless value
|
|
139
231
|
return if supported.include?(value.to_sym)
|