mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-05-29 13:21:50 +00:00
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:
@@ -9,12 +9,16 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "RNSVGRenderable.h"
|
||||
#import "RNSVGVBMOS.h"
|
||||
|
||||
@interface RNSVGImage : RNSVGRenderable
|
||||
|
||||
@property (nonatomic, assign) id src;
|
||||
@property (nonatomic, strong) NSString* x;
|
||||
@property (nonatomic, strong) NSString* y;
|
||||
@property (nonatomic, strong) NSString* width;
|
||||
@property (nonatomic, strong) NSString* height;
|
||||
@property (nonatomic, strong) NSString *align;
|
||||
@property (nonatomic, assign) RNSVGVBMOS meetOrSlice;
|
||||
|
||||
@end
|
||||
|
||||
@@ -7,12 +7,15 @@
|
||||
*/
|
||||
|
||||
#import "RNSVGImage.h"
|
||||
#import "RCTImageSource.h"
|
||||
#import "RCTConvert+RNSVG.h"
|
||||
#import "RCTLog.h"
|
||||
#import "RNSVGViewBox.h"
|
||||
|
||||
@implementation RNSVGImage
|
||||
{
|
||||
CGImageRef image;
|
||||
CGImageRef _image;
|
||||
CGFloat _imageRatio;
|
||||
}
|
||||
|
||||
- (void)setSrc:(id)src
|
||||
@@ -21,8 +24,10 @@
|
||||
return;
|
||||
}
|
||||
_src = src;
|
||||
CGImageRelease(image);
|
||||
image = CGImageRetain([RCTConvert CGImage:src]);
|
||||
CGImageRelease(_image);
|
||||
RCTImageSource *source = [RCTConvert RCTImageSource:src];
|
||||
_imageRatio = source.size.width / source.size.height;
|
||||
_image = CGImageRetain([RCTConvert CGImage:src]);
|
||||
[self invalidate];
|
||||
}
|
||||
|
||||
@@ -62,29 +67,80 @@
|
||||
_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
|
||||
{
|
||||
CGImageRelease(image);
|
||||
CGImageRelease(_image);
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
CGRect rect = [self getRect:context];
|
||||
// add hit area
|
||||
self.hitArea = CGPathCreateWithRect(rect, nil);
|
||||
self.hitArea = CFAutorelease(CGPathCreateWithRect(rect, nil));
|
||||
[self clip:context];
|
||||
|
||||
CGContextSaveGState(context);
|
||||
CGContextTranslateCTM(context, 0, rect.size.height);
|
||||
CGContextScaleCTM(context, 1.0, -1.0);
|
||||
CGContextDrawImage(context, rect, image);
|
||||
CGContextTranslateCTM(context, 0, rect.size.height + 2 * rect.origin.y);
|
||||
CGContextScaleCTM(context, 1, -1);
|
||||
|
||||
// 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);
|
||||
|
||||
}
|
||||
|
||||
- (CGRect)getRect:(CGContextRef)context
|
||||
{
|
||||
[self setBoundingBox:context];
|
||||
[self setBoundingBox:CGContextGetClipBoundingBox(context)];
|
||||
CGFloat x = [self getWidthRelatedValue:self.x];
|
||||
CGFloat y = [self getHeightRelatedValue:self.y];
|
||||
CGFloat width = [self getWidthRelatedValue:self.width];
|
||||
|
||||
Reference in New Issue
Block a user