react-native-svg
Version:
SVG library for react-native
183 lines (162 loc) • 5.6 kB
text/typescript
import React from 'react';
import { ColorValue, processColor } from 'react-native';
import { FeBlendProps as FeBlendComponentProps } from '../../elements/filters/FeBlend';
import { FeColorMatrixProps as FeColorMatrixComponentProps } from '../../elements/filters/FeColorMatrix';
import { FeCompositeProps as FeCompositeComponentProps } from '../../elements/filters/FeComposite';
import { FeFloodProps as FeFloodComponentProps } from '../../elements/filters/FeFlood';
import { FeGaussianBlurProps as FeGaussianBlurComponentProps } from '../../elements/filters/FeGaussianBlur';
import { FeMergeProps as FeMergeComponentProps } from '../../elements/filters/FeMerge';
import { NativeProps as FeBlendNativeProps } from '../../fabric/FeBlendNativeComponent';
import { NativeProps as FeColorMatrixNativeProps } from '../../fabric/FeColorMatrixNativeComponent';
import { NativeProps as FeCompositeNativeProps } from '../../fabric/FeCompositeNativeComponent';
import { NativeProps as FeFloodNativeProps } from '../../fabric/FeFloodNativeComponent';
import { NativeProps as FeGaussianBlurNativeProps } from '../../fabric/FeGaussianBlurNativeComponent';
import { NativeProps as FeMergeNativeProps } from '../../fabric/FeMergeNativeComponent';
import extractBrush from './extractBrush';
import extractOpacity from './extractOpacity';
import { NumberProp } from './types';
const spaceReg = /\s+/;
interface FilterPrimitiveCommonProps {
x?: NumberProp;
y?: NumberProp;
width?: NumberProp;
height?: NumberProp;
result?: string;
}
export const extractFilter = (
props: FilterPrimitiveCommonProps
): FilterPrimitiveCommonProps => {
const { x, y, width, height, result } = props;
const extracted: FilterPrimitiveCommonProps = {
x,
y,
width,
height,
result,
};
return extracted;
};
export const extractIn = (props: { in?: string }) => {
if (props.in) {
return { in1: props.in };
}
return {};
};
export const extractFeBlend = (
props: FeBlendComponentProps
): FeBlendNativeProps => {
const extracted: FeBlendNativeProps = {};
if (props.in2) {
extracted.in2 = props.in2;
}
if (props.mode) {
extracted.mode = props.mode;
}
return extracted;
};
export const extractFeColorMatrix = (
props: FeColorMatrixComponentProps
): FeColorMatrixNativeProps => {
const extracted: FeColorMatrixNativeProps = {};
if (props.values !== undefined) {
if (Array.isArray(props.values)) {
extracted.values = props.values.map((num) =>
typeof num === 'number' ? num : parseFloat(num)
);
} else if (typeof props.values === 'number') {
extracted.values = [props.values];
} else if (typeof props.values === 'string') {
extracted.values = props.values
.split(spaceReg)
.map(parseFloat)
.filter((el: number) => !isNaN(el));
} else {
console.warn('Invalid value for FeColorMatrix `values` prop');
}
}
if (props.type) {
extracted.type = props.type;
}
return extracted;
};
export const extractFeComposite = (
props: FeCompositeComponentProps
): FeCompositeNativeProps => {
const extracted: FeCompositeNativeProps = {
in1: props.in || '',
in2: props.in2 || '',
operator1: props.operator || 'over',
};
(['k1', 'k2', 'k3', 'k4'] as const).forEach((key) => {
if (props[key] !== undefined) {
extracted[key] = Number(props[key]) || 0;
}
});
return extracted;
};
const defaultFill = { type: 0, payload: processColor('black') as ColorValue };
export default function extractFeFlood(
props: FeFloodComponentProps
): FeFloodNativeProps {
const extracted: FeFloodNativeProps = {};
const { floodColor, floodOpacity } = props;
if (floodColor != null) {
extracted.floodColor =
!floodColor && typeof floodColor !== 'number'
? defaultFill
: (extractBrush(floodColor) as unknown as string);
} else {
// we want the default value of fill to be black to match the spec
extracted.floodColor = defaultFill;
}
if (floodOpacity != null) {
extracted.floodOpacity = extractOpacity(floodOpacity);
}
return extracted;
}
export const extractFeGaussianBlur = (
props: FeGaussianBlurComponentProps
): FeGaussianBlurNativeProps => {
const extracted: FeGaussianBlurNativeProps = {};
if (Array.isArray(props.stdDeviation)) {
extracted.stdDeviationX = Number(props.stdDeviation[0]) || 0;
extracted.stdDeviationY = Number(props.stdDeviation[1]) || 0;
} else 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;
};
export const extractFeMerge = (
props: FeMergeComponentProps,
parent: unknown
): FeMergeNativeProps => {
const nodes: Array<string> = [];
const childArray = props.children
? React.Children.map(props.children, (child) =>
React.cloneElement(child, { parent })
)
: [];
const l = childArray.length;
for (let i = 0; i < l; i++) {
const {
props: { in: in1 },
} = childArray[i];
nodes.push(in1 || '');
}
return { nodes };
};