diff --git a/USAGE.md b/USAGE.md index 1eeecac9..65e9b446 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1257,14 +1257,37 @@ const styles = StyleSheet.create({ Filter effects are a way of processing an element’s rendering before it is displayed in the document. Typically, rendering an element via CSS or SVG can conceptually be described as if the element, including its children, are drawn into a buffer (such as a raster image) and then that buffer is composited into the elements parent. Filters apply an effect before the compositing stage. Examples of such effects are blurring, changing color intensity and warping the image. -Currently supported\* filters are: +> [!NOTE] +> Not all filters have been implemented on native platforms yet. However, they do work on the Web, so we added them. Some filters will display a warning indicating they are not currently supported. + +The following filters have been implemented: - FeColorMatrix - FeGaussianBlur - FeMerge - FeOffset -\*_More filters are coming soon_ +Not supported yet: + +- FeBlend +- FeComponentTransfer +- FeComposite +- FeConvolveMatrix +- FeDiffuseLighting +- FeDisplacementMap +- FeDropShadow +- FeFlood +- FeFuncA +- FeFuncB +- FeFuncG +- FeFuncR +- FeImage +- FeMorphology +- FePointLight +- FeSpecularLighting +- FeSpotLight +- FeTile +- FeTurbulence Exmaple use of filters: diff --git a/src/ReactNativeSVG.ts b/src/ReactNativeSVG.ts index cc4bc1cd..addd927d 100644 --- a/src/ReactNativeSVG.ts +++ b/src/ReactNativeSVG.ts @@ -63,11 +63,33 @@ export { export type { CircleProps } from './elements/Circle'; export type { ClipPathProps } from './elements/ClipPath'; export type { EllipseProps } from './elements/Ellipse'; +export type { FeBlendProps } from './elements/filters/FeBlend'; export type { FeColorMatrixProps } from './elements/filters/FeColorMatrix'; +export type { FeComponentTransferProps } from './elements/filters/FeComponentTransfer'; +export type { + FeFuncAProps, + FeFuncBProps, + FeFuncGProps, + FeFuncRProps, +} from './elements/filters/FeComponentTransferFunction'; +export type { FeCompositeProps } from './elements/filters/FeComposite'; +export type { FeConvolveMatrixProps } from './elements/filters/FeConvolveMatrix'; +export type { FeDiffuseLightingProps } from './elements/filters/FeDiffuseLighting'; +export type { FeDisplacementMapProps } from './elements/filters/FeDisplacementMap'; +export type { FeDistantLightProps } from './elements/filters/FeDistantLight'; +export type { FeDropShadowProps } from './elements/filters/FeDropShadow'; +export type { FeFloodProps } from './elements/filters/FeFlood'; export type { FeGaussianBlurProps } from './elements/filters/FeGaussianBlur'; +export type { FeImageProps } from './elements/filters/FeImage'; export type { FeMergeProps } from './elements/filters/FeMerge'; export type { FeMergeNodeProps } from './elements/filters/FeMergeNode'; +export type { FeMorphologyProps } from './elements/filters/FeMorphology'; export type { FeOffsetProps } from './elements/filters/FeOffset'; +export type { FePointLightProps } from './elements/filters/FePointLight'; +export type { FeSpecularLightingProps } from './elements/filters/FeSpecularLighting'; +export type { FeSpotLightProps } from './elements/filters/FeSpotLight'; +export type { FeTileProps } from './elements/filters/FeTile'; +export type { FeTurbulenceProps } from './elements/filters/FeTurbulence'; export type { FilterProps } from './elements/filters/Filter'; export type { FilterPrimitiveCommonProps } from './elements/filters/FilterPrimitive'; export type { ForeignObjectProps } from './elements/ForeignObject'; diff --git a/src/elements.ts b/src/elements.ts index 19b01d02..e2bbbee3 100644 --- a/src/elements.ts +++ b/src/elements.ts @@ -22,11 +22,33 @@ import TSpan from './elements/TSpan'; import Text from './elements/Text'; import TextPath from './elements/TextPath'; import Use from './elements/Use'; +import FeBlend from './elements/filters/FeBlend'; import FeColorMatrix from './elements/filters/FeColorMatrix'; +import FeComponentTransfer from './elements/filters/FeComponentTransfer'; +import { + FeFuncA, + FeFuncB, + FeFuncG, + FeFuncR, +} from './elements/filters/FeComponentTransferFunction'; +import FeComposite from './elements/filters/FeComposite'; +import FeConvolveMatrix from './elements/filters/FeConvolveMatrix'; +import FeDiffuseLighting from './elements/filters/FeDiffuseLighting'; +import FeDisplacementMap from './elements/filters/FeDisplacementMap'; +import FeDistantLight from './elements/filters/FeDistantLight'; +import FeDropShadow from './elements/filters/FeDropShadow'; +import FeFlood from './elements/filters/FeFlood'; import FeGaussianBlur from './elements/filters/FeGaussianBlur'; +import FeImage from './elements/filters/FeImage'; import FeMerge from './elements/filters/FeMerge'; import FeMergeNode from './elements/filters/FeMergeNode'; +import FeMorphology from './elements/filters/FeMorphology'; import FeOffset from './elements/filters/FeOffset'; +import FePointLight from './elements/filters/FePointLight'; +import FeSpecularLighting from './elements/filters/FeSpecularLighting'; +import FeSpotLight from './elements/filters/FeSpotLight'; +import FeTile from './elements/filters/FeTile'; +import FeTurbulence from './elements/filters/FeTurbulence'; import Filter from './elements/filters/Filter'; export { @@ -34,11 +56,31 @@ export { ClipPath, Defs, Ellipse, + FeBlend, FeColorMatrix, + FeComponentTransfer, + FeComposite, + FeConvolveMatrix, + FeDiffuseLighting, + FeDisplacementMap, + FeDistantLight, + FeDropShadow, + FeFlood, + FeFuncA, + FeFuncB, + FeFuncG, + FeFuncR, FeGaussianBlur, + FeImage, FeMerge, FeMergeNode, + FeMorphology, FeOffset, + FePointLight, + FeSpecularLighting, + FeSpotLight, + FeTile, + FeTurbulence, Filter, ForeignObject, G, @@ -56,9 +98,9 @@ export { Stop, Svg, Symbol, - TSpan, Text, TextPath, + TSpan, Use, }; diff --git a/src/elements.web.ts b/src/elements.web.ts index 34a348e6..d8b4e93c 100644 --- a/src/elements.web.ts +++ b/src/elements.web.ts @@ -1,11 +1,33 @@ import type { CircleProps } from './elements/Circle'; import type { ClipPathProps } from './elements/ClipPath'; import type { EllipseProps } from './elements/Ellipse'; +import type { FeBlendProps } from './elements/filters/FeBlend'; import type { FeColorMatrixProps } from './elements/filters/FeColorMatrix'; +import type { FeComponentTransferProps } from './elements/filters/FeComponentTransfer'; +import type { + FeFuncAProps, + FeFuncBProps, + FeFuncGProps, + FeFuncRProps, +} from './elements/filters/FeComponentTransferFunction'; +import type { FeCompositeProps } from './elements/filters/FeComposite'; +import type { FeConvolveMatrixProps } from './elements/filters/FeConvolveMatrix'; +import type { FeDiffuseLightingProps } from './elements/filters/FeDiffuseLighting'; +import type { FeDisplacementMapProps } from './elements/filters/FeDisplacementMap'; +import type { FeDistantLightProps } from './elements/filters/FeDistantLight'; +import type { FeDropShadowProps } from './elements/filters/FeDropShadow'; +import type { FeFloodProps } from './elements/filters/FeFlood'; import type { FeGaussianBlurProps } from './elements/filters/FeGaussianBlur'; +import type { FeImageProps } from './elements/filters/FeImage'; import type { FeMergeProps } from './elements/filters/FeMerge'; import type { FeMergeNodeProps } from './elements/filters/FeMergeNode'; +import type { FeMorphologyProps } from './elements/filters/FeMorphology'; import type { FeOffsetProps } from './elements/filters/FeOffset'; +import type { FePointLightProps } from './elements/filters/FePointLight'; +import type { FeSpecularLightingProps } from './elements/filters/FeSpecularLighting'; +import type { FeSpotLightProps } from './elements/filters/FeSpotLight'; +import type { FeTileProps } from './elements/filters/FeTile'; +import type { FeTurbulenceProps } from './elements/filters/FeTurbulence'; import type { FilterProps } from './elements/filters/Filter'; import type { ForeignObjectProps } from './elements/ForeignObject'; import type { GProps } from './elements/G'; @@ -47,14 +69,78 @@ export class Ellipse extends WebShape { tag = 'ellipse' as const; } +export class FeBlend extends WebShape { + tag = 'feBlend' as const; +} + export class FeColorMatrix extends WebShape { tag = 'feColorMatrix' as const; } +export class FeComponentTransfer extends WebShape< + BaseProps & FeComponentTransferProps +> { + tag = 'feComponentTransfer' as const; +} + +export class FeComposite extends WebShape { + tag = 'feComposite' as const; +} + +export class FeConvolveMatrix extends WebShape< + BaseProps & FeConvolveMatrixProps +> { + tag = 'feConvolveMatrix' as const; +} + +export class FeDiffuseLighting extends WebShape< + BaseProps & FeDiffuseLightingProps +> { + tag = 'feDiffuseLighting' as const; +} + +export class FeDisplacementMap extends WebShape< + BaseProps & FeDisplacementMapProps +> { + tag = 'feDisplacementMap' as const; +} + +export class FeDistantLight extends WebShape { + tag = 'feDistantLight' as const; +} + +export class FeDropShadow extends WebShape { + tag = 'feDropShadow' as const; +} + +export class FeFlood extends WebShape { + tag = 'feFlood' as const; +} + +export class FeFuncA extends WebShape { + tag = 'feFuncA' as const; +} + +export class FeFuncB extends WebShape { + tag = 'feFuncB' as const; +} + +export class FeFuncG extends WebShape { + tag = 'feFuncG' as const; +} + +export class FeFuncR extends WebShape { + tag = 'feFuncR' as const; +} + export class FeGaussianBlur extends WebShape { tag = 'feGaussianBlur' as const; } +export class FeImage extends WebShape { + tag = 'feImage' as const; +} + export class FeMerge extends WebShape { tag = 'feMerge' as const; } @@ -63,10 +149,36 @@ export class FeMergeNode extends WebShape { tag = 'feMergeNode' as const; } +export class FeMorphology extends WebShape { + tag = 'feMorphology' as const; +} + export class FeOffset extends WebShape { tag = 'feOffset' as const; } +export class FePointLight extends WebShape { + tag = 'fePointLight' as const; +} + +export class FeSpecularLighting extends WebShape< + BaseProps & FeSpecularLightingProps +> { + tag = 'feSpecularLighting' as const; +} + +export class FeSpotLight extends WebShape { + tag = 'feSpotLight' as const; +} + +export class FeTile extends WebShape { + tag = 'feTile' as const; +} + +export class FeTurbulence extends WebShape { + tag = 'feTurbulence' as const; +} + export class Filter extends WebShape { tag = 'filter' as const; } diff --git a/src/elements/filters/FeBlend.tsx b/src/elements/filters/FeBlend.tsx new file mode 100644 index 00000000..d65e0bf5 --- /dev/null +++ b/src/elements/filters/FeBlend.tsx @@ -0,0 +1,23 @@ +import { warnUnimplementedFilter } from '../../lib/util'; +import FilterPrimitive from './FilterPrimitive'; + +type BlendMode = 'normal' | 'multiply' | 'screen' | 'darken' | 'lighten'; + +export interface FeBlendProps { + in?: string; + in2?: string; + mode?: BlendMode; +} + +export default class FeBlend extends FilterPrimitive { + static displayName = 'FeBlend'; + + static defaultProps = { + ...this.defaultPrimitiveProps, + }; + + render() { + warnUnimplementedFilter(); + return null; + } +} diff --git a/src/elements/filters/FeComponentTransfer.tsx b/src/elements/filters/FeComponentTransfer.tsx new file mode 100644 index 00000000..3ed6b6e6 --- /dev/null +++ b/src/elements/filters/FeComponentTransfer.tsx @@ -0,0 +1,21 @@ +import * as React from 'react'; +import FilterPrimitive from './FilterPrimitive'; +import { warnUnimplementedFilter } from '../../lib/util'; + +export interface FeComponentTransferProps { + in?: string; + children?: React.ReactElement | Array; +} + +export default class FeComponentTransfer extends FilterPrimitive { + static displayName = 'FeComponentTransfer'; + + static defaultProps = { + ...this.defaultPrimitiveProps, + }; + + render() { + warnUnimplementedFilter(); + return null; + } +} diff --git a/src/elements/filters/FeComponentTransferFunction.tsx b/src/elements/filters/FeComponentTransferFunction.tsx new file mode 100644 index 00000000..469f09f3 --- /dev/null +++ b/src/elements/filters/FeComponentTransferFunction.tsx @@ -0,0 +1,60 @@ +import { NumberArray, NumberProp } from '../../lib/extract/types'; +import { warnUnimplementedFilter } from '../../lib/util'; +import FilterPrimitive from './FilterPrimitive'; + +type FunctionChannel = 'R' | 'G' | 'B' | 'A' | 'UNKNOWN'; +type FunctionType = 'identity' | 'table' | 'discrete' | 'linear' | 'gamma'; + +export type FeComponentTransferFunctionProps = { + type: FunctionType; + tableValues?: NumberArray; + slope?: NumberProp; + intercept?: NumberProp; + amplitude?: NumberProp; + exponent?: NumberProp; + offset?: NumberProp; +}; + +export default class FeComponentTransferFunction extends FilterPrimitive { + channel: FunctionChannel = 'UNKNOWN'; + static defaultProps: React.ComponentProps< + typeof FeComponentTransferFunction + > = { + type: 'identity', + tableValues: [], + slope: 1, + intercept: 0, + amplitude: 1, + exponent: 1, + offset: 0, + }; + + render() { + warnUnimplementedFilter(); + return null; + } +} + +export type FeFuncRProps = FeComponentTransferFunctionProps; +export class FeFuncR extends FeComponentTransferFunction { + static displayName = 'FeFuncR'; + channel: FunctionChannel = 'R'; +} + +export type FeFuncGProps = FeComponentTransferFunctionProps; +export class FeFuncG extends FeComponentTransferFunction { + static displayName = 'FeFuncG'; + channel: FunctionChannel = 'G'; +} + +export type FeFuncBProps = FeComponentTransferFunctionProps; +export class FeFuncB extends FeComponentTransferFunction { + static displayName = 'FeFuncB'; + channel: FunctionChannel = 'B'; +} + +export type FeFuncAProps = FeComponentTransferFunctionProps; +export class FeFuncA extends FeComponentTransferFunction { + static displayName = 'FeFuncA'; + channel: FunctionChannel = 'A'; +} diff --git a/src/elements/filters/FeComposite.tsx b/src/elements/filters/FeComposite.tsx new file mode 100644 index 00000000..324a2c60 --- /dev/null +++ b/src/elements/filters/FeComposite.tsx @@ -0,0 +1,34 @@ +import { NumberProp } from '../../lib/extract/types'; +import { warnUnimplementedFilter } from '../../lib/util'; +import FilterPrimitive from './FilterPrimitive'; + +type FeCompositeOperator = + | 'over' + | 'in' + | 'out' + | 'atop' + | 'xor' + | 'arithmetic'; + +export interface FeCompositeProps { + in?: string; + in2?: string; + operator?: FeCompositeOperator; + k1?: NumberProp; + k2?: NumberProp; + k3?: NumberProp; + k4?: NumberProp; +} + +export default class FeComposite extends FilterPrimitive { + static displayName = 'FeComposite'; + + static defaultProps = { + ...this.defaultPrimitiveProps, + }; + + render() { + warnUnimplementedFilter(); + return null; + } +} diff --git a/src/elements/filters/FeConvolveMatrix.tsx b/src/elements/filters/FeConvolveMatrix.tsx new file mode 100644 index 00000000..4974d75c --- /dev/null +++ b/src/elements/filters/FeConvolveMatrix.tsx @@ -0,0 +1,30 @@ +import { BooleanProp, NumberArray, NumberProp } from '../../lib/extract/types'; +import { warnUnimplementedFilter } from '../../lib/util'; +import FilterPrimitive from './FilterPrimitive'; +import { EdgeMode } from './types'; + +export interface FeConvolveMatrixProps { + in?: string; + order?: NumberArray; + kernelMatrix?: NumberArray; + divisor?: NumberProp; + bias?: NumberProp; + targetX?: NumberProp; + targetY?: NumberProp; + edgeMode?: EdgeMode; + kernelUnitLength?: NumberArray; + preserveAlpha?: BooleanProp; +} + +export default class FeConvolveMatrix extends FilterPrimitive { + static displayName = 'FeConvolveMatrix'; + + static defaultProps = { + ...this.defaultPrimitiveProps, + }; + + render() { + warnUnimplementedFilter(); + return null; + } +} diff --git a/src/elements/filters/FeDiffuseLighting.tsx b/src/elements/filters/FeDiffuseLighting.tsx new file mode 100644 index 00000000..fc56429b --- /dev/null +++ b/src/elements/filters/FeDiffuseLighting.tsx @@ -0,0 +1,23 @@ +import { NumberArray, NumberProp } from '../../lib/extract/types'; +import { warnUnimplementedFilter } from '../../lib/util'; +import FilterPrimitive from './FilterPrimitive'; + +export interface FeDiffuseLightingProps { + in?: string; + surfaceScale?: NumberProp; + diffuseConstant?: NumberProp; + kernelUnitLength?: NumberArray; +} + +export default class FeDiffuseLighting extends FilterPrimitive { + static displayName = 'FeDiffuseLighting'; + + static defaultProps = { + ...this.defaultPrimitiveProps, + }; + + render() { + warnUnimplementedFilter(); + return null; + } +} diff --git a/src/elements/filters/FeDisplacementMap.tsx b/src/elements/filters/FeDisplacementMap.tsx new file mode 100644 index 00000000..1418eaf7 --- /dev/null +++ b/src/elements/filters/FeDisplacementMap.tsx @@ -0,0 +1,25 @@ +import { NumberProp } from '../../lib/extract/types'; +import { warnUnimplementedFilter } from '../../lib/util'; +import FilterPrimitive from './FilterPrimitive'; +import { ChannelSelector } from './types'; + +export interface FeDisplacementMapProps { + in?: string; + in2?: string; + scale?: NumberProp; + xChannelSelector?: ChannelSelector; + yChannelSelector?: ChannelSelector; +} + +export default class FeDisplacementMap extends FilterPrimitive { + static displayName = 'FeDisplacementMap'; + + static defaultProps = { + ...this.defaultPrimitiveProps, + }; + + render() { + warnUnimplementedFilter(); + return null; + } +} diff --git a/src/elements/filters/FeDistantLight.tsx b/src/elements/filters/FeDistantLight.tsx new file mode 100644 index 00000000..0f3bb59d --- /dev/null +++ b/src/elements/filters/FeDistantLight.tsx @@ -0,0 +1,19 @@ +import { Component } from 'react'; +import { NumberProp } from '../../lib/extract/types'; +import { warnUnimplementedFilter } from '../../lib/util'; + +export interface FeDistantLightProps { + azimuth?: NumberProp; + elevation?: NumberProp; +} + +export default class FeDistantLight extends Component { + static displayName = 'FeDistantLight'; + + static defaultProps = {}; + + render() { + warnUnimplementedFilter(); + return null; + } +} diff --git a/src/elements/filters/FeDropShadow.tsx b/src/elements/filters/FeDropShadow.tsx new file mode 100644 index 00000000..25052d8b --- /dev/null +++ b/src/elements/filters/FeDropShadow.tsx @@ -0,0 +1,23 @@ +import { NumberArray, NumberProp } from '../../lib/extract/types'; +import { warnUnimplementedFilter } from '../../lib/util'; +import FilterPrimitive from './FilterPrimitive'; + +export interface FeDropShadowProps { + in?: string; + stdDeviation?: NumberArray; + dx?: NumberProp; + dy?: NumberProp; +} + +export default class FeDropShadow extends FilterPrimitive { + static displayName = 'FeDropShadow'; + + static defaultProps = { + ...this.defaultPrimitiveProps, + }; + + render() { + warnUnimplementedFilter(); + return null; + } +} diff --git a/src/elements/filters/FeFlood.tsx b/src/elements/filters/FeFlood.tsx new file mode 100644 index 00000000..8d530dfc --- /dev/null +++ b/src/elements/filters/FeFlood.tsx @@ -0,0 +1,23 @@ +import { ColorValue } from 'react-native'; +import { NumberProp } from '../../lib/extract/types'; +import { warnUnimplementedFilter } from '../../lib/util'; +import FilterPrimitive from './FilterPrimitive'; + +export interface FeFloodProps { + in?: string; + floodColor?: ColorValue; + floodOpacity?: NumberProp; +} + +export default class FeFlood extends FilterPrimitive { + static displayName = 'FeFlood'; + + static defaultProps = { + ...this.defaultPrimitiveProps, + }; + + render() { + warnUnimplementedFilter(); + return null; + } +} diff --git a/src/elements/filters/FeImage.tsx b/src/elements/filters/FeImage.tsx new file mode 100644 index 00000000..c46da879 --- /dev/null +++ b/src/elements/filters/FeImage.tsx @@ -0,0 +1,21 @@ +import { warnUnimplementedFilter } from '../../lib/util'; +import FilterPrimitive from './FilterPrimitive'; + +export interface FeImageProps { + href?: string; + preserveAspectRatio?: string; + crossOrigin?: 'anonymous' | 'use-credentials' | ''; +} + +export default class FeImage extends FilterPrimitive { + static displayName = 'FeImage'; + + static defaultProps = { + ...this.defaultPrimitiveProps, + }; + + render() { + warnUnimplementedFilter(); + return null; + } +} diff --git a/src/elements/filters/FeMorphology.tsx b/src/elements/filters/FeMorphology.tsx new file mode 100644 index 00000000..d9358f78 --- /dev/null +++ b/src/elements/filters/FeMorphology.tsx @@ -0,0 +1,22 @@ +import { NumberArray } from '../../lib/extract/types'; +import { warnUnimplementedFilter } from '../../lib/util'; +import FilterPrimitive from './FilterPrimitive'; + +export interface FeMorphologyProps { + in?: string; + operator?: 'erode' | 'dilate'; + radius?: NumberArray; +} + +export default class FeMorphology extends FilterPrimitive { + static displayName = 'FeMorphology'; + + static defaultProps = { + ...this.defaultPrimitiveProps, + }; + + render() { + warnUnimplementedFilter(); + return null; + } +} diff --git a/src/elements/filters/FePointLight.tsx b/src/elements/filters/FePointLight.tsx new file mode 100644 index 00000000..5aaa4e32 --- /dev/null +++ b/src/elements/filters/FePointLight.tsx @@ -0,0 +1,20 @@ +import { Component } from 'react'; +import { NumberProp } from '../../lib/extract/types'; +import { warnUnimplementedFilter } from '../../lib/util'; + +export interface FePointLightProps { + x?: NumberProp; + y?: NumberProp; + z?: NumberProp; +} + +export default class FePointLight extends Component { + static displayName = 'FePointLight'; + + static defaultProps = {}; + + render() { + warnUnimplementedFilter(); + return null; + } +} diff --git a/src/elements/filters/FeSpecularLighting.tsx b/src/elements/filters/FeSpecularLighting.tsx new file mode 100644 index 00000000..e9728d63 --- /dev/null +++ b/src/elements/filters/FeSpecularLighting.tsx @@ -0,0 +1,24 @@ +import { NumberArray, NumberProp } from '../../lib/extract/types'; +import { warnUnimplementedFilter } from '../../lib/util'; +import FilterPrimitive from './FilterPrimitive'; + +export interface FeSpecularLightingProps { + in?: string; + surfaceScale?: NumberProp; + specularConstant?: NumberProp; + specularExponent?: NumberProp; + kernelUnitLength?: NumberArray; +} + +export default class FeSpecularLighting extends FilterPrimitive { + static displayName = 'FeSpecularLighting'; + + static defaultProps = { + ...this.defaultPrimitiveProps, + }; + + render() { + warnUnimplementedFilter(); + return null; + } +} diff --git a/src/elements/filters/FeSpotLight.tsx b/src/elements/filters/FeSpotLight.tsx new file mode 100644 index 00000000..36f43339 --- /dev/null +++ b/src/elements/filters/FeSpotLight.tsx @@ -0,0 +1,25 @@ +import { Component } from 'react'; +import { NumberProp } from '../../lib/extract/types'; +import { warnUnimplementedFilter } from '../../lib/util'; + +export interface FeSpotLightProps { + x?: NumberProp; + y?: NumberProp; + z?: NumberProp; + pointsAtX?: NumberProp; + pointsAtY?: NumberProp; + pointsAtZ?: NumberProp; + specularExponent?: NumberProp; + limitingConeAngle?: NumberProp; +} + +export default class FeSpotLight extends Component { + static displayName = 'FeSpotLight'; + + static defaultProps = {}; + + render() { + warnUnimplementedFilter(); + return null; + } +} diff --git a/src/elements/filters/FeTile.tsx b/src/elements/filters/FeTile.tsx new file mode 100644 index 00000000..0bca4721 --- /dev/null +++ b/src/elements/filters/FeTile.tsx @@ -0,0 +1,19 @@ +import { warnUnimplementedFilter } from '../../lib/util'; +import FilterPrimitive from './FilterPrimitive'; + +export interface FeTileProps { + in?: string; +} + +export default class FeTile extends FilterPrimitive { + static displayName = 'FeTile'; + + static defaultProps = { + ...this.defaultPrimitiveProps, + }; + + render() { + warnUnimplementedFilter(); + return null; + } +} diff --git a/src/elements/filters/FeTurbulence.tsx b/src/elements/filters/FeTurbulence.tsx new file mode 100644 index 00000000..a83afdd9 --- /dev/null +++ b/src/elements/filters/FeTurbulence.tsx @@ -0,0 +1,24 @@ +import { NumberArray, NumberProp } from '../../lib/extract/types'; +import { warnUnimplementedFilter } from '../../lib/util'; +import FilterPrimitive from './FilterPrimitive'; + +export interface FeTurbulenceProps { + baseFrequency?: NumberArray; + numOctaves?: NumberProp; + seed?: NumberProp; + stitchTiles?: 'stitch' | 'noStitch'; + type?: 'fractalNoise' | 'turbulence'; +} + +export default class FeTurbulence extends FilterPrimitive { + static displayName = 'FeTurbulence'; + + static defaultProps = { + ...this.defaultPrimitiveProps, + }; + + render() { + warnUnimplementedFilter(); + return null; + } +} diff --git a/src/elements/filters/types.ts b/src/elements/filters/types.ts new file mode 100644 index 00000000..503786fc --- /dev/null +++ b/src/elements/filters/types.ts @@ -0,0 +1,2 @@ +export type EdgeMode = 'duplicate' | 'wrap' | 'none'; +export type ChannelSelector = 'R' | 'G' | 'B' | 'A'; diff --git a/src/lib/extract/types.ts b/src/lib/extract/types.ts index 7f308d99..0f5a80db 100644 --- a/src/lib/extract/types.ts +++ b/src/lib/extract/types.ts @@ -9,6 +9,7 @@ import type React from 'react'; export type NumberProp = string | number; export type NumberArray = NumberProp[] | NumberProp; +export type BooleanProp = boolean | 'true' | 'false'; export type FillRule = 'evenodd' | 'nonzero'; export type Units = 'userSpaceOnUse' | 'objectBoundingBox'; diff --git a/src/lib/util.ts b/src/lib/util.ts index 488ce034..9464db48 100644 --- a/src/lib/util.ts +++ b/src/lib/util.ts @@ -1,3 +1,5 @@ +import warnOnce from 'warn-once'; + export function pickNotNil(object: { [prop: string]: unknown }) { const result: { [prop: string]: unknown } = {}; for (const key in object) { @@ -15,3 +17,35 @@ export const idPattern = /#([^)]+)\)?$/; export const getRandomNumber = () => Math.floor(Math.random() * Math.floor(Math.random() * Date.now())); + +export const warnUnimplementedFilter = () => { + warnOnce( + true, + `Some of the used filters are not yet supported on native platforms. Please check the USAGE.md for more info. Not implemented filters:\n`, + JSON.stringify( + [ + 'FeBlend', + 'FeComponentTransfer', + 'FeComposite', + 'FeConvolveMatrix', + 'FeDiffuseLighting', + 'FeDisplacementMap', + 'FeDropShadow', + 'FeFlood', + 'FeFuncA', + 'FeFuncB', + 'FeFuncG', + 'FeFuncR', + 'FeImage', + 'FeMorphology', + 'FePointLight', + 'FeSpecularLighting', + 'FeSpotLight', + 'FeTile', + 'FeTurbulence', + ], + null, + 2 + ) + ); +}; diff --git a/src/xmlTags.ts b/src/xmlTags.ts index fc34fdb0..2481e815 100644 --- a/src/xmlTags.ts +++ b/src/xmlTags.ts @@ -3,11 +3,27 @@ import { ClipPath, Defs, Ellipse, + FeBlend, FeColorMatrix, + FeComponentTransfer, + FeComposite, + FeConvolveMatrix, + FeDiffuseLighting, + FeDisplacementMap, + FeDistantLight, + FeDropShadow, + FeFlood, FeGaussianBlur, + FeImage, FeMerge, FeMergeNode, + FeMorphology, FeOffset, + FePointLight, + FeSpecularLighting, + FeSpotLight, + FeTile, + FeTurbulence, Filter, ForeignObject, G, @@ -37,11 +53,27 @@ export const tags = { defs: Defs, ellipse: Ellipse, filter: Filter, + feBlend: FeBlend, feColorMatrix: FeColorMatrix, + feComponentTransfer: FeComponentTransfer, + feComposite: FeComposite, + feConvolveMatrix: FeConvolveMatrix, + feDiffuseLighting: FeDiffuseLighting, + feDisplacementMap: FeDisplacementMap, + feDistantLight: FeDistantLight, + feDropShadow: FeDropShadow, + feFlood: FeFlood, feGaussianBlur: FeGaussianBlur, + feImage: FeImage, feMerge: FeMerge, feMergeNode: FeMergeNode, + feMorphology: FeMorphology, feOffset: FeOffset, + fePointLight: FePointLight, + feSpecularLighting: FeSpecularLighting, + feSpotLight: FeSpotLight, + feTile: FeTile, + feTurbulence: FeTurbulence, foreignObject: ForeignObject, g: G, image: Image,