mirror of
https://github.com/zoriya/react-native-svg.git
synced 2025-12-20 14:05:09 +00:00
add viewBox support for android
This commit is contained in:
@@ -5,7 +5,8 @@ import React, {
|
|||||||
import Svg, {
|
import Svg, {
|
||||||
Symbol,
|
Symbol,
|
||||||
Circle,
|
Circle,
|
||||||
Use
|
Use,
|
||||||
|
Rect
|
||||||
} from 'react-native-svg';
|
} from 'react-native-svg';
|
||||||
|
|
||||||
class SymbolExample extends Component{
|
class SymbolExample extends Component{
|
||||||
|
|||||||
@@ -55,14 +55,14 @@ public class RNSVGCircleShadowNode extends RNSVGPathShadowNode {
|
|||||||
@Override
|
@Override
|
||||||
protected Path getPath(Canvas canvas, Paint paint) {
|
protected Path getPath(Canvas canvas, Paint paint) {
|
||||||
Path path = new Path();
|
Path path = new Path();
|
||||||
float cx = PropHelper.fromPercentageToFloat(mCx, mWidth, 0, mScale);
|
float cx = PropHelper.fromPercentageToFloat(mCx, mCanvasWidth, 0, mScale);
|
||||||
float cy = PropHelper.fromPercentageToFloat(mCy, mHeight, 0, mScale);
|
float cy = PropHelper.fromPercentageToFloat(mCy, mCanvasHeight, 0, mScale);
|
||||||
|
|
||||||
float r;
|
float r;
|
||||||
if (PropHelper.isPercentage(mR)) {
|
if (PropHelper.isPercentage(mR)) {
|
||||||
r = PropHelper.fromPercentageToFloat(mR, 1, 0, 1);
|
r = PropHelper.fromPercentageToFloat(mR, 1, 0, 1);
|
||||||
float powX = (float)Math.pow((mWidth * r), 2);
|
float powX = (float)Math.pow((mCanvasWidth * r), 2);
|
||||||
float powY = (float)Math.pow((mHeight * r), 2);
|
float powY = (float)Math.pow((mCanvasHeight * r), 2);
|
||||||
r = (float)Math.sqrt(powX + powY) / (float)Math.sqrt(2);
|
r = (float)Math.sqrt(powX + powY) / (float)Math.sqrt(2);
|
||||||
} else {
|
} else {
|
||||||
r = Float.parseFloat(mR) * mScale;
|
r = Float.parseFloat(mR) * mScale;
|
||||||
|
|||||||
@@ -63,10 +63,10 @@ public class RNSVGEllipseShadowNode extends RNSVGPathShadowNode {
|
|||||||
@Override
|
@Override
|
||||||
protected Path getPath(Canvas canvas, Paint paint) {
|
protected Path getPath(Canvas canvas, Paint paint) {
|
||||||
Path path = new Path();
|
Path path = new Path();
|
||||||
float cx = PropHelper.fromPercentageToFloat(mCx, mWidth, 0, mScale);
|
float cx = PropHelper.fromPercentageToFloat(mCx, mCanvasWidth, 0, mScale);
|
||||||
float cy = PropHelper.fromPercentageToFloat(mCy, mHeight, 0, mScale);
|
float cy = PropHelper.fromPercentageToFloat(mCy, mCanvasHeight, 0, mScale);
|
||||||
float rx = PropHelper.fromPercentageToFloat(mRx, mWidth, 0, mScale);
|
float rx = PropHelper.fromPercentageToFloat(mRx, mCanvasWidth, 0, mScale);
|
||||||
float ry = PropHelper.fromPercentageToFloat(mRy, mHeight, 0, mScale);
|
float ry = PropHelper.fromPercentageToFloat(mRy, mCanvasHeight, 0, mScale);
|
||||||
RectF oval = new RectF(cx - rx, cy - ry, cx + rx, cy + ry);
|
RectF oval = new RectF(cx - rx, cy - ry, cx + rx, cy + ry);
|
||||||
path.addOval(oval, Path.Direction.CW);
|
path.addOval(oval, Path.Direction.CW);
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import java.util.ArrayList;
|
|||||||
public class RNSVGGroupShadowNode extends RNSVGPathShadowNode {
|
public class RNSVGGroupShadowNode extends RNSVGPathShadowNode {
|
||||||
|
|
||||||
public void draw(Canvas canvas, Paint paint, float opacity) {
|
public void draw(Canvas canvas, Paint paint, float opacity) {
|
||||||
opacity *= mOpacity;
|
|
||||||
RNSVGSvgViewShadowNode svg = getSvgShadowNode();
|
RNSVGSvgViewShadowNode svg = getSvgShadowNode();
|
||||||
|
|
||||||
if (opacity > MIN_OPACITY_FOR_DRAW) {
|
if (opacity > MIN_OPACITY_FOR_DRAW) {
|
||||||
@@ -36,6 +35,7 @@ public class RNSVGGroupShadowNode extends RNSVGPathShadowNode {
|
|||||||
for (int i = 0; i < getChildCount(); i++) {
|
for (int i = 0; i < getChildCount(); i++) {
|
||||||
RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i);
|
RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i);
|
||||||
child.setupDimensions(canvas);
|
child.setupDimensions(canvas);
|
||||||
|
|
||||||
child.mergeProperties(this, mPropList, true);
|
child.mergeProperties(this, mPropList, true);
|
||||||
child.draw(canvas, paint, opacity * mOpacity);
|
child.draw(canvas, paint, opacity * mOpacity);
|
||||||
|
|
||||||
|
|||||||
@@ -91,10 +91,10 @@ public class RNSVGImageShadowNode extends RNSVGPathShadowNode {
|
|||||||
int count = saveAndSetupCanvas(canvas);
|
int count = saveAndSetupCanvas(canvas);
|
||||||
|
|
||||||
clip(canvas, paint);
|
clip(canvas, paint);
|
||||||
float x = PropHelper.fromPercentageToFloat(mX, mWidth, 0, mScale);
|
float x = PropHelper.fromPercentageToFloat(mX, mCanvasWidth, 0, mScale);
|
||||||
float y = PropHelper.fromPercentageToFloat(mY, mHeight, 0, mScale);
|
float y = PropHelper.fromPercentageToFloat(mY, mCanvasHeight, 0, mScale);
|
||||||
float w = PropHelper.fromPercentageToFloat(mW, mWidth, 0, mScale);
|
float w = PropHelper.fromPercentageToFloat(mW, mCanvasWidth, 0, mScale);
|
||||||
float h = PropHelper.fromPercentageToFloat(mH, mHeight, 0, mScale);
|
float h = PropHelper.fromPercentageToFloat(mH, mCanvasHeight, 0, mScale);
|
||||||
canvas.drawBitmap(mBitmap, null, new Rect((int) x, (int) y, (int) (x + w), (int)(y + h)), null);
|
canvas.drawBitmap(mBitmap, null, new Rect((int) x, (int) y, (int) (x + w), (int)(y + h)), null);
|
||||||
|
|
||||||
restoreCanvas(canvas, count);
|
restoreCanvas(canvas, count);
|
||||||
|
|||||||
@@ -68,10 +68,10 @@ public class RNSVGLineShadowNode extends RNSVGPathShadowNode {
|
|||||||
@Override
|
@Override
|
||||||
protected Path getPath(Canvas canvas, Paint paint) {
|
protected Path getPath(Canvas canvas, Paint paint) {
|
||||||
Path path = new Path();
|
Path path = new Path();
|
||||||
float x1 = PropHelper.fromPercentageToFloat(mX1, mWidth, 0, mScale);
|
float x1 = PropHelper.fromPercentageToFloat(mX1, mCanvasWidth, 0, mScale);
|
||||||
float y1 = PropHelper.fromPercentageToFloat(mY1, mHeight, 0, mScale);
|
float y1 = PropHelper.fromPercentageToFloat(mY1, mCanvasHeight, 0, mScale);
|
||||||
float x2 = PropHelper.fromPercentageToFloat(mX2, mWidth, 0, mScale);
|
float x2 = PropHelper.fromPercentageToFloat(mX2, mCanvasWidth, 0, mScale);
|
||||||
float y2 = PropHelper.fromPercentageToFloat(mY2, mHeight, 0, mScale);
|
float y2 = PropHelper.fromPercentageToFloat(mY2, mCanvasHeight, 0, mScale);
|
||||||
|
|
||||||
path.moveTo(x1, y1);
|
path.moveTo(x1, y1);
|
||||||
path.lineTo(x2, y2);
|
path.lineTo(x2, y2);
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ public class RNSVGPathShadowNode extends RNSVGVirtualNode {
|
|||||||
|
|
||||||
private ArrayList<String> mChangedList;
|
private ArrayList<String> mChangedList;
|
||||||
private ArrayList<Object> mOriginProperties;
|
private ArrayList<Object> mOriginProperties;
|
||||||
protected ReadableArray mPropList;
|
protected ReadableArray mPropList = new JavaOnlyArray();;
|
||||||
|
|
||||||
@ReactProp(name = "d")
|
@ReactProp(name = "d")
|
||||||
public void setPath(@Nullable ReadableArray shapePath) {
|
public void setPath(@Nullable ReadableArray shapePath) {
|
||||||
@@ -381,8 +381,8 @@ public class RNSVGPathShadowNode extends RNSVGVirtualNode {
|
|||||||
@Override
|
@Override
|
||||||
public int hitTest(Point point, View view) {
|
public int hitTest(Point point, View view) {
|
||||||
Bitmap bitmap = Bitmap.createBitmap(
|
Bitmap bitmap = Bitmap.createBitmap(
|
||||||
mWidth,
|
mCanvasWidth,
|
||||||
mHeight,
|
mCanvasHeight,
|
||||||
Bitmap.Config.ARGB_8888);
|
Bitmap.Config.ARGB_8888);
|
||||||
|
|
||||||
Canvas canvas = new Canvas(bitmap);
|
Canvas canvas = new Canvas(bitmap);
|
||||||
|
|||||||
@@ -87,12 +87,12 @@ public class RNSVGRectShadowNode extends RNSVGPathShadowNode {
|
|||||||
@Override
|
@Override
|
||||||
protected Path getPath(Canvas canvas, Paint paint) {
|
protected Path getPath(Canvas canvas, Paint paint) {
|
||||||
Path path = new Path();
|
Path path = new Path();
|
||||||
float x = PropHelper.fromPercentageToFloat(mX, mWidth, 0, mScale);
|
float x = PropHelper.fromPercentageToFloat(mX, mCanvasWidth, 0, mScale);
|
||||||
float y = PropHelper.fromPercentageToFloat(mY, mHeight, 0, mScale);
|
float y = PropHelper.fromPercentageToFloat(mY, mCanvasHeight, 0, mScale);
|
||||||
float w = PropHelper.fromPercentageToFloat(mW, mWidth, 0, mScale);
|
float w = PropHelper.fromPercentageToFloat(mW, mCanvasWidth, 0, mScale);
|
||||||
float h = PropHelper.fromPercentageToFloat(mH, mHeight, 0, mScale);
|
float h = PropHelper.fromPercentageToFloat(mH, mCanvasHeight, 0, mScale);
|
||||||
float rx = PropHelper.fromPercentageToFloat(mRx, mWidth, 0, mScale);
|
float rx = PropHelper.fromPercentageToFloat(mRx, mCanvasWidth, 0, mScale);
|
||||||
float ry = PropHelper.fromPercentageToFloat(mRy, mHeight, 0, mScale);
|
float ry = PropHelper.fromPercentageToFloat(mRy, mCanvasHeight, 0, mScale);
|
||||||
|
|
||||||
if (rx != 0 || ry != 0) {
|
if (rx != 0 || ry != 0) {
|
||||||
if (rx == 0) {
|
if (rx == 0) {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ public class RNSVGRenderableViewManager extends ViewGroupManager<ViewGroup> {
|
|||||||
/* package */ static final String CLASS_CLIP_PATH = "RNSVGClipPath";
|
/* package */ static final String CLASS_CLIP_PATH = "RNSVGClipPath";
|
||||||
/* package */ static final String CLASS_DEFS = "RNSVGDefs";
|
/* package */ static final String CLASS_DEFS = "RNSVGDefs";
|
||||||
/* package */ static final String CLASS_USE = "RNSVGUse";
|
/* package */ static final String CLASS_USE = "RNSVGUse";
|
||||||
|
/* package */ static final String CLASS_VIEW_BOX = "RNSVGViewBox";
|
||||||
|
|
||||||
private final String mClassName;
|
private final String mClassName;
|
||||||
|
|
||||||
@@ -82,6 +83,9 @@ public class RNSVGRenderableViewManager extends ViewGroupManager<ViewGroup> {
|
|||||||
return new RNSVGRenderableViewManager(CLASS_USE);
|
return new RNSVGRenderableViewManager(CLASS_USE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static RNSVGRenderableViewManager createRNSVGViewBoxViewManager() {
|
||||||
|
return new RNSVGRenderableViewManager(CLASS_VIEW_BOX);
|
||||||
|
}
|
||||||
|
|
||||||
private RNSVGRenderableViewManager(String className) {
|
private RNSVGRenderableViewManager(String className) {
|
||||||
mClassName = className;
|
mClassName = className;
|
||||||
@@ -128,6 +132,9 @@ public class RNSVGRenderableViewManager extends ViewGroupManager<ViewGroup> {
|
|||||||
case CLASS_USE:
|
case CLASS_USE:
|
||||||
mVirtualNode = new RNSVGUseShadowNode();
|
mVirtualNode = new RNSVGUseShadowNode();
|
||||||
break;
|
break;
|
||||||
|
case CLASS_VIEW_BOX:
|
||||||
|
mVirtualNode = new RNSVGViewBoxShadowNode();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("Unexpected type " + mClassName);
|
throw new IllegalStateException("Unexpected type " + mClassName);
|
||||||
}
|
}
|
||||||
@@ -161,6 +168,8 @@ public class RNSVGRenderableViewManager extends ViewGroupManager<ViewGroup> {
|
|||||||
return RNSVGDefsShadowNode.class;
|
return RNSVGDefsShadowNode.class;
|
||||||
case CLASS_USE:
|
case CLASS_USE:
|
||||||
return RNSVGUseShadowNode.class;
|
return RNSVGUseShadowNode.class;
|
||||||
|
case CLASS_VIEW_BOX:
|
||||||
|
return RNSVGViewBoxShadowNode.class;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("Unexpected type " + mClassName);
|
throw new IllegalStateException("Unexpected type " + mClassName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -194,8 +194,8 @@ public class RNSVGTextShadowNode extends RNSVGPathShadowNode {
|
|||||||
@Override
|
@Override
|
||||||
public int hitTest(Point point, View view) {
|
public int hitTest(Point point, View view) {
|
||||||
Bitmap bitmap = Bitmap.createBitmap(
|
Bitmap bitmap = Bitmap.createBitmap(
|
||||||
mWidth,
|
mCanvasWidth,
|
||||||
mHeight,
|
mCanvasHeight,
|
||||||
Bitmap.Config.ARGB_8888);
|
Bitmap.Config.ARGB_8888);
|
||||||
|
|
||||||
Canvas canvas = new Canvas(bitmap);
|
Canvas canvas = new Canvas(bitmap);
|
||||||
|
|||||||
@@ -47,6 +47,14 @@ public class RNSVGUseShadowNode extends RNSVGPathShadowNode {
|
|||||||
markUpdated();
|
markUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getWidth() {
|
||||||
|
return mWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHeight() {
|
||||||
|
return mHeight;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Canvas canvas, Paint paint, float opacity) {
|
public void draw(Canvas canvas, Paint paint, float opacity) {
|
||||||
RNSVGVirtualNode template = getSvgShadowNode().getDefinedTemplate(mHref);
|
RNSVGVirtualNode template = getSvgShadowNode().getDefinedTemplate(mHref);
|
||||||
|
|||||||
@@ -0,0 +1,184 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package com.horcrux.svg;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Matrix;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.facebook.react.bridge.ReadableArray;
|
||||||
|
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shadow node for virtual RNSVGPath view
|
||||||
|
*/
|
||||||
|
public class RNSVGViewBoxShadowNode extends RNSVGGroupShadowNode {
|
||||||
|
|
||||||
|
private static final int MOS_MEET = 0;
|
||||||
|
private static final int MOS_SLICE = 1;
|
||||||
|
private static final int MOS_NONE = 2;
|
||||||
|
|
||||||
|
private String mMinX;
|
||||||
|
private String mMinY;
|
||||||
|
private String mVbWidth;
|
||||||
|
private String mVbHeight;
|
||||||
|
private String mBoxWidth;
|
||||||
|
private String mBoxHeight;
|
||||||
|
private String mAlign;
|
||||||
|
private int mMeetOrSlice;
|
||||||
|
private boolean mFromSymbol = false;
|
||||||
|
|
||||||
|
@ReactProp(name = "minX")
|
||||||
|
public void setMinX(String minX) {
|
||||||
|
mMinX = minX;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "minY")
|
||||||
|
public void setMinY(String minY) {
|
||||||
|
mMinY = minY;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "vbWidth")
|
||||||
|
public void setVbWidth(String vbWidth) {
|
||||||
|
mVbWidth = vbWidth;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "vbHeight")
|
||||||
|
public void setVbHeight(String vbHeight) {
|
||||||
|
mVbHeight = vbHeight;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ReactProp(name = "width")
|
||||||
|
public void setWidth(String width) {
|
||||||
|
mBoxWidth = width;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "height")
|
||||||
|
public void setHeight(String height) {
|
||||||
|
mBoxHeight = height;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "align")
|
||||||
|
public void setAlign(String align) {
|
||||||
|
mAlign = align;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "meetOrSlice")
|
||||||
|
public void setMeetOrSlice(int meetOrSlice) {
|
||||||
|
mMeetOrSlice = meetOrSlice;
|
||||||
|
markUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint, float opacity) {
|
||||||
|
// based on https://svgwg.org/svg2-draft/coords.html#ComputingAViewportsTransform
|
||||||
|
setupDimensions(canvas);
|
||||||
|
|
||||||
|
// Let vb-x, vb-y, vb-width, vb-height be the min-x, min-y, width and height values of the viewBox attribute respectively.
|
||||||
|
float vbX = PropHelper.fromPercentageToFloat(mMinX, mCanvasWidth, 0, mScale);
|
||||||
|
float vbY = PropHelper.fromPercentageToFloat(mMinY, mCanvasHeight, 0, mScale);
|
||||||
|
float vbWidth = PropHelper.fromPercentageToFloat(mVbWidth, mCanvasWidth, 0, mScale);
|
||||||
|
float vbHeight = PropHelper.fromPercentageToFloat(mVbHeight, mCanvasHeight, 0, mScale);
|
||||||
|
|
||||||
|
// Let e-x, e-y, e-width, e-height be the position and size of the element respectively.
|
||||||
|
float eX = mCanvasX;
|
||||||
|
float eY = mCanvasY;
|
||||||
|
float eWidth = mBoxWidth != null ? PropHelper.fromPercentageToFloat(mBoxWidth, mCanvasWidth, 0, mScale) : mCanvasWidth;
|
||||||
|
float eHeight = mBoxHeight != null ? PropHelper.fromPercentageToFloat(mBoxHeight, mCanvasHeight, 0, mScale) : mCanvasHeight;
|
||||||
|
|
||||||
|
// Initialize scale-x to e-width/vb-width.
|
||||||
|
float scaleX = eWidth / vbWidth;
|
||||||
|
|
||||||
|
// Initialize scale-y to e-height/vb-height.
|
||||||
|
float scaleY = eHeight / vbHeight;
|
||||||
|
|
||||||
|
// Initialize translate-x to vb-x - e-x.
|
||||||
|
// Initialize translate-y to vb-y - e-y.
|
||||||
|
float translateX = vbX - eX;
|
||||||
|
float translateY = vbY - eY;
|
||||||
|
|
||||||
|
// If align is 'none'
|
||||||
|
if (mMeetOrSlice == MOS_NONE) {
|
||||||
|
// Let scale be set the smaller value of scale-x and scale-y.
|
||||||
|
// Assign scale-x and scale-y to scale.
|
||||||
|
float scale = scaleX = scaleY = Math.min(scaleX, scaleY);
|
||||||
|
|
||||||
|
// If scale is greater than 1
|
||||||
|
if (scale > 1) {
|
||||||
|
// Minus translateX by (eWidth / scale - vbWidth) / 2
|
||||||
|
// Minus translateY by (eHeight / scale - vbHeight) / 2
|
||||||
|
translateX -= (eWidth / scale - vbWidth) / 2;
|
||||||
|
translateY -= (eHeight / scale - vbHeight) / 2;
|
||||||
|
} else {
|
||||||
|
translateX -= (eWidth - vbWidth * scale) / 2;
|
||||||
|
translateY -= (eHeight - vbHeight * scale) / 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If align is not 'none' and meetOrSlice is 'meet', set the larger of scale-x and scale-y to the smaller.
|
||||||
|
// Otherwise, if align is not 'none' and meetOrSlice is 'slice', set the smaller of scale-x and scale-y to the larger.
|
||||||
|
|
||||||
|
if (!mAlign.equals("none") && mMeetOrSlice == MOS_MEET) {
|
||||||
|
scaleX = scaleY = Math.min(scaleX, scaleY);
|
||||||
|
} else if (!mAlign.equals("none") && mMeetOrSlice == MOS_SLICE) {
|
||||||
|
scaleX = scaleY = Math.min(scaleX, scaleY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If align contains 'xMid', minus (e-width / scale-x - vb-width) / 2 from transform-x.
|
||||||
|
if (mAlign.contains("xMid")) {
|
||||||
|
translateX -= (eWidth / scaleX - vbWidth) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If align contains 'xMax', minus (e-width / scale-x - vb-width) from transform-x.
|
||||||
|
if (mAlign.contains("xMax")) {
|
||||||
|
translateX -= eWidth / scaleX - vbWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If align contains 'yMid', minus (e-height / scale-y - vb-height) / 2 from transform-y.
|
||||||
|
if (mAlign.contains("YMid")) {
|
||||||
|
translateY -= (eHeight / scaleY - vbHeight) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If align contains 'yMax', minus (e-height / scale-y - vb-height) from transform-y.
|
||||||
|
if (mAlign.contains("YMax")) {
|
||||||
|
translateY -= eHeight / scaleY - vbHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.scale(scaleX, scaleY);
|
||||||
|
canvas.translate(-translateX * (mFromSymbol ? scaleX : 1), -translateY * (mFromSymbol ? scaleY : 1));
|
||||||
|
super.draw(canvas, paint, opacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mergeProperties(RNSVGVirtualNode target, ReadableArray mergeList) {
|
||||||
|
if (target.getClass() == RNSVGUseShadowNode.class) {
|
||||||
|
mFromSymbol = true;
|
||||||
|
mBoxWidth = ((RNSVGUseShadowNode)target).getWidth();
|
||||||
|
mBoxHeight = ((RNSVGUseShadowNode)target).getHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetProperties() {
|
||||||
|
mBoxWidth = mBoxHeight = null;
|
||||||
|
mFromSymbol = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ import android.graphics.Matrix;
|
|||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
|
import android.graphics.Rect;
|
||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
import android.graphics.Region;
|
import android.graphics.Region;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -66,8 +67,10 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
|
|||||||
private boolean mClipRuleSet;
|
private boolean mClipRuleSet;
|
||||||
private boolean mClipDataSet;
|
private boolean mClipDataSet;
|
||||||
protected boolean mResponsible;
|
protected boolean mResponsible;
|
||||||
protected int mWidth;
|
protected int mCanvasX;
|
||||||
protected int mHeight;
|
protected int mCanvasY;
|
||||||
|
protected int mCanvasWidth;
|
||||||
|
protected int mCanvasHeight;
|
||||||
protected String mName;
|
protected String mName;
|
||||||
|
|
||||||
private RNSVGSvgViewShadowNode mSvgShadowNode;
|
private RNSVGSvgViewShadowNode mSvgShadowNode;
|
||||||
@@ -292,8 +295,12 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void setupDimensions(Canvas canvas) {
|
protected void setupDimensions(Canvas canvas) {
|
||||||
mWidth = canvas.getWidth();
|
// TODO: not sure this is a right way to get canvas boundingBox
|
||||||
mHeight = canvas.getHeight();
|
Rect mCanvasClipBounds = canvas.getClipBounds();
|
||||||
|
mCanvasX = mCanvasClipBounds.left;
|
||||||
|
mCanvasY = mCanvasClipBounds.top;
|
||||||
|
mCanvasWidth = canvas.getWidth();
|
||||||
|
mCanvasHeight = canvas.getHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void saveDefinition() {
|
protected void saveDefinition() {
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public class RNSvgPackage implements ReactPackage {
|
|||||||
RNSVGRenderableViewManager.createRNSVGClipPathViewManager(),
|
RNSVGRenderableViewManager.createRNSVGClipPathViewManager(),
|
||||||
RNSVGRenderableViewManager.createRNSVGDefsViewManager(),
|
RNSVGRenderableViewManager.createRNSVGDefsViewManager(),
|
||||||
RNSVGRenderableViewManager.createRNSVGUseViewManager(),
|
RNSVGRenderableViewManager.createRNSVGUseViewManager(),
|
||||||
|
RNSVGRenderableViewManager.createRNSVGViewBoxViewManager(),
|
||||||
new RNSVGSvgViewManager());
|
new RNSVGSvgViewManager());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,16 +20,17 @@ class SymbolElement extends Component{
|
|||||||
}
|
}
|
||||||
|
|
||||||
let content = viewBox ? <ViewBox
|
let content = viewBox ? <ViewBox
|
||||||
|
name={props.id}
|
||||||
viewBox={viewBox}
|
viewBox={viewBox}
|
||||||
preserveAspectRatio={props.preserveAspectRatio}
|
preserveAspectRatio={props.preserveAspectRatio}
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</ViewBox> : props.children;
|
</ViewBox> : <G id={props.id}>
|
||||||
|
{props.children}
|
||||||
|
</G>;
|
||||||
|
|
||||||
return <Defs>
|
return <Defs>
|
||||||
<G id={props.id}>
|
|
||||||
{content}
|
{content}
|
||||||
</G>
|
|
||||||
</Defs>;
|
</Defs>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const meetOrSliceTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const alignEnum = _.reduce([
|
const alignEnum = _.reduce([
|
||||||
'xMinMin', 'xMidYMin', 'xMaxYMin',
|
'xMinYMin', 'xMidYMin', 'xMaxYMin',
|
||||||
'xMinYMid', 'xMidYMid', 'xMaxYMid',
|
'xMinYMid', 'xMidYMid', 'xMaxYMid',
|
||||||
'xMinYMax', 'xMidYMax', 'xMaxYMax',
|
'xMinYMax', 'xMidYMax', 'xMaxYMax',
|
||||||
'none'
|
'none'
|
||||||
@@ -36,7 +36,7 @@ class ViewBox extends Component{
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let {viewBox, preserveAspectRatio} = this.props;
|
let {viewBox, preserveAspectRatio, name} = this.props;
|
||||||
|
|
||||||
let params = viewBox.trim().split(spacesRegExp);
|
let params = viewBox.trim().split(spacesRegExp);
|
||||||
|
|
||||||
@@ -51,7 +51,9 @@ class ViewBox extends Component{
|
|||||||
|
|
||||||
let meetOrSlice = meetOrSliceTypes[modes[1]] || 0;
|
let meetOrSlice = meetOrSliceTypes[modes[1]] || 0;
|
||||||
let align = alignEnum[modes[0]] || 'xMidYMid';
|
let align = alignEnum[modes[0]] || 'xMidYMid';
|
||||||
|
|
||||||
return <RNSVGViewBox
|
return <RNSVGViewBox
|
||||||
|
name={name}
|
||||||
minX={params[0]}
|
minX={params[0]}
|
||||||
minY={params[1]}
|
minY={params[1]}
|
||||||
vbWidth={params[2]}
|
vbWidth={params[2]}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
[self clip:context];
|
[self clip:context];
|
||||||
|
|
||||||
for (RNSVGNode *node in self.subviews) {
|
for (RNSVGNode *node in self.subviews) {
|
||||||
[node inheritProperties:self inheritedList:self.propList];
|
[node mergeProperties:self mergeList:self.propList inherited:YES];
|
||||||
[node renderTo:context];
|
[node renderTo:context];
|
||||||
|
|
||||||
if (node.responsible && !svg.responsible) {
|
if (node.responsible && !svg.responsible) {
|
||||||
@@ -78,11 +78,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)inheritProperties:(__kindof RNSVGNode *)parent inheritedList:(NSArray<NSString *> *)inheritedList;
|
|
||||||
{
|
|
||||||
for (NSString *key in inheritedList) {
|
|
||||||
[self inheritProperty:parent propName:key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -71,18 +71,13 @@
|
|||||||
*/
|
*/
|
||||||
- (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray<NSString *> *)mergeList;
|
- (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray<NSString *> *)mergeList;
|
||||||
|
|
||||||
|
- (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray<NSString *> *)mergeList inherited:(BOOL)inherited;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* just for template node to reset all owned properties once after rendered.
|
* just for template node to reset all owned properties once after rendered.
|
||||||
*/
|
*/
|
||||||
- (void)resetProperties;
|
- (void)resetProperties;
|
||||||
|
|
||||||
/**
|
|
||||||
* inherit properties from parent g element
|
|
||||||
*/
|
|
||||||
- (void)inheritProperties:(__kindof RNSVGNode *)parent inheritedList:(NSArray<NSString *> *)inheritedList;
|
|
||||||
|
|
||||||
- (void)inheritProperty:(__kindof RNSVGNode *)parent propName:(NSString *)propName;
|
|
||||||
|
|
||||||
- (void)beginTransparencyLayer:(CGContextRef)context;
|
- (void)beginTransparencyLayer:(CGContextRef)context;
|
||||||
|
|
||||||
- (void)endTransparencyLayer:(CGContextRef)context;
|
- (void)endTransparencyLayer:(CGContextRef)context;
|
||||||
|
|||||||
@@ -224,16 +224,6 @@
|
|||||||
// abstract
|
// abstract
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)inheritProperty:(__kindof RNSVGNode *)parent propName:(NSString *)propName
|
|
||||||
{
|
|
||||||
// abstract
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)inheritProperties:(__kindof RNSVGNode *)parent inheritedList:(NSArray<NSString *> *)inheritedList;
|
|
||||||
{
|
|
||||||
// abstract
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
CGPathRelease(_clipPath);
|
CGPathRelease(_clipPath);
|
||||||
|
|||||||
@@ -215,7 +215,6 @@
|
|||||||
[self setValue:[_originProperties valueForKey:key] forKey:key];
|
[self setValue:[_originProperties valueForKey:key] forKey:key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[super resetProperties];
|
|
||||||
_changedList = nil;
|
_changedList = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,11 +230,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)inheritProperties:(__kindof RNSVGNode *)parent inheritedList:(NSArray<NSString *> *)inheritedList
|
|
||||||
{
|
|
||||||
[self mergeProperties:parent mergeList:inheritedList inherited:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)renderLayerTo:(CGContextRef)context
|
- (void)renderLayerTo:(CGContextRef)context
|
||||||
{
|
{
|
||||||
// abstract
|
// abstract
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ const ViewBoxAttributes = {
|
|||||||
vbWidth: true,
|
vbWidth: true,
|
||||||
vbHeight: true,
|
vbHeight: true,
|
||||||
align: true,
|
align: true,
|
||||||
meetOrSlice: true
|
meetOrSlice: true,
|
||||||
|
name: true
|
||||||
};
|
};
|
||||||
|
|
||||||
const NodeAttributes = {
|
const NodeAttributes = {
|
||||||
|
|||||||
Reference in New Issue
Block a user