experimental SVG-based video rendering engine made for music videos. React to MIDI or arbitrary signals from your DAW through "probe" VSTs
at main 3.9 kB view raw
1use measure_time::debug_time; 2 3use crate::{ColorMapping, Filter, FilterType}; 4 5use super::{CSSRenderable, renderable::SVGRenderable, svg}; 6 7impl SVGRenderable for Filter { 8 fn render_to_svg( 9 &self, 10 _colormap: crate::ColorMapping, 11 _cell_size: usize, 12 _object_sizes: crate::graphics::objects::ObjectSizes, 13 _id: &str, 14 ) -> anyhow::Result<svg::Node> { 15 { 16 debug_time!("render_to_svg/filter"); 17 Ok(match self.kind { 18 FilterType::Glow => { 19 // format!( 20 // r#" 21 // <filter id="glow"> 22 // <feGaussianBlur stdDeviation="{}" result="coloredBlur"/> 23 // <feMerge> 24 // <feMergeNode in="coloredBlur"/> 25 // <feMergeNode in="SourceGraphic"/> 26 // </feMerge> 27 // </filter> 28 // "#, 29 // 2.5 30 // ) // TODO parameterize stdDeviation 31 svg::tag("filter").wrapping(vec![ 32 // TODO parameterize stdDeviation 33 svg::tag("feGaussianBlur") 34 .attr("stdDeviation", self.parameter) 35 .attr("result", "coloredBlur"), 36 svg::tag("feMerge").wrapping(vec![ 37 svg::tag("feMergeNode").attr("in", "coloredBlur"), 38 svg::tag("feMergeNode").attr("in", "SourceGraphic"), 39 ]), 40 ]) 41 } 42 FilterType::NaturalShadow => { 43 /* 44 <filter id="natural-shadow-filter" x="0" y="0" width="2" height="2"> 45 <feOffset in="SourceGraphic" dx="3" dy="3" /> 46 <feGaussianBlur stdDeviation="12" result="blur" /> 47 <feMerge> 48 <feMergeNode in="blur" /> 49 <feMergeNode in="SourceGraphic" /> 50 </feMerge> 51 </filter> 52 */ 53 svg::tag("filter").wrapping(vec![ 54 svg::tag("feOffset") 55 .attr("in", "SourceGraphic") 56 .attr("dx", self.parameter) 57 .attr("dy", self.parameter), 58 svg::tag("feGaussianBlur") 59 .attr("stdDeviation", self.parameter * 4.0) 60 .attr("result", "blur"), 61 svg::tag("feMerge").wrapping(vec![ 62 svg::tag("feMergeNode").attr("in", "blur"), 63 svg::tag("feMergeNode").attr("in", "SourceGraphic"), 64 ]), 65 ]) 66 } 67 FilterType::Saturation => { 68 /* 69 <filter id="saturation"> 70 <feColorMatrix type="saturate" values="0.5"/> 71 </filter> 72 */ 73 svg::tag("filter").wrapping(vec![ 74 svg::tag("feColorMatrix") 75 .attr("type", "saturate") 76 .attr("values", self.parameter), 77 ]) 78 } 79 } 80 .attr("id", self.id()) 81 .attr("filterUnit", "userSpaceOnUse") 82 .into()) 83 } 84 } 85} 86 87impl CSSRenderable for Filter { 88 fn render_to_css_filled(&self, _colormap: &ColorMapping) -> String { 89 format!("filter: url(#{}); overflow: visible;", self.id()) 90 } 91 92 fn render_to_css_stroked(&self, colormap: &ColorMapping) -> String { 93 self.render_to_css_filled(colormap) 94 } 95}