svg-filters: add turbulence and displacement map
This commit is contained in:
parent
919a3bb377
commit
0197df5ee2
5 changed files with 98 additions and 9 deletions
|
@ -3,7 +3,11 @@ use petgraph::{data::Build, prelude::NodeIndex};
|
|||
|
||||
use crate::{
|
||||
types::nodes::primitives::{
|
||||
blend::BlendMode, color_matrix::ColorMatrixType, component_transfer::TransferFn,
|
||||
blend::BlendMode,
|
||||
color_matrix::ColorMatrixType,
|
||||
component_transfer::TransferFn,
|
||||
displacement_map::Channel,
|
||||
turbulence::{NoiseType, StitchTiles},
|
||||
},
|
||||
Node,
|
||||
};
|
||||
|
@ -152,4 +156,41 @@ impl FilterGraph {
|
|||
pub fn flood_opaque(&mut self, flood_color: Color) -> NodeIndex {
|
||||
self.dag.add_node(Node::flood_opaque(flood_color))
|
||||
}
|
||||
|
||||
pub fn turbulence(
|
||||
&mut self,
|
||||
base_freq_x: f32,
|
||||
base_freq_y: f32,
|
||||
num_octaves: u16,
|
||||
seed: u32,
|
||||
stitch_tiles: StitchTiles,
|
||||
noise_type: NoiseType,
|
||||
) -> NodeIndex {
|
||||
self.dag.add_node(Node::turbulence(
|
||||
base_freq_x,
|
||||
base_freq_y,
|
||||
num_octaves,
|
||||
seed,
|
||||
stitch_tiles,
|
||||
noise_type,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn displacement_map(
|
||||
&mut self,
|
||||
source_image: impl Into<NodeInput>,
|
||||
displacement_map: impl Into<NodeInput>,
|
||||
scale: f32,
|
||||
x_channel: Channel,
|
||||
y_channel: Channel,
|
||||
) -> NodeIndex {
|
||||
let node_idx = self
|
||||
.dag
|
||||
.add_node(Node::displacement_map(scale, x_channel, y_channel));
|
||||
self.dag
|
||||
.add_edge(self.resolve_input(source_image.into()), node_idx, ());
|
||||
self.dag
|
||||
.add_edge(self.resolve_input(displacement_map.into()), node_idx, ());
|
||||
node_idx
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,9 +9,11 @@ use self::{
|
|||
color_matrix::{ColorMatrix, ColorMatrixType},
|
||||
component_transfer::{ComponentTransfer, TransferFn},
|
||||
composite::{Composite, CompositeOperator},
|
||||
displacement_map::{Channel, DisplacementMap},
|
||||
flood::Flood,
|
||||
gaussian_blur::GaussianBlur,
|
||||
offset::Offset,
|
||||
turbulence::{NoiseType, StitchTiles, Turbulence},
|
||||
FePrimitive,
|
||||
},
|
||||
standard_input::StandardInput,
|
||||
|
@ -207,4 +209,29 @@ impl Node {
|
|||
pub fn flood_opaque(flood_color: Color) -> Self {
|
||||
Self::flood(flood_color, 1.)
|
||||
}
|
||||
|
||||
pub fn turbulence(
|
||||
base_freq_x: f32,
|
||||
base_freq_y: f32,
|
||||
num_octaves: u16,
|
||||
seed: u32,
|
||||
stitch_tiles: StitchTiles,
|
||||
noise_type: NoiseType,
|
||||
) -> Self {
|
||||
Self::simple(FePrimitive::Turbulence(Turbulence {
|
||||
base_frequency: (base_freq_x, base_freq_y),
|
||||
num_octaves,
|
||||
seed,
|
||||
stitch_tiles,
|
||||
noise_type,
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn displacement_map(scale: f32, x_channel: Channel, y_channel: Channel) -> Self {
|
||||
Self::simple(FePrimitive::DisplacementMap(DisplacementMap {
|
||||
scale,
|
||||
x_channel_selector: x_channel,
|
||||
y_channel_selector: y_channel,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ impl WriteElement for FePrimitive {
|
|||
FePrimitive::Turbulence(el) => el.attrs(),
|
||||
FePrimitive::ConvolveMatrix(_) => todo!(),
|
||||
FePrimitive::DiffuseLighting(_) => todo!(),
|
||||
FePrimitive::DisplacementMap(_) => todo!(),
|
||||
FePrimitive::DisplacementMap(el) => el.attrs(),
|
||||
FePrimitive::Flood(el) => el.attrs(),
|
||||
FePrimitive::Image(_) => todo!(),
|
||||
FePrimitive::Merge(_) => todo!(),
|
||||
|
@ -111,7 +111,7 @@ impl WriteElement for FePrimitive {
|
|||
FePrimitive::Turbulence(el) => el.tag_name(),
|
||||
FePrimitive::ConvolveMatrix(_) => todo!(),
|
||||
FePrimitive::DiffuseLighting(_) => todo!(),
|
||||
FePrimitive::DisplacementMap(_) => todo!(),
|
||||
FePrimitive::DisplacementMap(el) => el.tag_name(),
|
||||
FePrimitive::Flood(el) => el.tag_name(),
|
||||
FePrimitive::Image(_) => todo!(),
|
||||
FePrimitive::Merge(_) => todo!(),
|
||||
|
@ -138,7 +138,7 @@ impl WriteElement for FePrimitive {
|
|||
FePrimitive::Offset(el) => el.element_writer(writer, common, inputs, output),
|
||||
FePrimitive::ConvolveMatrix(_) => todo!(),
|
||||
FePrimitive::DiffuseLighting(_) => todo!(),
|
||||
FePrimitive::DisplacementMap(_) => todo!(),
|
||||
FePrimitive::DisplacementMap(el) => el.element_writer(writer, common, inputs, output),
|
||||
FePrimitive::Flood(el) => el.element_writer(writer, common, inputs, output),
|
||||
FePrimitive::Image(_) => todo!(),
|
||||
FePrimitive::Merge(_) => todo!(),
|
||||
|
|
|
@ -1,13 +1,32 @@
|
|||
use super::WriteElement;
|
||||
|
||||
/// [feDisplacementMap](https://www.w3.org/TR/SVG11/filters.html#feDisplacementMapElement)
|
||||
#[derive(Debug)]
|
||||
pub struct DisplacementMap {
|
||||
scale: f32,
|
||||
x_channel_selector: Channel,
|
||||
y_channel_selector: Channel,
|
||||
pub scale: f32,
|
||||
pub x_channel_selector: Channel,
|
||||
pub y_channel_selector: Channel,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Channel {
|
||||
impl WriteElement for DisplacementMap {
|
||||
fn attrs(&self) -> Vec<quick_xml::events::attributes::Attribute> {
|
||||
let mut r = Vec::new();
|
||||
gen_attrs![
|
||||
r;
|
||||
self.scale != 0. => b"scale": self.scale,
|
||||
self.x_channel_selector != Channel::A => b"xChannelSelector": format!("{:?}", self.x_channel_selector),
|
||||
self.y_channel_selector != Channel::A => b"yChannelSelector": format!("{:?}", self.y_channel_selector)
|
||||
];
|
||||
r
|
||||
}
|
||||
|
||||
fn tag_name(&self) -> &'static str {
|
||||
"feDisplacementMap"
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum Channel {
|
||||
A,
|
||||
R,
|
||||
G,
|
||||
|
|
|
@ -3,6 +3,8 @@ use csscolorparser::Color;
|
|||
use super::WriteElement;
|
||||
|
||||
/// [feFlood](https://www.w3.org/TR/SVG11/filters.html#feFloodElement)
|
||||
// NOTE: this doesn't work for some reason, but the examples from mdn don't either.
|
||||
// might be a browser bug, def worth investigating
|
||||
#[derive(Debug)]
|
||||
pub struct Flood {
|
||||
pub flood_color: Color,
|
||||
|
|
Loading…
Reference in a new issue