Add preserveAspectRatio prop for Image

Add preserveAspectRatio prop for Image.
Fix touch events for Image on Android.
Fix viewBox slice bug on Android.
This commit is contained in:
Horcrux
2016-08-13 14:03:08 +08:00
parent a4c0c60b7f
commit d1afb78da0
20 changed files with 251 additions and 42 deletions

View File

@@ -7,24 +7,48 @@ import Svg, {
Defs, Defs,
Circle, Circle,
ClipPath, ClipPath,
Rect,
Text Text
} from 'react-native-svg'; } from 'react-native-svg';
class ImageExample extends Component{ class ImageExample extends Component{
static title = 'Image'; static title = 'Draw Image with preserveAspectRatio prop';
render() { render() {
return <Svg return <Svg
height="100" height="100"
width="100" width="100"
style={{backgroundColor: 'red'}}
> >
<Defs>
<ClipPath id="clip">
<Circle cx="50%" cy="50%" r="40%"/>
</ClipPath>
</Defs>
<Rect
x="5%"
y="5%"
width="50%"
height="90%"
/>
<Image <Image
x="5%" x="5%"
y="5%" y="5%"
width="90%" width="50%"
height="90%" height="90%"
preserveAspectRatio="xMidYMid slice"
opacity="0.5"
href={require('../image.jpg')} href={require('../image.jpg')}
clipPath="url(#clip)"
/> />
<Text
x="50"
y="50"
textAnchor="middle"
fontWeight="bold"
fontSize="16"
fill="blue"
>HOGWARTS</Text>
</Svg>; </Svg>;
} }
} }
@@ -43,6 +67,7 @@ class ClipImage extends Component{
</ClipPath> </ClipPath>
</Defs> </Defs>
<Image <Image
onPress={() => alert('press on Image')}
x="5%" x="5%"
y="5%" y="5%"
width="90%" width="90%"

View File

@@ -579,7 +579,7 @@ npm install
2. more Text features support (textPath, tref, tspan) 2. more Text features support (textPath, tref, tspan)
3. Pattern element 3. Pattern element
4. implement Animated elements 4. implement Animated elements
5. more Image features support 5. load Image from url
#### Thanks: #### Thanks:

View File

@@ -12,10 +12,16 @@ package com.horcrux.svg;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.net.Uri; import android.net.Uri;
import android.util.Log;
import com.facebook.common.executors.UiThreadImmediateExecutorService; import com.facebook.common.executors.UiThreadImmediateExecutorService;
import com.facebook.common.logging.FLog; import com.facebook.common.logging.FLog;
import com.facebook.common.references.CloseableReference; import com.facebook.common.references.CloseableReference;
@@ -45,6 +51,9 @@ public class RNSVGImageShadowNode extends RNSVGPathShadowNode {
private String mW; private String mW;
private String mH; private String mH;
private Uri mUri; private Uri mUri;
private float mImageRatio;
private String mAlign;
private int mMeetOrSlice;
private AtomicBoolean mLoading = new AtomicBoolean(false); private AtomicBoolean mLoading = new AtomicBoolean(false);
@ReactProp(name = "x") @ReactProp(name = "x")
@@ -81,12 +90,29 @@ public class RNSVGImageShadowNode extends RNSVGPathShadowNode {
return; return;
} }
mImageRatio = (float)src.getInt("width") / (float)src.getInt("height");
mUri = Uri.parse(uriString); mUri = Uri.parse(uriString);
} }
} }
@ReactProp(name = "align")
public void setAlign(String align) {
mAlign = align;
markUpdated();
}
@ReactProp(name = "meetOrSlice")
public void setMeetOrSlice(int meetOrSlice) {
mMeetOrSlice = meetOrSlice;
markUpdated();
}
@Override @Override
public void draw(final Canvas canvas, final Paint paint, final float opacity) { public void draw(final Canvas canvas, final Paint paint, final float opacity) {
mPath = new Path();
mPath.addRect(new RectF(getRect()), Path.Direction.CW);
if (!mLoading.get()) { if (!mLoading.get()) {
final ImageRequest request = ImageRequestBuilder.newBuilderWithSource(mUri).build(); final ImageRequest request = ImageRequestBuilder.newBuilderWithSource(mUri).build();
@@ -140,14 +166,70 @@ public class RNSVGImageShadowNode extends RNSVGPathShadowNode {
private void doRender(@Nonnull final Canvas canvas, @Nonnull final Paint paint, @Nonnull final Bitmap bitmap, final float opacity) { private void doRender(@Nonnull final Canvas canvas, @Nonnull final Paint paint, @Nonnull final Bitmap bitmap, final float opacity) {
final int count = saveAndSetupCanvas(canvas); final int count = saveAndSetupCanvas(canvas);
canvas.concat(mMatrix);
clip(canvas, paint);
Paint alphaPaint = new Paint(); Paint alphaPaint = new Paint();
alphaPaint.setAlpha((int) (opacity * 255)); alphaPaint.setAlpha((int) (opacity * 255));
canvas.drawBitmap(bitmap, null, getRect(), alphaPaint); // apply viewBox transform on Image render.
Rect rect = getRect();
float rectWidth = (float)rect.width();
float rectHeight = (float)rect.height();
float rectX = (float)rect.left;
float rectY = (float)rect.top;
float rectRatio = rectWidth / rectHeight;
RectF renderRect;
if (mImageRatio == rectRatio) {
renderRect = new RectF(rect);
} else if (mImageRatio < rectRatio) {
renderRect = new RectF(0, 0, (int)(rectHeight * mImageRatio), (int)rectHeight);
} else {
renderRect = new RectF(0, 0, (int)rectWidth, (int)(rectWidth / mImageRatio));
}
RNSVGViewBoxShadowNode viewBox = new RNSVGViewBoxShadowNode();
viewBox.setMinX("0");
viewBox.setMinY("0");
viewBox.setVbWidth(renderRect.width() / mScale + "");
viewBox.setVbHeight(renderRect.height() / mScale + "");
viewBox.setWidth(rectWidth / mScale);
viewBox.setHeight(rectHeight / mScale);
viewBox.setAlign(mAlign);
viewBox.setMeetOrSlice(mMeetOrSlice);
viewBox.setupDimensions(new Rect(0, 0, (int) rectWidth, (int) rectHeight));
Matrix transform = viewBox.getTransform();
transform.mapRect(renderRect);
Matrix translation = new Matrix();
translation.postTranslate(rectX, rectY);
translation.mapRect(renderRect);
Path clip = new Path();
Path clipPath = getClipPath(canvas, paint);
if (clipPath != null) {
// clip by the common area of clipPath and mPath
clip.setFillType(Path.FillType.INVERSE_EVEN_ODD);
Path inverseWindingPath = new Path();
inverseWindingPath.setFillType(Path.FillType.INVERSE_WINDING);
inverseWindingPath.addPath(mPath);
inverseWindingPath.addPath(clipPath);
Path evenOddPath = new Path();
evenOddPath.setFillType(Path.FillType.EVEN_ODD);
evenOddPath.addPath(mPath);
evenOddPath.addPath(clipPath);
canvas.clipPath(evenOddPath, Region.Op.DIFFERENCE);
canvas.clipPath(inverseWindingPath, Region.Op.DIFFERENCE);
} else {
canvas.clipPath(mPath, Region.Op.REPLACE);
}
canvas.drawBitmap(bitmap, null, renderRect, alphaPaint);
restoreCanvas(canvas, count); restoreCanvas(canvas, count);
markUpdateSeen(); markUpdateSeen();
} }

View File

@@ -103,7 +103,7 @@ public class RNSVGRectShadowNode extends RNSVGPathShadowNode {
} }
path.addRoundRect(new RectF(x, y, x + w, y + h), rx, ry, Path.Direction.CW); path.addRoundRect(new RectF(x, y, x + w, y + h), rx, ry, Path.Direction.CW);
} else { } else {
path.addRect(x, y, x + w, y + h, Path.Direction.CW); path.addRect(x, y, x + w, y + h, Path.Direction.CW);
} }
return path; return path;
} }

View File

@@ -10,6 +10,7 @@
package com.horcrux.svg; package com.horcrux.svg;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint; import android.graphics.Paint;
import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableArray;
@@ -85,8 +86,13 @@ public class RNSVGViewBoxShadowNode extends RNSVGGroupShadowNode {
@Override @Override
public void draw(Canvas canvas, Paint paint, float opacity) { public void draw(Canvas canvas, Paint paint, float opacity) {
// based on https://svgwg.org/svg2-draft/coords.html#ComputingAViewportsTransform
setupDimensions(canvas); setupDimensions(canvas);
mMatrix = getTransform();
super.draw(canvas, paint, opacity);
}
public Matrix getTransform() {
// based on https://svgwg.org/svg2-draft/coords.html#ComputingAViewportsTransform
// Let vb-x, vb-y, vb-width, vb-height be the min-x, min-y, width and height values of the viewBox attribute respectively. // 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 vbX = PropHelper.fromPercentageToFloat(mMinX, mCanvasWidth, 0, mScale);
@@ -134,7 +140,7 @@ public class RNSVGViewBoxShadowNode extends RNSVGGroupShadowNode {
if (!mAlign.equals("none") && mMeetOrSlice == MOS_MEET) { if (!mAlign.equals("none") && mMeetOrSlice == MOS_MEET) {
scaleX = scaleY = Math.min(scaleX, scaleY); scaleX = scaleY = Math.min(scaleX, scaleY);
} else if (!mAlign.equals("none") && mMeetOrSlice == MOS_SLICE) { } else if (!mAlign.equals("none") && mMeetOrSlice == MOS_SLICE) {
scaleX = scaleY = Math.min(scaleX, scaleY); scaleX = scaleY = Math.max(scaleX, scaleY);
} }
// If align contains 'xMid', minus (e-width / scale-x - vb-width) / 2 from transform-x. // If align contains 'xMid', minus (e-width / scale-x - vb-width) / 2 from transform-x.
@@ -161,10 +167,10 @@ public class RNSVGViewBoxShadowNode extends RNSVGGroupShadowNode {
// The transform applied to content contained by the element is given by // The transform applied to content contained by the element is given by
// translate(translate-x, translate-y) scale(scale-x, scale-y). // translate(translate-x, translate-y) scale(scale-x, scale-y).
mMatrix.reset(); Matrix transform = new Matrix();
mMatrix.postTranslate(-translateX * (mFromSymbol ? scaleX : 1), -translateY * (mFromSymbol ? scaleY : 1)); transform.postTranslate(-translateX * (mFromSymbol ? scaleX : 1), -translateY * (mFromSymbol ? scaleY : 1));
mMatrix.postScale(scaleX, scaleY); transform.postScale(scaleX, scaleY);
super.draw(canvas, paint, opacity); return transform;
} }
@Override @Override

View File

@@ -236,16 +236,21 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
} }
} }
protected void clip(Canvas canvas, Paint paint) { protected @Nullable Path getClipPath(Canvas canvas, Paint paint) {
Path clip = mClipPath; Path clip = mClipPath;
if (clip == null && mClipPathRef != null) { if (clip == null && mClipPathRef != null) {
RNSVGVirtualNode node = getSvgShadowNode().getDefinedClipPath(mClipPathRef); RNSVGVirtualNode node = getSvgShadowNode().getDefinedClipPath(mClipPathRef);
clip = node.getPath(canvas, paint); clip = node.getPath(canvas, paint);
} }
return clip;
}
protected void clip(Canvas canvas, Paint paint) {
Path clip = getClipPath(canvas, paint);
if (clip != null) { if (clip != null) {
canvas.clipPath(clip, Region.Op.REPLACE); canvas.clipPath(clip, Region.Op.REPLACE);
canvas.saveLayer(0f, 0f, 0f, 0f, paint, Canvas.CLIP_SAVE_FLAG);
} }
} }
@@ -286,6 +291,13 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
mCanvasHeight = canvas.getHeight(); mCanvasHeight = canvas.getHeight();
} }
protected void setupDimensions(Rect rect) {
mCanvasX = rect.left;
mCanvasY = rect.top;
mCanvasWidth = rect.width();
mCanvasHeight = rect.height();
}
protected void saveDefinition() { protected void saveDefinition() {
if (mName != null) { if (mName != null) {
getSvgShadowNode().defineTemplate(this, mName); getSvgShadowNode().defineTemplate(this, mName);

View File

@@ -4,7 +4,8 @@ import {ImageAttributes} from '../lib/attributes';
import {numberProp, touchableProps, responderProps} from '../lib/props'; import {numberProp, touchableProps, responderProps} from '../lib/props';
import Shape from './Shape'; import Shape from './Shape';
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
import {meetOrSliceTypes, alignEnum} from './ViewBox';
const spacesRegExp = /\s+/;
class Image extends Shape { class Image extends Shape {
static displayName = 'Image'; static displayName = 'Image';
@@ -15,15 +16,16 @@ class Image extends Shape {
y: numberProp, y: numberProp,
width: numberProp.isRequired, width: numberProp.isRequired,
height: numberProp.isRequired, height: numberProp.isRequired,
href: PropTypes.number.isRequired href: PropTypes.number.isRequired,
//preserveAspectRatio: PropTypes.string preserveAspectRatio: PropTypes.string
}; };
static defaultProps = { static defaultProps = {
x: 0, x: 0,
y: 0, y: 0,
width: 0, width: 0,
height: 0 height: 0,
preserveAspectRatio: 'xMidYMid meet'
}; };
setNativeProps = (...args) => { setNativeProps = (...args) => {
@@ -32,6 +34,10 @@ class Image extends Shape {
render() { render() {
let {props} = this; let {props} = this;
let modes = props.preserveAspectRatio.trim().split(spacesRegExp);
let meetOrSlice = meetOrSliceTypes[modes[1]] || 0;
let align = alignEnum[modes[0]] || 'xMidYMid';
return <RNSVGImage return <RNSVGImage
ref={ele => {this.root = ele;}} ref={ele => {this.root = ele;}}
{...this.extractProps({...props, x: null, y: null}, {responder: true, transform: true})} {...this.extractProps({...props, x: null, y: null}, {responder: true, transform: true})}
@@ -39,6 +45,8 @@ class Image extends Shape {
y={props.y.toString()} y={props.y.toString()}
width={props.width.toString()} width={props.width.toString()}
height={props.height.toString()} height={props.height.toString()}
meetOrSlice={meetOrSlice}
align={align}
src={resolveAssetSource(props.href)} src={resolveAssetSource(props.href)}
/>; />;
} }

View File

@@ -73,3 +73,8 @@ const RNSVGViewBox = createReactNativeComponentClass({
export default ViewBox; export default ViewBox;
export {
meetOrSliceTypes,
alignEnum
}

View File

@@ -9,12 +9,16 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "RNSVGRenderable.h" #import "RNSVGRenderable.h"
#import "RNSVGVBMOS.h"
@interface RNSVGImage : RNSVGRenderable @interface RNSVGImage : RNSVGRenderable
@property (nonatomic, assign) id src; @property (nonatomic, assign) id src;
@property (nonatomic, strong) NSString* x; @property (nonatomic, strong) NSString* x;
@property (nonatomic, strong) NSString* y; @property (nonatomic, strong) NSString* y;
@property (nonatomic, strong) NSString* width; @property (nonatomic, strong) NSString* width;
@property (nonatomic, strong) NSString* height; @property (nonatomic, strong) NSString* height;
@property (nonatomic, strong) NSString *align;
@property (nonatomic, assign) RNSVGVBMOS meetOrSlice;
@end @end

View File

@@ -7,12 +7,15 @@
*/ */
#import "RNSVGImage.h" #import "RNSVGImage.h"
#import "RCTImageSource.h"
#import "RCTConvert+RNSVG.h" #import "RCTConvert+RNSVG.h"
#import "RCTLog.h" #import "RCTLog.h"
#import "RNSVGViewBox.h"
@implementation RNSVGImage @implementation RNSVGImage
{ {
CGImageRef image; CGImageRef _image;
CGFloat _imageRatio;
} }
- (void)setSrc:(id)src - (void)setSrc:(id)src
@@ -21,8 +24,10 @@
return; return;
} }
_src = src; _src = src;
CGImageRelease(image); CGImageRelease(_image);
image = CGImageRetain([RCTConvert CGImage:src]); RCTImageSource *source = [RCTConvert RCTImageSource:src];
_imageRatio = source.size.width / source.size.height;
_image = CGImageRetain([RCTConvert CGImage:src]);
[self invalidate]; [self invalidate];
} }
@@ -62,29 +67,80 @@
_height = height; _height = height;
} }
- (void)setAlign:(NSString *)align
{
if (align == _align) {
return;
}
[self invalidate];
_align = align;
}
- (void)setMeetOrSlice:(RNSVGVBMOS)meetOrSlice
{
if (meetOrSlice == _meetOrSlice) {
return;
}
[self invalidate];
_meetOrSlice = meetOrSlice;
}
- (void)dealloc - (void)dealloc
{ {
CGImageRelease(image); CGImageRelease(_image);
} }
- (void)renderLayerTo:(CGContextRef)context - (void)renderLayerTo:(CGContextRef)context
{ {
CGRect rect = [self getRect:context]; CGRect rect = [self getRect:context];
// add hit area // add hit area
self.hitArea = CGPathCreateWithRect(rect, nil); self.hitArea = CFAutorelease(CGPathCreateWithRect(rect, nil));
[self clip:context]; [self clip:context];
CGContextSaveGState(context); CGContextSaveGState(context);
CGContextTranslateCTM(context, 0, rect.size.height); CGContextTranslateCTM(context, 0, rect.size.height + 2 * rect.origin.y);
CGContextScaleCTM(context, 1.0, -1.0); CGContextScaleCTM(context, 1, -1);
CGContextDrawImage(context, rect, image);
// apply viewBox transform on Image render.
CGFloat imageRatio = _imageRatio;
CGFloat rectWidth = rect.size.width;
CGFloat rectHeight = rect.size.height;
CGFloat rectX = rect.origin.x;
CGFloat rectY = rect.origin.y;
CGFloat rectRatio = rectWidth / rectHeight;
CGRect renderRect;
if (imageRatio == rectRatio) {
renderRect = rect;
} else if (imageRatio < rectRatio) {
renderRect = CGRectMake(0, 0, rectHeight * imageRatio, rectHeight);
} else {
renderRect = CGRectMake(0, 0, rectWidth, rectWidth / imageRatio);
}
RNSVGViewBox *viewBox = [[RNSVGViewBox alloc] init];
viewBox.minX = viewBox.minY = @"0";
viewBox.vbWidth = [NSString stringWithFormat:@"%f", renderRect.size.width];
viewBox.vbHeight = [NSString stringWithFormat:@"%f", renderRect.size.height];
viewBox.width = [NSString stringWithFormat:@"%f", rectWidth];
viewBox.height = [NSString stringWithFormat:@"%f", rectHeight];
viewBox.align = self.align;
viewBox.meetOrSlice = self.meetOrSlice;
[viewBox setBoundingBox:CGRectMake(0, 0, rectWidth, rectHeight)];
CGAffineTransform transform = [viewBox getTransform];
renderRect = CGRectApplyAffineTransform(renderRect, transform);
renderRect = CGRectApplyAffineTransform(renderRect, CGAffineTransformMakeTranslation(rectX, rectY));
CGContextClipToRect(context, rect);
CGContextDrawImage(context, renderRect, _image);
CGContextRestoreGState(context); CGContextRestoreGState(context);
} }
- (CGRect)getRect:(CGContextRef)context - (CGRect)getRect:(CGContextRef)context
{ {
[self setBoundingBox:context]; [self setBoundingBox:CGContextGetClipBoundingBox(context)];
CGFloat x = [self getWidthRelatedValue:self.x]; CGFloat x = [self getWidthRelatedValue:self.x];
CGFloat y = [self getHeightRelatedValue:self.y]; CGFloat y = [self getHeightRelatedValue:self.y];
CGFloat width = [self getWidthRelatedValue:self.width]; CGFloat width = [self getWidthRelatedValue:self.width];

View File

@@ -29,7 +29,7 @@
@property (nonatomic, assign) CGPathRef hitArea; @property (nonatomic, assign) CGPathRef hitArea;
@property (nonatomic, copy) NSArray<NSString *> *propList; @property (nonatomic, copy) NSArray<NSString *> *propList;
- (void)setBoundingBox:(CGContextRef)context; - (void)setBoundingBox:(CGRect)boundingBox;
- (CGFloat)getWidthRelatedValue:(NSString *)string; - (CGFloat)getWidthRelatedValue:(NSString *)string;
- (CGFloat)getHeightRelatedValue:(NSString *)string; - (CGFloat)getHeightRelatedValue:(NSString *)string;
- (CGFloat)getContextWidth; - (CGFloat)getContextWidth;

View File

@@ -205,11 +205,11 @@
} }
} }
- (void)setBoundingBox:(CGContextRef)context - (void)setBoundingBox:(CGRect)boundingBox
{ {
_boundingBox = CGContextGetClipBoundingBox(context); _boundingBox = boundingBox;
_widthConverter = [[RNSVGPercentageConverter alloc] initWithRelativeAndOffset:CGRectGetWidth(_boundingBox) offset:0]; _widthConverter = [[RNSVGPercentageConverter alloc] initWithRelativeAndOffset:boundingBox.size.width offset:0];
_heightConverter = [[RNSVGPercentageConverter alloc] initWithRelativeAndOffset:CGRectGetHeight(_boundingBox) offset:0]; _heightConverter = [[RNSVGPercentageConverter alloc] initWithRelativeAndOffset:boundingBox.size.height offset:0];
} }
- (CGFloat)getWidthRelatedValue:(NSString *)string - (CGFloat)getWidthRelatedValue:(NSString *)string

View File

@@ -20,4 +20,6 @@
@property (nonatomic, strong) NSString *width; @property (nonatomic, strong) NSString *width;
@property (nonatomic, strong) NSString *height; @property (nonatomic, strong) NSString *height;
- (CGAffineTransform)getTransform;
@end @end

View File

@@ -70,9 +70,15 @@
} }
- (void)renderTo:(CGContextRef)context - (void)renderTo:(CGContextRef)context
{
[self setBoundingBox:CGContextGetClipBoundingBox(context)];
self.matrix = [self getTransform];
[super renderTo:context];
}
- (CGAffineTransform)getTransform
{ {
// based on https://svgwg.org/svg2-draft/coords.html#ComputingAViewportsTransform // based on https://svgwg.org/svg2-draft/coords.html#ComputingAViewportsTransform
[self setBoundingBox:context];
// Let vb-x, vb-y, vb-width, vb-height be the min-x, min-y, width and height values of the viewBox attribute respectively. // Let vb-x, vb-y, vb-width, vb-height be the min-x, min-y, width and height values of the viewBox attribute respectively.
CGFloat vbX = [self getWidthRelatedValue:self.minX]; CGFloat vbX = [self getWidthRelatedValue:self.minX];
@@ -150,9 +156,8 @@
} }
} }
self.matrix = CGAffineTransformMakeScale(scaleX, scaleY); CGAffineTransform transform = CGAffineTransformMakeScale(scaleX, scaleY);
self.matrix = CGAffineTransformTranslate(self.matrix, -translateX * (_fromSymbol ? scaleX : 1), -translateY * (_fromSymbol ? scaleY : 1)); return CGAffineTransformTranslate(transform, -translateX * (_fromSymbol ? scaleX : 1), -translateY * (_fromSymbol ? scaleY : 1));
[super renderTo:context];
} }
- (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray<NSString *> *)mergeList - (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray<NSString *> *)mergeList

View File

@@ -40,7 +40,7 @@
- (CGPathRef)getPath:(CGContextRef)context - (CGPathRef)getPath:(CGContextRef)context
{ {
[self setBoundingBox:context]; [self setBoundingBox:CGContextGetClipBoundingBox(context)];
CGMutablePathRef path = CGPathCreateMutable(); CGMutablePathRef path = CGPathCreateMutable();
RNSVGPercentageConverter* convert = [[RNSVGPercentageConverter alloc] init]; RNSVGPercentageConverter* convert = [[RNSVGPercentageConverter alloc] init];
CGFloat cx = [self getWidthRelatedValue:self.cx]; CGFloat cx = [self getWidthRelatedValue:self.cx];

View File

@@ -49,7 +49,7 @@
- (CGPathRef)getPath:(CGContextRef)context - (CGPathRef)getPath:(CGContextRef)context
{ {
[self setBoundingBox:context]; [self setBoundingBox:CGContextGetClipBoundingBox(context)];
CGMutablePathRef path = CGPathCreateMutable(); CGMutablePathRef path = CGPathCreateMutable();
CGFloat cx = [self getWidthRelatedValue:self.cx]; CGFloat cx = [self getWidthRelatedValue:self.cx];
CGFloat cy = [self getHeightRelatedValue:self.cy]; CGFloat cy = [self getHeightRelatedValue:self.cy];

View File

@@ -49,7 +49,7 @@
- (CGPathRef)getPath:(CGContextRef)context - (CGPathRef)getPath:(CGContextRef)context
{ {
[self setBoundingBox:context]; [self setBoundingBox:CGContextGetClipBoundingBox(context)];
CGMutablePathRef path = CGPathCreateMutable(); CGMutablePathRef path = CGPathCreateMutable();
CGFloat x1 = [self getWidthRelatedValue:self.x1]; CGFloat x1 = [self getWidthRelatedValue:self.x1];
CGFloat y1 = [self getHeightRelatedValue:self.y1]; CGFloat y1 = [self getHeightRelatedValue:self.y1];

View File

@@ -67,7 +67,7 @@
- (CGPathRef)getPath:(CGContextRef)context - (CGPathRef)getPath:(CGContextRef)context
{ {
[self setBoundingBox:context]; [self setBoundingBox:CGContextGetClipBoundingBox(context)];
CGMutablePathRef path = CGPathCreateMutable(); CGMutablePathRef path = CGPathCreateMutable();
CGFloat x = [self getWidthRelatedValue:self.x]; CGFloat x = [self getWidthRelatedValue:self.x];
CGFloat y = [self getHeightRelatedValue:self.y]; CGFloat y = [self getHeightRelatedValue:self.y];

View File

@@ -25,5 +25,7 @@ RCT_EXPORT_VIEW_PROPERTY(y, NSString)
RCT_EXPORT_VIEW_PROPERTY(width, NSString) RCT_EXPORT_VIEW_PROPERTY(width, NSString)
RCT_EXPORT_VIEW_PROPERTY(height, NSString) RCT_EXPORT_VIEW_PROPERTY(height, NSString)
RCT_EXPORT_VIEW_PROPERTY(src, id) RCT_EXPORT_VIEW_PROPERTY(src, id)
RCT_EXPORT_VIEW_PROPERTY(align, NSString)
RCT_EXPORT_VIEW_PROPERTY(meetOrSlice, RNSVGVBMOS)
@end @end

View File

@@ -160,7 +160,9 @@ const ImageAttributes = merge({
y: true, y: true,
width: true, width: true,
height: true, height: true,
src: true src: true,
align: true,
meetOrSlice: true
}, RenderableAttributes); }, RenderableAttributes);
const LineAttributes = merge({ const LineAttributes = merge({