mirror of
https://github.com/zoriya/react-native-svg.git
synced 2025-12-05 22:56:11 +00:00
feat: add FeGaussianBlur filter (#2352)
# Summary Continuation of #2316 Introducing new filter `FeGaussianBlur`. ### Implementation notes On Android there is no easy way to fully implement Gaussian blur, as there is no native api for this. While a basic implementation is possible with `RenderScript`, it does not allow for blur in one axis and greater than `25` ## Test Plan Example app -> Filters -> FeGaussianBlur ## Compatibility | OS | Implemented | | ------- | :---------: | | iOS | ✅ | | Android | ✅ |
This commit is contained in:
@@ -25,6 +25,7 @@ import Marker from './elements/Marker';
|
||||
import ForeignObject from './elements/ForeignObject';
|
||||
import Filter from './elements/filters/Filter';
|
||||
import FeColorMatrix from './elements/filters/FeColorMatrix';
|
||||
import FeGaussianBlur from './elements/filters/FeGaussianBlur';
|
||||
|
||||
import {
|
||||
parse,
|
||||
@@ -71,6 +72,7 @@ import {
|
||||
RNSVGUse,
|
||||
RNSVGFilter,
|
||||
RNSVGFeColorMatrix,
|
||||
RNSVGFeGaussianBlur,
|
||||
} from './fabric';
|
||||
|
||||
export {
|
||||
@@ -109,6 +111,7 @@ export type { MarkerProps } from './elements/Marker';
|
||||
export type { ForeignObjectProps } from './elements/ForeignObject';
|
||||
export type { FilterProps } from './elements/filters/Filter';
|
||||
export type { FeColorMatrixProps } from './elements/filters/FeColorMatrix';
|
||||
export type { FeGaussianBlurProps } from './elements/filters/FeGaussianBlur';
|
||||
export type { FilterPrimitiveCommonProps } from './elements/filters/FilterPrimitive';
|
||||
|
||||
export * from './lib/extract/types';
|
||||
@@ -149,6 +152,7 @@ export {
|
||||
Shape,
|
||||
Filter,
|
||||
FeColorMatrix,
|
||||
FeGaussianBlur,
|
||||
RNSVGMarker,
|
||||
RNSVGMask,
|
||||
RNSVGPattern,
|
||||
@@ -173,6 +177,7 @@ export {
|
||||
RNSVGForeignObject,
|
||||
RNSVGFilter,
|
||||
RNSVGFeColorMatrix,
|
||||
RNSVGFeGaussianBlur,
|
||||
};
|
||||
|
||||
export type {
|
||||
|
||||
40
src/elements/filters/FeGaussianBlur.tsx
Normal file
40
src/elements/filters/FeGaussianBlur.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import * as React from 'react';
|
||||
import { NativeMethods } from 'react-native';
|
||||
import RNSVGFeGaussianBlur from '../../fabric/FeGaussianBlurNativeComponent';
|
||||
import {
|
||||
extractFeGaussianBlur,
|
||||
extractFilter,
|
||||
} from '../../lib/extract/extractFilter';
|
||||
import { FilterEdgeMode, NumberProp } from '../../lib/extract/types';
|
||||
import FilterPrimitive from './FilterPrimitive';
|
||||
|
||||
export interface FeGaussianBlurProps {
|
||||
in?: string;
|
||||
stdDeviation?: NumberProp;
|
||||
// edgeMode is hard to implement and not supported by any
|
||||
// browser except safari, so it's not implemented for now
|
||||
// https://caniuse.com/mdn-api_svgfegaussianblurelement_edgemode
|
||||
edgeMode?: FilterEdgeMode;
|
||||
}
|
||||
|
||||
export default class FeGaussianBlur extends FilterPrimitive<FeGaussianBlurProps> {
|
||||
static displayName = 'FeGaussianBlur';
|
||||
|
||||
static defaultProps = {
|
||||
...this.defaultPrimitiveProps,
|
||||
stdDeviation: 0,
|
||||
edgeMode: 'none',
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<RNSVGFeGaussianBlur
|
||||
ref={(ref) =>
|
||||
this.refMethod(ref as (FeGaussianBlur & NativeMethods) | null)
|
||||
}
|
||||
{...extractFilter(this.props)}
|
||||
{...extractFeGaussianBlur(this.props)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
25
src/fabric/FeGaussianBlurNativeComponent.ts
Normal file
25
src/fabric/FeGaussianBlurNativeComponent.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
|
||||
import type { ViewProps } from './utils';
|
||||
|
||||
import { NumberProp } from '../lib/extract/types';
|
||||
import type { UnsafeMixed } from './codegenUtils';
|
||||
import { Float, WithDefault } from 'react-native/Libraries/Types/CodegenTypes';
|
||||
|
||||
type FilterEdgeMode = 'duplicate' | 'wrap' | 'none';
|
||||
|
||||
interface FilterPrimitiveCommonProps {
|
||||
x?: UnsafeMixed<NumberProp>;
|
||||
y?: UnsafeMixed<NumberProp>;
|
||||
width?: UnsafeMixed<NumberProp>;
|
||||
height?: UnsafeMixed<NumberProp>;
|
||||
result?: string;
|
||||
}
|
||||
|
||||
export interface NativeProps extends ViewProps, FilterPrimitiveCommonProps {
|
||||
in1?: string;
|
||||
stdDeviationX?: Float;
|
||||
stdDeviationY?: Float;
|
||||
edgeMode?: WithDefault<FilterEdgeMode, 'none'>;
|
||||
}
|
||||
|
||||
export default codegenNativeComponent<NativeProps>('RNSVGFeGaussianBlur');
|
||||
@@ -22,6 +22,7 @@ import RNSVGTSpan from './TSpanNativeComponent';
|
||||
import RNSVGUse from './UseNativeComponent';
|
||||
import RNSVGFilter from './FilterNativeComponent';
|
||||
import RNSVGFeColorMatrix from './FeColorMatrixNativeComponent';
|
||||
import RNSVGFeGaussianBlur from './FeGaussianBlurNativeComponent';
|
||||
|
||||
export {
|
||||
RNSVGCircle,
|
||||
@@ -48,4 +49,5 @@ export {
|
||||
RNSVGUse,
|
||||
RNSVGFilter,
|
||||
RNSVGFeColorMatrix,
|
||||
RNSVGFeGaussianBlur,
|
||||
};
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { FilterPrimitiveCommonProps } from '../elements/filters/FilterPrimitive';
|
||||
import { FeColorMatrixProps } from '../index';
|
||||
import { FeColorMatrixProps, FeGaussianBlurProps } from '../index';
|
||||
|
||||
export type FilterElement = ({ name: 'feColorMatrix' } & FeColorMatrixProps) &
|
||||
export type FilterElement = (
|
||||
| ({ name: 'feColorMatrix' } & FeColorMatrixProps)
|
||||
| ({ name: 'feGaussianBlur' } & FeGaussianBlurProps)
|
||||
) &
|
||||
FilterPrimitiveCommonProps;
|
||||
|
||||
export type Filters = Array<FilterElement>;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { FeColorMatrixProps as FeColorMatrixComponentProps } from '../../elements/filters/FeColorMatrix';
|
||||
import { FeGaussianBlurProps as FeGaussianBlurComponentProps } from '../../elements/filters/FeGaussianBlur';
|
||||
import { NativeProps as FeColorMatrixNativeProps } from '../../fabric/FeColorMatrixNativeComponent';
|
||||
import { NativeProps as FeGaussianBlurNativeProps } from '../../fabric/FeGaussianBlurNativeComponent';
|
||||
import { NumberProp } from './types';
|
||||
|
||||
const spaceReg = /\s+/;
|
||||
@@ -53,3 +55,32 @@ export const extractFeColorMatrix = (
|
||||
|
||||
return extracted;
|
||||
};
|
||||
|
||||
export const extractFeGaussianBlur = (
|
||||
props: FeGaussianBlurComponentProps
|
||||
): FeGaussianBlurNativeProps => {
|
||||
const extracted: FeGaussianBlurNativeProps = {};
|
||||
|
||||
if (props.in) {
|
||||
extracted.in1 = props.in;
|
||||
}
|
||||
if (
|
||||
typeof props.stdDeviation === 'string' &&
|
||||
props.stdDeviation.match(spaceReg)
|
||||
) {
|
||||
const stdDeviation = props.stdDeviation.split(spaceReg);
|
||||
extracted.stdDeviationX = Number(stdDeviation[0]) || 0;
|
||||
extracted.stdDeviationY = Number(stdDeviation[1]) || 0;
|
||||
} else if (
|
||||
typeof props.stdDeviation === 'number' ||
|
||||
(typeof props.stdDeviation === 'string' &&
|
||||
!props.stdDeviation.match(spaceReg))
|
||||
) {
|
||||
extracted.stdDeviationX = Number(props.stdDeviation) || 0;
|
||||
extracted.stdDeviationY = Number(props.stdDeviation) || 0;
|
||||
}
|
||||
if (props.edgeMode) {
|
||||
extracted.edgeMode = props.edgeMode;
|
||||
}
|
||||
return extracted;
|
||||
};
|
||||
|
||||
@@ -27,6 +27,7 @@ import Mask from './elements/Mask';
|
||||
import Marker from './elements/Marker';
|
||||
import Filter from './elements/filters/Filter';
|
||||
import FeColorMatrix from './elements/filters/FeColorMatrix';
|
||||
import FeGaussianBlur from './elements/filters/FeGaussianBlur';
|
||||
|
||||
export const tags: { [tag: string]: ComponentType } = {
|
||||
svg: Svg,
|
||||
@@ -54,6 +55,7 @@ export const tags: { [tag: string]: ComponentType } = {
|
||||
marker: Marker,
|
||||
filter: Filter,
|
||||
feColorMatrix: FeColorMatrix,
|
||||
feGaussianBlur: FeGaussianBlur,
|
||||
};
|
||||
|
||||
function missingTag() {
|
||||
|
||||
Reference in New Issue
Block a user