mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-05 16:04:38 +00:00
feat: introduce CSS filter API on FilterImage (#2359)
# Summary Provide a **CSS**-like filter API in the `FilterImage` component. Unlike the SVG filter API, which can be complex and challenging even for simple tasks, the CSS API is straightforward and allows users to quickly achieve satisfactory results. The full API can be viewed here https://developer.mozilla.org/en-US/docs/Web/CSS/filter _We support all `<filter-function>` listed in the docs while we do not support functions from `<url>` (`url()` and `src()`)._ All shorthands are implemented according to the W3 standard described here https://www.w3.org/TR/filter-effects-1/#ShorthandEquivalents This PR also changes the `filters` prop behavior as it adds `fe` in front of `name` attribute to not introduce any abstract above that specified in the docs. ```tsx <FilterImage source={myImage} filters={[{ name: 'colorMatrix', type: 'saturate', values: 0.2 }]) /> ``` is now ```tsx <FilterImage source={myImage} filters={[{ name: 'feColorMatrix', type: 'saturate', values: 0.2 }]) /> ``` ## Examples Below are the simple examples of the usage through `StyleSheet` ```tsx import React from 'react'; import {StyleSheet, View} from 'react-native'; import {FilterImage} from 'react-native-svg/filter-image'; export default () => { return ( <FilterImage style={styles.image} source={{ uri: 'https://cdn.pixabay.com/photo/2024/05/26/00/40/lizard-8787888_1280.jpg', }} /> ); }; const styles = StyleSheet.create({ image: { width: 200, height: 200, filter: 'saturate(100) grayscale(100%)', }, }); ``` or directly in the `style` prop ```tsx import React from 'react'; import {StyleSheet, View} from 'react-native'; import {FilterImage} from 'react-native-svg/filter-image'; export default () => { return ( <FilterImage style={{ width: 200, height: 200, filter: 'saturate(100) grayscale(100%)', }} source={{ uri: 'https://cdn.pixabay.com/photo/2024/05/26/00/40/lizard-8787888_1280.jpg', }} /> ); }; ``` ## Compatibility | OS | Implemented | | ------- | :---------: | | iOS | ✅ | | Android | ✅ | ## Checklist - [x] I have tested this on a device and a simulator - [x] I added documentation in `README.md` - [x] I updated the typed files (typescript)
This commit is contained in:
@@ -14,14 +14,14 @@ const img = require('../../assets/office.jpg');
|
||||
const normal: Filters = [];
|
||||
const losAngeles: Filters = [
|
||||
{
|
||||
name: 'colorMatrix',
|
||||
name: 'feColorMatrix',
|
||||
type: 'matrix',
|
||||
values: [1.8, 0, 0, 0, 0, 0, 1.3, 0, 0, 0, 0, 0, 1.2, 0, 0, 0, 0, 0, 1, 0],
|
||||
},
|
||||
];
|
||||
const lagos: Filters = [
|
||||
{
|
||||
name: 'colorMatrix',
|
||||
name: 'feColorMatrix',
|
||||
type: 'matrix',
|
||||
values: [
|
||||
1.4, 0, 0, 0, 0, 0, 1.2, 0, 0, 0, 0, 0, 1.5, 0, 0, 0, 0, 0, 0.9, 0,
|
||||
@@ -29,11 +29,10 @@ const lagos: Filters = [
|
||||
},
|
||||
];
|
||||
const tokyo: Filters = [
|
||||
{name: 'colorMatrix', type: 'saturate', values: [1.5]},
|
||||
{name: 'feColorMatrix', type: 'saturate', values: [1.5]},
|
||||
{
|
||||
name: 'colorMatrix',
|
||||
name: 'feColorMatrix',
|
||||
type: 'matrix',
|
||||
|
||||
values: [
|
||||
0.2, 0.2, 0.2, 0, 0, 0.2, 0.2, 0.2, 0, 0, 0.2, 0.2, 0.2, 0, 0, 0, 0, 0, 1,
|
||||
0,
|
||||
@@ -41,11 +40,11 @@ const tokyo: Filters = [
|
||||
},
|
||||
];
|
||||
const saturated: Filters = [
|
||||
{name: 'colorMatrix', type: 'saturate', values: [1.5]},
|
||||
{name: 'feColorMatrix', type: 'saturate', values: [1.5]},
|
||||
];
|
||||
const boring: Filters = [
|
||||
{
|
||||
name: 'colorMatrix',
|
||||
name: 'feColorMatrix',
|
||||
type: 'matrix',
|
||||
values: [
|
||||
0.6965, 0.3845, 0.0945, 0, 0, 0.1745, 0.8430000000000001, 0.084, 0, 0,
|
||||
@@ -131,10 +130,10 @@ const styles = StyleSheet.create({
|
||||
|
||||
const icon = (
|
||||
<FilterImage
|
||||
filters={[{name: 'colorMatrix', type: 'saturate', values: [0.5]}]}
|
||||
source={img}
|
||||
width={30}
|
||||
height={30}
|
||||
style={{filter: 'saturate(2.5)'}}
|
||||
/>
|
||||
);
|
||||
|
||||
|
||||
@@ -4,26 +4,53 @@ import {FilterImage} from 'react-native-svg/filter-image';
|
||||
|
||||
const testImage = require('../../assets/image.jpg');
|
||||
|
||||
const FilterImageLocalExample = () => {
|
||||
const FilterImageLocalExampleStyleCSS = () => {
|
||||
return (
|
||||
<View>
|
||||
<FilterImage source={testImage} style={{filter: 'saturate(0.5)'}} />
|
||||
</View>
|
||||
);
|
||||
};
|
||||
FilterImageLocalExampleStyleCSS.title = 'With style filter CSS';
|
||||
|
||||
const FilterImageLocalExampleStyleSVG = () => {
|
||||
return (
|
||||
<View>
|
||||
<FilterImage
|
||||
filters={[{name: 'colorMatrix', type: 'saturate', values: [0.5]}]}
|
||||
source={testImage}
|
||||
style={{
|
||||
filter: [{name: 'feColorMatrix', type: 'saturate', values: 0.5}],
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
FilterImageLocalExample.title = 'Local image with filter';
|
||||
FilterImageLocalExampleStyleSVG.title = 'With style filter SVG';
|
||||
|
||||
const FilterImageLocalExamplePropSVG = () => {
|
||||
return (
|
||||
<View>
|
||||
<FilterImage
|
||||
source={testImage}
|
||||
filters={[{name: 'feColorMatrix', type: 'saturate', values: 0.5}]}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
FilterImageLocalExamplePropSVG.title = 'With prop filters SVG';
|
||||
|
||||
const icon = (
|
||||
<FilterImage
|
||||
filters={[{name: 'colorMatrix', type: 'saturate', values: [0.5]}]}
|
||||
source={testImage}
|
||||
width={30}
|
||||
height={30}
|
||||
style={{filter: 'saturate(0.5)'}}
|
||||
/>
|
||||
);
|
||||
|
||||
const samples = [FilterImageLocalExample];
|
||||
const samples = [
|
||||
FilterImageLocalExampleStyleCSS,
|
||||
FilterImageLocalExampleStyleSVG,
|
||||
FilterImageLocalExamplePropSVG,
|
||||
];
|
||||
export {icon, samples};
|
||||
|
||||
@@ -1,32 +1,44 @@
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import {StyleSheet, View} from 'react-native';
|
||||
import {FilterImage} from 'react-native-svg/filter-image';
|
||||
|
||||
const testSource = {
|
||||
uri: 'https://cdn.pixabay.com/photo/2023/03/17/11/39/mountain-7858482_1280.jpg',
|
||||
};
|
||||
|
||||
const FilterImageRemoteExample = () => {
|
||||
const FilterImageRemoteExampleCSS = () => {
|
||||
return (
|
||||
<View>
|
||||
<FilterImage
|
||||
filters={[{name: 'colorMatrix', type: 'saturate', values: [3]}]}
|
||||
source={testSource}
|
||||
style={{width: 200, height: 200}}
|
||||
style={[styles.image, {filter: 'saturate(3)'}]}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
FilterImageRemoteExample.title = 'Remote image with filter';
|
||||
FilterImageRemoteExampleCSS.title = 'Remote image with CSS filter';
|
||||
|
||||
const FilterImageRemoteExample = () => {
|
||||
return (
|
||||
<View>
|
||||
<FilterImage
|
||||
source={testSource}
|
||||
style={styles.image}
|
||||
filters={[{name: 'feColorMatrix', type: 'saturate', values: [3]}]}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
FilterImageRemoteExample.title = 'Remote image with prop filters';
|
||||
|
||||
const FilterImageFewFiltersExample = () => {
|
||||
return (
|
||||
<View>
|
||||
<FilterImage
|
||||
filters={[
|
||||
{name: 'colorMatrix', type: 'saturate', values: [10]},
|
||||
{name: 'feColorMatrix', type: 'saturate', values: [10]},
|
||||
{
|
||||
name: 'colorMatrix',
|
||||
name: 'feColorMatrix',
|
||||
type: 'matrix',
|
||||
values: '0.2 0.2 0.2 0 0 0.2 0.2 0.2 0 0 0.2 0.2 0.2 0 0 0 0 0 1 0',
|
||||
},
|
||||
@@ -41,12 +53,23 @@ FilterImageFewFiltersExample.title = 'Remote image with filters';
|
||||
|
||||
const icon = (
|
||||
<FilterImage
|
||||
filters={[{name: 'colorMatrix', type: 'saturate', values: [0.5]}]}
|
||||
source={testSource}
|
||||
width={30}
|
||||
height={30}
|
||||
style={{filter: 'saturate(0.5)'}}
|
||||
/>
|
||||
);
|
||||
|
||||
const samples = [FilterImageRemoteExample, FilterImageFewFiltersExample];
|
||||
const styles = StyleSheet.create({
|
||||
image: {
|
||||
width: 200,
|
||||
height: 200,
|
||||
},
|
||||
});
|
||||
|
||||
const samples = [
|
||||
FilterImageRemoteExampleCSS,
|
||||
FilterImageRemoteExample,
|
||||
FilterImageFewFiltersExample,
|
||||
];
|
||||
export {icon, samples};
|
||||
|
||||
@@ -53,10 +53,10 @@ const styles = StyleSheet.create({
|
||||
|
||||
const icon = (
|
||||
<FilterImage
|
||||
filters={[{name: 'colorMatrix', type: 'saturate', values: [0.5]}]}
|
||||
source={require('../../assets/image.jpg')}
|
||||
width={30}
|
||||
height={30}
|
||||
style={{filter: 'saturate(3.5)'}}
|
||||
/>
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user