mirror of
https://github.com/zoriya/react-native-svg.git
synced 2025-12-05 22:56:11 +00:00
feat: add FeMerge and FeMergeNode filters (#2369)
# Summary As mentioned in #2362 Introduce new filters: * `FeMerge` * `FeMergeNode` ## Example usage ```tsx <Svg width="200" height="200"> <Filter id="mergeWithOffset" width="180" height="180"> <FeOffset dx="50" dy="50" result="test" /> <FeOffset dx="100" dy="100" in="SourceGraphic" /> <FeMerge> <FeMergeNode in="SourceGraphic" /> <FeMergeNode in="test" /> <FeMergeNode /> </FeMerge> </Filter> <Rect x="0" y="0" width="100" height="100" stroke="black" fill="red" filter="url(#mergeWithOffset)" /> </Svg> ``` <img width="207" alt="image" src="https://github.com/user-attachments/assets/9cb3ded6-f939-4b2b-8ece-df54e64fe898"> ## Test Plan `Example` app -> `Filters` -> `FeMerge` ## 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:
43
android/src/main/java/com/horcrux/svg/FeMergeView.java
Normal file
43
android/src/main/java/com/horcrux/svg/FeMergeView.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package com.horcrux.svg;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableType;
|
||||
import java.util.HashMap;
|
||||
|
||||
@SuppressLint("ViewConstructor")
|
||||
class FeMergeView extends FilterPrimitiveView {
|
||||
private ReadableArray mNodes;
|
||||
|
||||
public FeMergeView(ReactContext reactContext) {
|
||||
super(reactContext);
|
||||
}
|
||||
|
||||
public void setNodes(ReadableArray nodes) {
|
||||
this.mNodes = nodes;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bitmap applyFilter(HashMap<String, Bitmap> resultsMap, Bitmap prevResult) {
|
||||
Bitmap result =
|
||||
Bitmap.createBitmap(prevResult.getWidth(), prevResult.getHeight(), Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(result);
|
||||
int nodesSize = this.mNodes.size();
|
||||
for (int i = 0; i < nodesSize; i++) {
|
||||
Bitmap sourceFromResults =
|
||||
this.mNodes.getType(i) == ReadableType.String
|
||||
? resultsMap.get(this.mNodes.getString(i))
|
||||
: prevResult;
|
||||
if (sourceFromResults != null) {
|
||||
canvas.drawBitmap(sourceFromResults, 0, 0, new Paint());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -107,6 +107,8 @@ import com.facebook.react.viewmanagers.RNSVGFeColorMatrixManagerDelegate;
|
||||
import com.facebook.react.viewmanagers.RNSVGFeColorMatrixManagerInterface;
|
||||
import com.facebook.react.viewmanagers.RNSVGFeGaussianBlurManagerDelegate;
|
||||
import com.facebook.react.viewmanagers.RNSVGFeGaussianBlurManagerInterface;
|
||||
import com.facebook.react.viewmanagers.RNSVGFeMergeManagerDelegate;
|
||||
import com.facebook.react.viewmanagers.RNSVGFeMergeManagerInterface;
|
||||
import com.facebook.react.viewmanagers.RNSVGFeOffsetManagerDelegate;
|
||||
import com.facebook.react.viewmanagers.RNSVGFeOffsetManagerInterface;
|
||||
import com.facebook.react.viewmanagers.RNSVGFilterManagerDelegate;
|
||||
@@ -589,6 +591,7 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
|
||||
RNSVGFilter,
|
||||
RNSVGFeColorMatrix,
|
||||
RNSVGFeGaussianBlur,
|
||||
RNSVGFeMerge,
|
||||
RNSVGFeOffset,
|
||||
RNSVGMarker,
|
||||
RNSVGForeignObject,
|
||||
@@ -640,6 +643,8 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
|
||||
return new FeColorMatrixView(reactContext);
|
||||
case RNSVGFeGaussianBlur:
|
||||
return new FeGaussianBlurView(reactContext);
|
||||
case RNSVGFeMerge:
|
||||
return new FeMergeView(reactContext);
|
||||
case RNSVGFeOffset:
|
||||
return new FeOffsetView(reactContext);
|
||||
case RNSVGMarker:
|
||||
@@ -1630,6 +1635,21 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
|
||||
}
|
||||
}
|
||||
|
||||
static class FeMergeManager extends FilterPrimitiveManager<FeMergeView>
|
||||
implements RNSVGFeMergeManagerInterface<FeMergeView> {
|
||||
FeMergeManager() {
|
||||
super(SVGClass.RNSVGFeMerge);
|
||||
mDelegate = new RNSVGFeMergeManagerDelegate(this);
|
||||
}
|
||||
|
||||
public static final String REACT_CLASS = "RNSVGFeMerge";
|
||||
|
||||
@ReactProp(name = "nodes")
|
||||
public void setNodes(FeMergeView node, ReadableArray nodes) {
|
||||
node.setNodes(nodes);
|
||||
}
|
||||
}
|
||||
|
||||
static class FeOffsetManager extends FilterPrimitiveManager<FeOffsetView>
|
||||
implements RNSVGFeOffsetManagerInterface<FeOffsetView> {
|
||||
FeOffsetManager() {
|
||||
|
||||
@@ -232,6 +232,15 @@ public class SvgPackage extends TurboReactPackage implements ViewManagerOnDemand
|
||||
return new FeGaussianBlurManager();
|
||||
}
|
||||
}));
|
||||
specs.put(
|
||||
FeMergeManager.REACT_CLASS,
|
||||
ModuleSpec.viewManagerSpec(
|
||||
new Provider<NativeModule>() {
|
||||
@Override
|
||||
public NativeModule get() {
|
||||
return new FeMergeManager();
|
||||
}
|
||||
}));
|
||||
specs.put(
|
||||
FeOffsetManager.REACT_CLASS,
|
||||
ModuleSpec.viewManagerSpec(
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
* @generated by codegen project: GeneratePropsJavaDelegate.js
|
||||
*/
|
||||
|
||||
package com.facebook.react.viewmanagers;
|
||||
|
||||
import android.view.View;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.react.bridge.DynamicFromObject;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.uimanager.BaseViewManagerDelegate;
|
||||
import com.facebook.react.uimanager.BaseViewManagerInterface;
|
||||
|
||||
public class RNSVGFeMergeManagerDelegate<T extends View, U extends BaseViewManagerInterface<T> & RNSVGFeMergeManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
|
||||
public RNSVGFeMergeManagerDelegate(U viewManager) {
|
||||
super(viewManager);
|
||||
}
|
||||
@Override
|
||||
public void setProperty(T view, String propName, @Nullable Object value) {
|
||||
switch (propName) {
|
||||
case "x":
|
||||
mViewManager.setX(view, new DynamicFromObject(value));
|
||||
break;
|
||||
case "y":
|
||||
mViewManager.setY(view, new DynamicFromObject(value));
|
||||
break;
|
||||
case "width":
|
||||
mViewManager.setWidth(view, new DynamicFromObject(value));
|
||||
break;
|
||||
case "height":
|
||||
mViewManager.setHeight(view, new DynamicFromObject(value));
|
||||
break;
|
||||
case "result":
|
||||
mViewManager.setResult(view, value == null ? null : (String) value);
|
||||
break;
|
||||
case "nodes":
|
||||
mViewManager.setNodes(view, (ReadableArray) value);
|
||||
break;
|
||||
default:
|
||||
super.setProperty(view, propName, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
* @generated by codegen project: GeneratePropsJavaInterface.js
|
||||
*/
|
||||
|
||||
package com.facebook.react.viewmanagers;
|
||||
|
||||
import android.view.View;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.react.bridge.Dynamic;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
|
||||
public interface RNSVGFeMergeManagerInterface<T extends View> {
|
||||
void setX(T view, Dynamic value);
|
||||
void setY(T view, Dynamic value);
|
||||
void setWidth(T view, Dynamic value);
|
||||
void setHeight(T view, Dynamic value);
|
||||
void setResult(T view, @Nullable String value);
|
||||
void setNodes(T view, @Nullable ReadableArray value);
|
||||
}
|
||||
Reference in New Issue
Block a user