mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-01 14:15:03 +00:00
fix: applying multiple filters on iOS (#2366)
# Summary
Applying multiple `FeColorFilter` instances can cause unexpected
behavior on iOS, likely due to a bug in `CoreImage` where the `CIImage`
recipe isn't applied step by step as it should be. This fix ensures that
the filter result is rendered after each application by converting the
image to `CGImage` and then back to `CIImage`.
## Test Plan
With this simple test, we can prove that these changes are working
```tsx
<Svg height="200" width="200">
<Filter id="filter">
<FeColorMatrix type="matrix" values="78 -70 -7 0 0 -21 29 -7 0 0 -21 -70 0 0 0 0 0 0 1 0"/>
<FeColorMatrix type="matrix" values="0.2126, 0.7152, 0.0722, 0, 0, 0.2126, 0.7152, 0.0722, 0, 0, 0.2126, 0.7152, 0, 0, 0, 0, 0, 0, 1, 0"/>
</Filter>
<Rect width="200" height="200" fill="red" filter="url(#filter)"/>
</Svg>
```
| Web | iOS before changes | iOS after changes |
| --- | --- | --- |
| <img width="242" alt="image"
src="https://github.com/user-attachments/assets/dc683341-b3ca-4fab-86d8-cf72b15c13d4">
| <img width="237" alt="image"
src="https://github.com/user-attachments/assets/d4a1af5d-ae67-4ed9-9dbd-d03540b2c63c">
| <img width="249" alt="image"
src="https://github.com/user-attachments/assets/83e856a6-5bcc-4534-ad7b-a1f188434e1c">
|
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#import "RNSVGFilter.h"
|
||||
#import "RNSVGFilterPrimitive.h"
|
||||
#import "RNSVGRenderUtils.h"
|
||||
|
||||
#ifdef RCT_NEW_ARCH_ENABLED
|
||||
#import <React/RCTConversions.h>
|
||||
@@ -97,7 +98,11 @@ using namespace facebook::react;
|
||||
for (RNSVGNode *node in self.subviews) {
|
||||
if ([node isKindOfClass:[RNSVGFilterPrimitive class]]) {
|
||||
currentFilter = (RNSVGFilterPrimitive *)node;
|
||||
result = [currentFilter applyFilter:resultsMap previousFilterResult:result];
|
||||
CGImageRef cgResult = [[RNSVGRenderUtils sharedCIContext] createCGImage:[currentFilter applyFilter:resultsMap
|
||||
previousFilterResult:result]
|
||||
fromRect:[result extent]];
|
||||
result = [CIImage imageWithCGImage:cgResult];
|
||||
CGImageRelease(cgResult);
|
||||
if (currentFilter.result) {
|
||||
[resultsMap setObject:result forKey:currentFilter.result];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user