From 3879c90bd8273ba8b38713b2f39d2bdfd5265665 Mon Sep 17 00:00:00 2001 From: Mikael Sand Date: Fri, 17 Aug 2018 22:09:47 +0300 Subject: [PATCH] Support native animation of fill and stroke --- .../com/horcrux/svg/RenderableShadowNode.java | 39 +- .../java/com/horcrux/svg/RenderableView.java | 8 +- .../horcrux/svg/RenderableViewManager.java | 397 +++++++++--------- ios/Utils/RCTConvert+RNSVG.m | 20 + 4 files changed, 258 insertions(+), 206 deletions(-) diff --git a/android/src/main/java/com/horcrux/svg/RenderableShadowNode.java b/android/src/main/java/com/horcrux/svg/RenderableShadowNode.java index dc2a4890e..03e5ba50d 100644 --- a/android/src/main/java/com/horcrux/svg/RenderableShadowNode.java +++ b/android/src/main/java/com/horcrux/svg/RenderableShadowNode.java @@ -17,8 +17,12 @@ import android.graphics.Region; import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.Dynamic; import com.facebook.react.bridge.JSApplicationIllegalArgumentException; +import com.facebook.react.bridge.JavaOnlyArray; import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.ReadableType; import com.facebook.react.bridge.WritableArray; import com.facebook.react.uimanager.annotations.ReactProp; @@ -70,9 +74,24 @@ abstract public class RenderableShadowNode extends VirtualNode { protected @Nullable ReadableArray mPropList; protected @Nullable WritableArray mAttributeList; + static final Pattern regex = Pattern.compile("[0-9.-]+"); + @ReactProp(name = "fill") - public void setFill(@Nullable ReadableArray fill) { - mFill = fill; + public void setFill(@Nullable Dynamic fill) { + ReadableType type = fill.getType(); + if (type.equals(ReadableType.Array)) { + mFill = fill.asArray(); + } else { + JavaOnlyArray arr = new JavaOnlyArray(); + arr.pushInt(0); + Matcher m = regex.matcher(fill.asString()); + int i = 0; + while (m.find()) { + Double parsed = Double.parseDouble(m.group()); + arr.pushDouble(i++ < 3 ? parsed / 255 : parsed); + } + mFill = arr; + } markUpdated(); } @@ -99,8 +118,20 @@ public void setFillRule(int fillRule) { } @ReactProp(name = "stroke") - public void setStroke(@Nullable ReadableArray strokeColors) { - mStroke = strokeColors; + public void setStroke(@Nullable Dynamic strokeColors) { + ReadableType type = strokeColors.getType(); + if (type.equals(ReadableType.Array)) { + mStroke = strokeColors.asArray(); + } else { + JavaOnlyArray arr = new JavaOnlyArray(); + arr.pushInt(0); + Matcher m = regex.matcher(strokeColors.asString()); + while (m.find()) { + Double parsed = Double.parseDouble(m.group()); + arr.pushDouble(parsed); + } + mStroke = arr; + } markUpdated(); } diff --git a/android/src/main/java/com/horcrux/svg/RenderableView.java b/android/src/main/java/com/horcrux/svg/RenderableView.java index 517b51327..a50eba2e2 100644 --- a/android/src/main/java/com/horcrux/svg/RenderableView.java +++ b/android/src/main/java/com/horcrux/svg/RenderableView.java @@ -4,21 +4,21 @@ import com.facebook.react.bridge.ReactContext; -public class RenderableView extends ViewGroup { - VirtualNode shadowNode; +public class RenderableView extends ViewGroup { + public T shadowNode; public RenderableView(ReactContext reactContext) { super(reactContext); } - VirtualNode getShadowNode() { + T getShadowNode() { return shadowNode; } @Override public void setId(int id) { super.setId(id); - shadowNode = RenderableViewManager.getShadowNodeByTag(id); + shadowNode = (T) RenderableViewManager.getShadowNodeByTag(id); } void dropView() { diff --git a/android/src/main/java/com/horcrux/svg/RenderableViewManager.java b/android/src/main/java/com/horcrux/svg/RenderableViewManager.java index ca4d53631..804912f3a 100644 --- a/android/src/main/java/com/horcrux/svg/RenderableViewManager.java +++ b/android/src/main/java/com/horcrux/svg/RenderableViewManager.java @@ -12,6 +12,7 @@ import android.graphics.Bitmap; import android.util.SparseArray; +import com.facebook.react.bridge.Dynamic; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.uimanager.LayoutShadowNode; @@ -30,7 +31,7 @@ * into native views and don't need any logic (all the logic is in {@link SvgView}), this * "stubbed" ViewManager is used for all of them. */ -class RenderableViewManager extends ViewGroupManager { +class RenderableViewManager extends ViewGroupManager> { /* package */ private static final String CLASS_GROUP = "RNSVGGroup"; /* package */ private static final String CLASS_PATH = "RNSVGPath"; @@ -52,275 +53,275 @@ class RenderableViewManager extends ViewGroupManager { private final String mClassName; - static RenderableViewManager createGroupViewManager() { - return new RenderableViewManager(CLASS_GROUP); + static RenderableViewManager createGroupViewManager() { + return new RenderableViewManager<>(CLASS_GROUP); } - static RenderableViewManager createPathViewManager() { - return new RenderableViewManager(CLASS_PATH) { + static RenderableViewManager createPathViewManager() { + return new RenderableViewManager(CLASS_PATH) { @ReactProp(name = "d") - public void setD(RenderableView node, String d) { - ((PathShadowNode) node.getShadowNode()).setD(d); + public void setD(RenderableView node, String d) { + node.shadowNode.setD(d); } }; } - static RenderableViewManager createTextViewManager() { - return new RenderableViewManager(CLASS_TEXT) { + static RenderableViewManager createTextViewManager() { + return new RenderableViewManager(CLASS_TEXT) { @ReactProp(name = "textLength") - public void setTextLength(RenderableView node, @Nullable String length) { - ((TextShadowNode) node.getShadowNode()).setTextLength(length); + public void setTextLength(RenderableView node, @Nullable String length) { + node.shadowNode.setTextLength(length); } @ReactProp(name = "lengthAdjust") - public void setLengthAdjust(RenderableView node, @Nullable String adjustment) { - ((TextShadowNode) node.getShadowNode()).setLengthAdjust(adjustment); + public void setLengthAdjust(RenderableView node, @Nullable String adjustment) { + node.shadowNode.setLengthAdjust(adjustment); } @ReactProp(name = "alignmentBaseline") - public void setMethod(RenderableView node, @Nullable String alignment) { - ((TextShadowNode) node.getShadowNode()).setMethod(alignment); + public void setMethod(RenderableView node, @Nullable String alignment) { + node.shadowNode.setMethod(alignment); } @ReactProp(name = "baselineShift") - public void setBaselineShift(RenderableView node, @Nullable String baselineShift) { - ((TextShadowNode) node.getShadowNode()).setBaselineShift(baselineShift); + public void setBaselineShift(RenderableView node, @Nullable String baselineShift) { + node.shadowNode.setBaselineShift(baselineShift); } @ReactProp(name = "verticalAlign") - public void setVerticalAlign(RenderableView node, @Nullable String verticalAlign) { - ((TextShadowNode) node.getShadowNode()).setVerticalAlign(verticalAlign); + public void setVerticalAlign(RenderableView node, @Nullable String verticalAlign) { + node.shadowNode.setVerticalAlign(verticalAlign); } @ReactProp(name = "rotate") - public void setRotate(RenderableView node, @Nullable ReadableArray rotate) { - ((TextShadowNode) node.getShadowNode()).setRotate(rotate); + public void setRotate(RenderableView node, @Nullable ReadableArray rotate) { + node.shadowNode.setRotate(rotate); } @ReactProp(name = "deltaX") - public void setDeltaX(RenderableView node, @Nullable ReadableArray deltaX) { - ((TextShadowNode) node.getShadowNode()).setDeltaX(deltaX); + public void setDeltaX(RenderableView node, @Nullable ReadableArray deltaX) { + node.shadowNode.setDeltaX(deltaX); } @ReactProp(name = "deltaY") - public void setDeltaY(RenderableView node, @Nullable ReadableArray deltaY) { - ((TextShadowNode) node.getShadowNode()).setDeltaY(deltaY); + public void setDeltaY(RenderableView node, @Nullable ReadableArray deltaY) { + node.shadowNode.setDeltaY(deltaY); } @ReactProp(name = "positionX") - public void setPositionX(RenderableView node, @Nullable ReadableArray positionX) { - ((TextShadowNode) node.getShadowNode()).setPositionX(positionX); + public void setPositionX(RenderableView node, @Nullable ReadableArray positionX) { + node.shadowNode.setPositionX(positionX); } @ReactProp(name = "positionY") - public void setPositionY(RenderableView node, @Nullable ReadableArray positionY) { - ((TextShadowNode) node.getShadowNode()).setPositionY(positionY); + public void setPositionY(RenderableView node, @Nullable ReadableArray positionY) { + node.shadowNode.setPositionY(positionY); } @ReactProp(name = "font") - public void setFont(RenderableView node, @Nullable ReadableMap font) { - ((TextShadowNode) node.getShadowNode()).setFont(font); + public void setFont(RenderableView node, @Nullable ReadableMap font) { + node.shadowNode.setFont(font); } }; } - static RenderableViewManager createTSpanViewManager() { - return new RenderableViewManager(CLASS_TSPAN) { + static RenderableViewManager createTSpanViewManager() { + return new RenderableViewManager(CLASS_TSPAN) { @ReactProp(name = "content") - public void setContent(RenderableView node, @Nullable String content) { - ((TSpanShadowNode) node.getShadowNode()).setContent(content); + public void setContent(RenderableView node, @Nullable String content) { + node.shadowNode.setContent(content); } }; } - static RenderableViewManager createTextPathViewManager() { - return new RenderableViewManager(CLASS_TEXT_PATH) { + static RenderableViewManager createTextPathViewManager() { + return new RenderableViewManager(CLASS_TEXT_PATH) { @ReactProp(name = "href") - public void setHref(RenderableView node, String href) { - ((TextPathShadowNode) node.getShadowNode()).setHref(href); + public void setHref(RenderableView node, String href) { + node.shadowNode.setHref(href); } @ReactProp(name = "startOffset") - public void setStartOffset(RenderableView node, @Nullable String startOffset) { - ((TextPathShadowNode) node.getShadowNode()).setStartOffset(startOffset); + public void setStartOffset(RenderableView node, @Nullable String startOffset) { + node.shadowNode.setStartOffset(startOffset); } @ReactProp(name = "method") - public void setMethod(RenderableView node, @Nullable String method) { - ((TextPathShadowNode) node.getShadowNode()).setMethod(method); + public void setMethod(RenderableView node, @Nullable String method) { + node.shadowNode.setMethod(method); } @ReactProp(name = "spacing") - public void setSpacing(RenderableView node, @Nullable String spacing) { - ((TextPathShadowNode) node.getShadowNode()).setSpacing(spacing); + public void setSpacing(RenderableView node, @Nullable String spacing) { + node.shadowNode.setSpacing(spacing); } @ReactProp(name = "side") - public void setSide(RenderableView node, @Nullable String side) { - ((TextPathShadowNode) node.getShadowNode()).setSide(side); + public void setSide(RenderableView node, @Nullable String side) { + node.shadowNode.setSide(side); } @ReactProp(name = "midLine") - public void setSharp(RenderableView node, @Nullable String midLine) { - ((TextPathShadowNode) node.getShadowNode()).setSharp(midLine); + public void setSharp(RenderableView node, @Nullable String midLine) { + node.shadowNode.setSharp(midLine); } }; } - static RenderableViewManager createImageViewManager() { - return new RenderableViewManager(CLASS_IMAGE) { + static RenderableViewManager createImageViewManager() { + return new RenderableViewManager(CLASS_IMAGE) { @ReactProp(name = "x") - public void setX(RenderableView node, String x) { - ((ImageShadowNode) node.getShadowNode()).setX(x); + public void setX(RenderableView node, String x) { + node.shadowNode.setX(x); } @ReactProp(name = "y") - public void setY(RenderableView node, String y) { - ((ImageShadowNode) node.getShadowNode()).setY(y); + public void setY(RenderableView node, String y) { + node.shadowNode.setY(y); } @ReactProp(name = "imagewidth") - public void setWidth(RenderableView node, String width) { - ((ImageShadowNode) node.getShadowNode()).setWidth(width); + public void setWidth(RenderableView node, String width) { + node.shadowNode.setWidth(width); } @ReactProp(name = "imageheight") - public void seHeight(RenderableView node, String height) { - ((ImageShadowNode) node.getShadowNode()).seHeight(height); + public void seHeight(RenderableView node, String height) { + node.shadowNode.seHeight(height); } @ReactProp(name = "src") - public void setSrc(RenderableView node, @Nullable ReadableMap src) { - ((ImageShadowNode) node.getShadowNode()).setSrc(src); + public void setSrc(RenderableView node, @Nullable ReadableMap src) { + node.shadowNode.setSrc(src); } @ReactProp(name = "align") - public void setAlign(RenderableView node, String align) { - ((ImageShadowNode) node.getShadowNode()).setAlign(align); + public void setAlign(RenderableView node, String align) { + node.shadowNode.setAlign(align); } @ReactProp(name = "meetOrSlice") - public void setMeetOrSlice(RenderableView node, int meetOrSlice) { - ((ImageShadowNode) node.getShadowNode()).setMeetOrSlice(meetOrSlice); + public void setMeetOrSlice(RenderableView node, int meetOrSlice) { + node.shadowNode.setMeetOrSlice(meetOrSlice); } @ReactProp(name = "matrix") - public void setMatrix(RenderableView node, @Nullable ReadableArray matrixArray) { - ((ImageShadowNode) node.getShadowNode()).setMatrix(matrixArray); + public void setMatrix(RenderableView node, @Nullable ReadableArray matrixArray) { + node.shadowNode.setMatrix(matrixArray); } }; } - static RenderableViewManager createCircleViewManager() { - return new RenderableViewManager(CLASS_CIRCLE) { + static RenderableViewManager createCircleViewManager() { + return new RenderableViewManager(CLASS_CIRCLE) { @ReactProp(name = "cx") - public void setCx(RenderableView node, String cx) { - ((CircleShadowNode) node.getShadowNode()).setCx(cx); + public void setCx(RenderableView node, String cx) { + node.shadowNode.setCx(cx); } @ReactProp(name = "cy") - public void setCy(RenderableView node, String cy) { - ((CircleShadowNode) node.getShadowNode()).setCy(cy); + public void setCy(RenderableView node, String cy) { + node.shadowNode.setCy(cy); } @ReactProp(name = "r") - public void setR(RenderableView node, String r) { - ((CircleShadowNode) node.getShadowNode()).setR(r); + public void setR(RenderableView node, String r) { + node.shadowNode.setR(r); } }; } - static RenderableViewManager createEllipseViewManager() { - return new RenderableViewManager(CLASS_ELLIPSE) { + static RenderableViewManager createEllipseViewManager() { + return new RenderableViewManager(CLASS_ELLIPSE) { @ReactProp(name = "cx") - public void setCx(RenderableView node, String cx) { - ((EllipseShadowNode) node.getShadowNode()).setCx(cx); + public void setCx(RenderableView node, String cx) { + node.shadowNode.setCx(cx); } @ReactProp(name = "cy") - public void setCy(RenderableView node, String cy) { - ((EllipseShadowNode) node.getShadowNode()).setCy(cy); + public void setCy(RenderableView node, String cy) { + node.shadowNode.setCy(cy); } @ReactProp(name = "rx") - public void setRx(RenderableView node, String rx) { - ((EllipseShadowNode) node.getShadowNode()).setRx(rx); + public void setRx(RenderableView node, String rx) { + node.shadowNode.setRx(rx); } @ReactProp(name = "ry") - public void setRy(RenderableView node, String ry) { - ((EllipseShadowNode) node.getShadowNode()).setRy(ry); + public void setRy(RenderableView node, String ry) { + node.shadowNode.setRy(ry); } }; } - static RenderableViewManager createLineViewManager() { - return new RenderableViewManager(CLASS_LINE) { + static RenderableViewManager createLineViewManager() { + return new RenderableViewManager(CLASS_LINE) { @ReactProp(name = "x1") - public void setX1(RenderableView node, String x1) { - ((LineShadowNode) node.getShadowNode()).setX1(x1); + public void setX1(RenderableView node, String x1) { + node.shadowNode.setX1(x1); } @ReactProp(name = "y1") - public void setY1(RenderableView node, String y1) { - ((LineShadowNode) node.getShadowNode()).setY1(y1); + public void setY1(RenderableView node, String y1) { + node.shadowNode.setY1(y1); } @ReactProp(name = "x2") - public void setX2(RenderableView node, String x2) { - ((LineShadowNode) node.getShadowNode()).setX2(x2); + public void setX2(RenderableView node, String x2) { + node.shadowNode.setX2(x2); } @ReactProp(name = "y2") - public void setY2(RenderableView node, String y2) { - ((LineShadowNode) node.getShadowNode()).setY2(y2); + public void setY2(RenderableView node, String y2) { + node.shadowNode.setY2(y2); } }; } - static RenderableViewManager createRectViewManager() { - return new RenderableViewManager(CLASS_RECT) { + static RenderableViewManager createRectViewManager() { + return new RenderableViewManager(CLASS_RECT) { @ReactProp(name = "x") - public void setX(RenderableView node, String x) { - ((RectShadowNode) node.getShadowNode()).setX(x); + public void setX(RenderableView node, String x) { + node.shadowNode.setX(x); } @ReactProp(name = "y") - public void setY(RenderableView node, String y) { - ((RectShadowNode) node.getShadowNode()).setY(y); + public void setY(RenderableView node, String y) { + node.shadowNode.setY(y); } @ReactProp(name = "rectwidth") - public void setWidth(RenderableView node, String width) { - ((RectShadowNode) node.getShadowNode()).setWidth(width); + public void setWidth(RenderableView node, String width) { + node.shadowNode.setWidth(width); } @ReactProp(name = "rectheight") - public void setHeight(RenderableView node, String height) { - ((RectShadowNode) node.getShadowNode()).setHeight(height); + public void setHeight(RenderableView node, String height) { + node.shadowNode.setHeight(height); } @ReactProp(name = "rx") - public void setRx(RenderableView node, String rx) { - ((RectShadowNode) node.getShadowNode()).setRx(rx); + public void setRx(RenderableView node, String rx) { + node.shadowNode.setRx(rx); } @ReactProp(name = "ry") - public void setRy(RenderableView node, String ry) { - ((RectShadowNode) node.getShadowNode()).setRy(ry); + public void setRy(RenderableView node, String ry) { + node.shadowNode.setRy(ry); } }; } @@ -333,147 +334,147 @@ static RenderableViewManager createDefsViewManager() { return new RenderableViewManager(CLASS_DEFS); } - static RenderableViewManager createUseViewManager() { - return new RenderableViewManager(CLASS_USE) { + static RenderableViewManager createUseViewManager() { + return new RenderableViewManager(CLASS_USE) { @ReactProp(name = "href") - public void setHref(RenderableView node, String href) { - ((UseShadowNode) node.getShadowNode()).setHref(href); + public void setHref(RenderableView node, String href) { + node.shadowNode.setHref(href); } @ReactProp(name = "usewidth") - public void setWidth(RenderableView node, String width) { - ((UseShadowNode) node.getShadowNode()).setWidth(width); + public void setWidth(RenderableView node, String width) { + node.shadowNode.setWidth(width); } @ReactProp(name = "useheight") - public void setHeight(RenderableView node, String height) { - ((UseShadowNode) node.getShadowNode()).setHeight(height); + public void setHeight(RenderableView node, String height) { + node.shadowNode.setHeight(height); } }; } - static RenderableViewManager createSymbolManager() { - return new RenderableViewManager(CLASS_SYMBOL) { + static RenderableViewManager createSymbolManager() { + return new RenderableViewManager(CLASS_SYMBOL) { @ReactProp(name = "minX") - public void setMinX(RenderableView node, float minX) { - ((SymbolShadowNode) node.getShadowNode()).setMinX(minX); + public void setMinX(RenderableView node, float minX) { + node.shadowNode.setMinX(minX); } @ReactProp(name = "minY") - public void setMinY(RenderableView node, float minY) { - ((SymbolShadowNode) node.getShadowNode()).setMinY(minY); + public void setMinY(RenderableView node, float minY) { + node.shadowNode.setMinY(minY); } @ReactProp(name = "vbWidth") - public void setVbWidth(RenderableView node, float vbWidth) { - ((SymbolShadowNode) node.getShadowNode()).setVbWidth(vbWidth); + public void setVbWidth(RenderableView node, float vbWidth) { + node.shadowNode.setVbWidth(vbWidth); } @ReactProp(name = "vbHeight") - public void setVbHeight(RenderableView node, float vbHeight) { - ((SymbolShadowNode) node.getShadowNode()).setVbHeight(vbHeight); + public void setVbHeight(RenderableView node, float vbHeight) { + node.shadowNode.setVbHeight(vbHeight); } @ReactProp(name = "align") - public void setAlign(RenderableView node, String align) { - ((SymbolShadowNode) node.getShadowNode()).setAlign(align); + public void setAlign(RenderableView node, String align) { + node.shadowNode.setAlign(align); } @ReactProp(name = "meetOrSlice") - public void setMeetOrSlice(RenderableView node, int meetOrSlice) { - ((SymbolShadowNode) node.getShadowNode()).setMeetOrSlice(meetOrSlice); + public void setMeetOrSlice(RenderableView node, int meetOrSlice) { + node.shadowNode.setMeetOrSlice(meetOrSlice); } }; } - static RenderableViewManager createLinearGradientManager() { - return new RenderableViewManager(CLASS_LINEAR_GRADIENT) { + static RenderableViewManager createLinearGradientManager() { + return new RenderableViewManager(CLASS_LINEAR_GRADIENT) { @ReactProp(name = "x1") - public void setX1(RenderableView node, String x1) { - ((LinearGradientShadowNode) node.getShadowNode()).setX1(x1); + public void setX1(RenderableView node, String x1) { + node.shadowNode.setX1(x1); } @ReactProp(name = "y1") - public void setY1(RenderableView node, String y1) { - ((LinearGradientShadowNode) node.getShadowNode()).setY1(y1); + public void setY1(RenderableView node, String y1) { + node.shadowNode.setY1(y1); } @ReactProp(name = "x2") - public void setX2(RenderableView node, String x2) { - ((LinearGradientShadowNode) node.getShadowNode()).setX2(x2); + public void setX2(RenderableView node, String x2) { + node.shadowNode.setX2(x2); } @ReactProp(name = "y2") - public void setY2(RenderableView node, String y2) { - ((LinearGradientShadowNode) node.getShadowNode()).setY2(y2); + public void setY2(RenderableView node, String y2) { + node.shadowNode.setY2(y2); } @ReactProp(name = "gradient") - public void setGradient(RenderableView node, ReadableArray gradient) { - ((LinearGradientShadowNode) node.getShadowNode()).setGradient(gradient); + public void setGradient(RenderableView node, ReadableArray gradient) { + node.shadowNode.setGradient(gradient); } @ReactProp(name = "gradientUnits") - public void setGradientUnits(RenderableView node, int gradientUnits) { - ((LinearGradientShadowNode) node.getShadowNode()).setGradientUnits(gradientUnits); + public void setGradientUnits(RenderableView node, int gradientUnits) { + node.shadowNode.setGradientUnits(gradientUnits); } @ReactProp(name = "gradientTransform") - public void setGradientTransform(RenderableView node, @Nullable ReadableArray matrixArray) { - ((LinearGradientShadowNode) node.getShadowNode()).setGradientTransform(matrixArray); + public void setGradientTransform(RenderableView node, @Nullable ReadableArray matrixArray) { + node.shadowNode.setGradientTransform(matrixArray); } }; } - static RenderableViewManager createRadialGradientManager() { - return new RenderableViewManager(CLASS_RADIAL_GRADIENT) { + static RenderableViewManager createRadialGradientManager() { + return new RenderableViewManager(CLASS_RADIAL_GRADIENT) { @ReactProp(name = "fx") - public void setFx(RenderableView node, String fx) { - ((RadialGradientShadowNode) node.getShadowNode()).setFx(fx); + public void setFx(RenderableView node, String fx) { + node.shadowNode.setFx(fx); } @ReactProp(name = "fy") - public void setFy(RenderableView node, String fy) { - ((RadialGradientShadowNode) node.getShadowNode()).setFy(fy); + public void setFy(RenderableView node, String fy) { + node.shadowNode.setFy(fy); } @ReactProp(name = "rx") - public void setRx(RenderableView node, String rx) { - ((RadialGradientShadowNode) node.getShadowNode()).setRx(rx); + public void setRx(RenderableView node, String rx) { + node.shadowNode.setRx(rx); } @ReactProp(name = "ry") - public void setRy(RenderableView node, String ry) { - ((RadialGradientShadowNode) node.getShadowNode()).setRy(ry); + public void setRy(RenderableView node, String ry) { + node.shadowNode.setRy(ry); } @ReactProp(name = "cx") - public void setCx(RenderableView node, String cx) { - ((RadialGradientShadowNode) node.getShadowNode()).setCx(cx); + public void setCx(RenderableView node, String cx) { + node.shadowNode.setCx(cx); } @ReactProp(name = "cy") - public void setCy(RenderableView node, String cy) { - ((RadialGradientShadowNode) node.getShadowNode()).setCy(cy); + public void setCy(RenderableView node, String cy) { + node.shadowNode.setCy(cy); } @ReactProp(name = "gradient") - public void setGradient(RenderableView node, ReadableArray gradient) { - ((RadialGradientShadowNode) node.getShadowNode()).setGradient(gradient); + public void setGradient(RenderableView node, ReadableArray gradient) { + node.shadowNode.setGradient(gradient); } @ReactProp(name = "gradientUnits") - public void setGradientUnits(RenderableView node, int gradientUnits) { - ((RadialGradientShadowNode) node.getShadowNode()).setGradientUnits(gradientUnits); + public void setGradientUnits(RenderableView node, int gradientUnits) { + node.shadowNode.setGradientUnits(gradientUnits); } @ReactProp(name = "gradientTransform") - public void setGradientTransform(RenderableView node, @Nullable ReadableArray matrixArray) { - ((RadialGradientShadowNode) node.getShadowNode()).setGradientTransform(matrixArray); + public void setGradientTransform(RenderableView node, @Nullable ReadableArray matrixArray) { + node.shadowNode.setGradientTransform(matrixArray); } }; } @@ -528,7 +529,7 @@ public LayoutShadowNode createShadowNodeInstance() { } @Override - public Class getShadowNodeClass() { + public Class getShadowNodeClass() { switch (mClassName) { case CLASS_GROUP: return GroupShadowNode.class; @@ -568,64 +569,64 @@ public Class getShadowNodeClass() { } @ReactProp(name = "fill") - public void setFill(RenderableView node, @Nullable ReadableArray fill) { - ((RenderableShadowNode) node.getShadowNode()).setFill(fill); + public void setFill(RenderableView node, @Nullable Dynamic fill) { + node.shadowNode.setFill(fill); } @ReactProp(name = "fillOpacity", defaultFloat = 1f) - public void setFillOpacity(RenderableView node, float fillOpacity) { - ((RenderableShadowNode) node.getShadowNode()).setFillOpacity(fillOpacity); + public void setFillOpacity(RenderableView node, float fillOpacity) { + node.shadowNode.setFillOpacity(fillOpacity); } @ReactProp(name = "fillRule", defaultInt = FILL_RULE_NONZERO) - public void setFillRule(RenderableView node, int fillRule) { - ((RenderableShadowNode) node.getShadowNode()).setFillRule(fillRule); + public void setFillRule(RenderableView node, int fillRule) { + node.shadowNode.setFillRule(fillRule); } @ReactProp(name = "stroke") - public void setStroke(RenderableView node, @Nullable ReadableArray strokeColors) { - ((RenderableShadowNode) node.getShadowNode()).setStroke(strokeColors); + public void setStroke(RenderableView node, @Nullable Dynamic strokeColors) { + node.shadowNode.setStroke(strokeColors); } @ReactProp(name = "strokeOpacity", defaultFloat = 1f) - public void setStrokeOpacity(RenderableView node, float strokeOpacity) { - ((RenderableShadowNode) node.getShadowNode()).setStrokeOpacity(strokeOpacity); + public void setStrokeOpacity(RenderableView node, float strokeOpacity) { + node.shadowNode.setStrokeOpacity(strokeOpacity); } @ReactProp(name = "strokeDasharray") - public void setStrokeDasharray(RenderableView node, @Nullable ReadableArray strokeDasharray) { - ((RenderableShadowNode) node.getShadowNode()).setStrokeDasharray(strokeDasharray); + public void setStrokeDasharray(RenderableView node, @Nullable ReadableArray strokeDasharray) { + node.shadowNode.setStrokeDasharray(strokeDasharray); } @ReactProp(name = "strokeDashoffset") - public void setStrokeDashoffset(RenderableView node, float strokeDashoffset) { - ((RenderableShadowNode) node.getShadowNode()).setStrokeDashoffset(strokeDashoffset); + public void setStrokeDashoffset(RenderableView node, float strokeDashoffset) { + node.shadowNode.setStrokeDashoffset(strokeDashoffset); } @ReactProp(name = "strokeWidth") - public void setStrokeWidth(RenderableView node, String strokeWidth) { - ((RenderableShadowNode) node.getShadowNode()).setStrokeWidth(strokeWidth); + public void setStrokeWidth(RenderableView node, String strokeWidth) { + node.shadowNode.setStrokeWidth(strokeWidth); } @ReactProp(name = "strokeMiterlimit", defaultFloat = 4f) - public void setStrokeMiterlimit(RenderableView node, float strokeMiterlimit) { - ((RenderableShadowNode) node.getShadowNode()).setStrokeMiterlimit(strokeMiterlimit); + public void setStrokeMiterlimit(RenderableView node, float strokeMiterlimit) { + node.shadowNode.setStrokeMiterlimit(strokeMiterlimit); } @ReactProp(name = "strokeLinecap", defaultInt = CAP_ROUND) - public void setStrokeLinecap(RenderableView node, int strokeLinecap) { - ((RenderableShadowNode) node.getShadowNode()).setStrokeLinecap(strokeLinecap); + public void setStrokeLinecap(RenderableView node, int strokeLinecap) { + node.shadowNode.setStrokeLinecap(strokeLinecap); } @ReactProp(name = "strokeLinejoin", defaultInt = JOIN_ROUND) - public void setStrokeLinejoin(RenderableView node, int strokeLinejoin) { - ((RenderableShadowNode) node.getShadowNode()).setStrokeLinejoin(strokeLinejoin); + public void setStrokeLinejoin(RenderableView node, int strokeLinejoin) { + node.shadowNode.setStrokeLinejoin(strokeLinejoin); } @ReactProp(name = "propList") - public void setPropList(RenderableView node, @Nullable ReadableArray propList) { - ((RenderableShadowNode) node.getShadowNode()).setPropList(propList); + public void setPropList(RenderableView node, @Nullable ReadableArray propList) { + node.shadowNode.setPropList(propList); } /** @@ -634,9 +635,9 @@ public void setPropList(RenderableView node, @Nullable ReadableArray propList) { * you want to override this method you should call super.onAfterUpdateTransaction from it as * the parent class of the ViewManager may rely on callback being executed. */ - protected void onAfterUpdateTransaction(RenderableView node) { + protected void onAfterUpdateTransaction(RenderableView node) { super.onAfterUpdateTransaction(node); - VirtualNode shadow = node.getShadowNode(); + VirtualNode shadow = node.shadowNode; SvgViewShadowNode view = shadow.getSvgShadowNode(); if (view == null) { return; @@ -650,19 +651,19 @@ protected void onAfterUpdateTransaction(RenderableView node) { } @Override - protected RenderableView createViewInstance(ThemedReactContext reactContext) { - return new RenderableView(reactContext); + protected RenderableView createViewInstance(ThemedReactContext reactContext) { + return new RenderableView(reactContext); } @Override - public void updateExtraData(RenderableView root, Object extraData) { + public void updateExtraData(RenderableView root, Object extraData) { throw new IllegalStateException("SVG elements does not map into a native view"); } private static final SparseArray mTagToShadowNode = new SparseArray<>(); @Override - public void onDropViewInstance(RenderableView view) { + public void onDropViewInstance(RenderableView view) { mTagToShadowNode.remove(view.getId()); view.dropView(); } diff --git a/ios/Utils/RCTConvert+RNSVG.m b/ios/Utils/RCTConvert+RNSVG.m index 53655148d..1f06b8c32 100644 --- a/ios/Utils/RCTConvert+RNSVG.m +++ b/ios/Utils/RCTConvert+RNSVG.m @@ -13,6 +13,8 @@ #import #import +NSRegularExpression *regex; + @implementation RCTConvert (RNSVG) RCT_ENUM_CONVERTER(RNSVGCGFCRule, (@{ @@ -54,6 +56,24 @@ + (RNSVGCGFloatArray)RNSVGCGFloatArray:(id)json + (RNSVGBrush *)RNSVGBrush:(id)json { + if ([json isKindOfClass:[NSString class]]) { + NSString *value = [self NSString:json]; + if (!regex) { + regex = [NSRegularExpression regularExpressionWithPattern:@"[0-9.-]+" options:NSRegularExpressionCaseInsensitive error:nil]; + } + NSArray *_matches = [regex matchesInString:value options:0 range:NSMakeRange(0, [value length])]; + NSMutableArray *output = [NSMutableArray array]; + NSUInteger i = 0; + [output addObject:[NSNumber numberWithInteger:0]]; + for (NSTextCheckingResult *match in _matches) { + NSString* strNumber = [value substringWithRange:match.range]; + [output addObject:[NSNumber numberWithDouble:(i++ < 3 ? strNumber.doubleValue / 255 : strNumber.doubleValue)]]; + } + if ([output count] < 5) { + [output addObject:[NSNumber numberWithDouble:1]]; + } + return [[RNSVGSolidColorBrush alloc] initWithArray:output]; + } NSArray *arr = [self NSArray:json]; NSUInteger type = [self NSUInteger:arr.firstObject];