mirror of
https://github.com/zoriya/react-native-svg.git
synced 2025-12-05 22:56:11 +00:00
# Summary Introducing the long-awaited **Filters** in `react-native-svg` 🎉 ### Motivation This PR is the beginning of bringing support of SVG Filters into `react-native-svg`. * **related issues**: This PR series will address the following issues: #150, #176, #635, #883, #994, #996, #1216 * **feature overview**: This PR is a boilerplate for Filters * introducing `Filter` component and `FeColorMatrix` as a start. * It also introduces a new subdirectory called `react-native-svg/filter-image` with a `FilterImage` component. # Usage ## Filter and Fe... Filters are compatible with the web familiar standard, so most things should be compatible out-of-the-box and changes will be limited to using a capital letter as it's component. ### Example ```tsx import React from 'react'; import { FeColorMatrix, Filter, Rect, Svg } from 'react-native-svg'; export default () => { return ( <Svg height="300" width="300"> <Filter id="myFilter"> <FeColorMatrix type="saturate" values="0.2" /> </Filter> <Rect x="0" y="0" width="300" height="300" fill="red" filter="url(#myFilter)" /> </Svg> ); }; ```  ## Filter Image `FilterImage` is a new component that is not strictly related to SVG. Its behavior should be the same as a regular `Image` component from React Native with one exception - the additional prop `filters`, which accepts an array of filters to apply to the image. ### Example ```tsx import React from 'react'; import { StyleSheet } from 'react-native'; import { FilterImage } from 'react-native-svg/filter-image'; const myImage = require('./myImage.jpg'); export default () => { return ( <FilterImage style={styles.image} source={myImage} filters={[ { name: 'colorMatrix', type: 'saturate', values: 0.2 }, { name: 'colorMatrix', 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, ], }, ]} /> ); }; const styles = StyleSheet.create({ image: { width: 200, height: 200, }, }); ```  ## Test Plan **Example App**: Updated the example app with various filter effects, showcasing real-world usage. ## Compatibility | OS | Implemented | | ------- | :---------: | | iOS | ✅ | | Android | ✅ | ## Checklist - [x] I have tested this on a device and a simulator - [x] I added documentation in `README.md` and `USAGE.md` - [x] I updated the typed files (typescript)
154 lines
4.3 KiB
Objective-C
154 lines
4.3 KiB
Objective-C
/**
|
||
* Copyright (c) 2015-present, Horcrux.
|
||
* All rights reserved.
|
||
*
|
||
* This source code is licensed under the MIT-style license found in the
|
||
* LICENSE file in the root directory of this source tree.
|
||
*/
|
||
|
||
#import "RNSVGCGFCRule.h"
|
||
#import "RNSVGSvgView.h"
|
||
|
||
#import <React/RCTPointerEvents.h>
|
||
#import <React/UIView+React.h>
|
||
|
||
#ifdef RCT_NEW_ARCH_ENABLED
|
||
#import <React/RCTViewComponentView.h>
|
||
#endif // RCT_NEW_ARCH_ENABLED
|
||
|
||
@class RNSVGGroup;
|
||
|
||
/**
|
||
* RNSVG nodes are implemented as base NSViews/UIViews. They should be implementation for all basic
|
||
*interfaces for all non-definition nodes.
|
||
*/
|
||
|
||
@interface RNSVGNode :
|
||
#ifdef RCT_NEW_ARCH_ENABLED
|
||
RCTViewComponentView
|
||
#else
|
||
RNSVGView
|
||
#endif // RCT_NEW_ARCH_ENABLED
|
||
/*
|
||
N[1/Sqrt[2], 36]
|
||
The inverse of the square root of 2.
|
||
Provide enough digits for the 128-bit IEEE quad (36 significant digits).
|
||
*/
|
||
extern CGFloat const RNSVG_M_SQRT1_2l;
|
||
extern CGFloat const RNSVG_DEFAULT_FONT_SIZE;
|
||
|
||
@property (nonatomic, strong) NSString *name;
|
||
@property (nonatomic, strong) NSString *display;
|
||
@property (nonatomic, assign) CGFloat opacity;
|
||
@property (nonatomic, assign) RNSVGCGFCRule clipRule;
|
||
@property (nonatomic, strong) NSString *clipPath;
|
||
@property (nonatomic, strong) NSString *mask;
|
||
@property (nonatomic, strong) NSString *markerStart;
|
||
@property (nonatomic, strong) NSString *markerMid;
|
||
@property (nonatomic, strong) NSString *markerEnd;
|
||
@property (nonatomic, strong) RNSVGPlatformView *parentComponentView;
|
||
|
||
/**
|
||
* Used to control how touch events are processed.
|
||
*/
|
||
@property (nonatomic, assign) RCTPointerEvents pointerEvents;
|
||
@property (nonatomic, assign) BOOL responsible;
|
||
|
||
@property (nonatomic, assign) CGAffineTransform ctm;
|
||
@property (nonatomic, assign) CGAffineTransform screenCTM;
|
||
@property (nonatomic, assign) CGAffineTransform matrix;
|
||
@property (nonatomic, assign) CGAffineTransform transforms;
|
||
@property (nonatomic, assign) CGAffineTransform invmatrix;
|
||
@property (nonatomic, assign) CGAffineTransform invTransform;
|
||
@property (nonatomic, assign) BOOL active;
|
||
@property (nonatomic, assign) BOOL dirty;
|
||
@property (nonatomic, assign) BOOL merging;
|
||
@property (nonatomic, assign) BOOL skip;
|
||
@property (nonatomic, assign) CGPathRef path;
|
||
@property (nonatomic, assign) CGPathRef strokePath;
|
||
@property (nonatomic, assign) CGPathRef markerPath;
|
||
@property (nonatomic, assign) CGRect clientRect;
|
||
@property (nonatomic, assign) CGRect pathBounds;
|
||
@property (nonatomic, assign) CGRect fillBounds;
|
||
@property (nonatomic, assign) CGRect strokeBounds;
|
||
@property (nonatomic, assign) CGRect markerBounds;
|
||
@property (nonatomic, copy) RCTDirectEventBlock onLayout;
|
||
|
||
/**
|
||
* RNSVGSvgView which ownes current RNSVGNode
|
||
*/
|
||
@property (nonatomic, readonly, weak) RNSVGSvgView *svgView;
|
||
@property (nonatomic, readonly, weak) RNSVGGroup *textRoot;
|
||
|
||
- (void)invalidate;
|
||
|
||
- (RNSVGGroup *)getParentTextRoot;
|
||
|
||
- (void)renderTo:(CGContextRef)context rect:(CGRect)rect;
|
||
|
||
/**
|
||
* @abstract
|
||
* renderTo will take opacity into account and draw renderLayerTo off-screen if there is opacity
|
||
* specified, then composite that onto the context. renderLayerTo always draws at opacity=1.
|
||
*/
|
||
- (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect;
|
||
|
||
/**
|
||
* get clipPath from cache
|
||
*/
|
||
- (CGPathRef)getClipPath;
|
||
|
||
/**
|
||
* get clipPath through context
|
||
*/
|
||
- (CGPathRef)getClipPath:(CGContextRef)context;
|
||
|
||
/**
|
||
* clip node by clipPath
|
||
*/
|
||
- (void)clip:(CGContextRef)context;
|
||
|
||
/**
|
||
* getPath will return the path inside node as a ClipPath.
|
||
*/
|
||
- (CGPathRef)getPath:(CGContextRef)context;
|
||
|
||
- (CGFloat)relativeOnWidthString:(NSString *)length;
|
||
|
||
- (CGFloat)relativeOnHeightString:(NSString *)length;
|
||
|
||
- (CGFloat)relativeOnOtherString:(NSString *)length;
|
||
|
||
- (CGFloat)relativeOn:(RNSVGLength *)length relative:(CGFloat)relative;
|
||
|
||
- (CGFloat)relativeOnFraction:(RNSVGLength *)length relative:(CGFloat)relative;
|
||
|
||
- (CGFloat)relativeOnWidth:(RNSVGLength *)length;
|
||
|
||
- (CGFloat)relativeOnHeight:(RNSVGLength *)length;
|
||
|
||
- (CGFloat)relativeOnOther:(RNSVGLength *)length;
|
||
|
||
- (CGFloat)getFontSizeFromContext;
|
||
|
||
- (CGFloat)getContextWidth;
|
||
|
||
- (CGFloat)getContextHeight;
|
||
|
||
/**
|
||
* save element`s reference into svg element.
|
||
*/
|
||
- (void)parseReference;
|
||
|
||
- (void)beginTransparencyLayer:(CGContextRef)context;
|
||
|
||
- (void)endTransparencyLayer:(CGContextRef)context;
|
||
|
||
- (void)traverseSubviews:(BOOL (^)(__kindof RNSVGView *node))block;
|
||
|
||
- (void)clearChildCache;
|
||
|
||
- (void)clearPath;
|
||
|
||
@end
|