From 0b887bccf5a5af41aa3bdb7a6172046651663156 Mon Sep 17 00:00:00 2001 From: Horcrux Date: Thu, 5 May 2016 18:50:22 +0800 Subject: [PATCH] add Image element (iOS) --- Example/examples.js | 4 +- Example/examples/Image.js | 83 ++++++++++++++++++ Example/image.jpg | Bin 0 -> 13303 bytes Example/main.js | 2 +- elements/Image.js | 34 +++++-- elements/Shape.js | 8 +- ios/RNSVG.xcodeproj/project.pbxproj | 12 +++ ios/RNSVGImage.h | 19 ++++ ios/RNSVGImage.m | 67 ++++++++++++++ ios/RNSVGRenderable.h | 2 + ios/RNSVGRenderable.m | 11 +++ ios/RNSVGShape.h | 2 + ios/RNSVGShape.m | 7 +- ios/ViewManagers/RNSVGImageManager.h | 13 +++ ios/ViewManagers/RNSVGImageManager.m | 26 ++++++ lib/SerializablePath.js | 79 +++++------------ lib/attributes.js | 15 +++- lib/extract/extractProps.js | 2 +- ...zableShape.js => formatPercentageProps.js} | 20 ++--- 19 files changed, 308 insertions(+), 98 deletions(-) create mode 100644 Example/examples/Image.js create mode 100644 Example/image.jpg create mode 100644 ios/RNSVGImage.h create mode 100644 ios/RNSVGImage.m create mode 100644 ios/ViewManagers/RNSVGImageManager.h create mode 100644 ios/ViewManagers/RNSVGImageManager.m rename lib/{SerializableShape.js => formatPercentageProps.js} (68%) diff --git a/Example/examples.js b/Example/examples.js index d9992710..e8f46b19 100644 --- a/Example/examples.js +++ b/Example/examples.js @@ -13,6 +13,7 @@ import * as Use from './examples/Use'; import * as Symbol from './examples/Symbol'; import * as Gradients from './examples/Gradients'; import * as Clipping from './examples/Clipping'; +import * as Image from './examples/Image'; export { Svg, @@ -29,5 +30,6 @@ export { Use, Symbol, Gradients, - Clipping + Clipping, + Image }; diff --git a/Example/examples/Image.js b/Example/examples/Image.js new file mode 100644 index 00000000..c8772147 --- /dev/null +++ b/Example/examples/Image.js @@ -0,0 +1,83 @@ +import React, { + Component +} from 'react-native'; + +import Svg, { + Image, + Defs, + Circle, + ClipPath, + Text +} from 'react-native-svg'; + +class ImageExample extends Component{ + static title = 'Image'; + + render() { + return + + ; + } +} + +class ClipImage extends Component{ + static title = 'Clip Image'; + + render() { + return + + + + + + + HOGWARTS + ; + } +} + +const icon = + +; + +const samples = [ImageExample, ClipImage]; + +export { + icon, + samples +}; diff --git a/Example/image.jpg b/Example/image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8fddd5c17f4898a99fa0f4d295f11b7c225d4988 GIT binary patch literal 13303 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 } } +let RNSVGImage = createReactNativeComponentClass({ + validAttributes: ImageAttributes, + uiViewClassName: 'RNSVGImage' +}); + + export default Image; diff --git a/elements/Shape.js b/elements/Shape.js index 9a1b7eb3..a3319bba 100644 --- a/elements/Shape.js +++ b/elements/Shape.js @@ -1,11 +1,11 @@ import React, { Component } from 'react-native'; -import './Path'; // must import Path first, don`t know why. without this will throw an `Super expression must either be null or a function, not undefined`, maybe cyclic dependencies issue +import './Path'; // must import Path first, don`t know why. without this will throw an `Super expression must either be null or a function, not undefined` import _ from 'lodash'; import extractProps from '../lib/extract/extractProps'; import {ShapeAttributes} from '../lib/attributes'; -import SerializableShape from '../lib/SerializableShape'; +import formatPercentageProps from '../lib/formatPercentageProps'; import createReactNativeComponentClass from 'react-native/Libraries/ReactNative/createReactNativeComponentClass'; import {circleProps, ellipseProps, lineProps, rectProps} from '../lib/props'; @@ -55,8 +55,6 @@ class Shape extends Component{ }); } - let shape = new SerializableShape(props, COORD_PROPS[this.type]).toJSON(); - return ; diff --git a/ios/RNSVG.xcodeproj/project.pbxproj b/ios/RNSVG.xcodeproj/project.pbxproj index ec2ad54f..43856bf4 100644 --- a/ios/RNSVG.xcodeproj/project.pbxproj +++ b/ios/RNSVG.xcodeproj/project.pbxproj @@ -21,6 +21,8 @@ 0CF68B121AF0549300FF9E5C /* RNSVGNodeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFC1AF0549300FF9E5C /* RNSVGNodeManager.m */; }; 0CF68B131AF0549300FF9E5C /* RNSVGRenderableManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFE1AF0549300FF9E5C /* RNSVGRenderableManager.m */; }; 0CF68B161AF0549300FF9E5C /* RNSVGTextManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B041AF0549300FF9E5C /* RNSVGTextManager.m */; }; + 108FD88C1CDAF09B00A65FB3 /* RNSVGImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 108FD88B1CDAF09B00A65FB3 /* RNSVGImageManager.m */; }; + 108FD88F1CDAF0A300A65FB3 /* RNSVGImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 108FD88E1CDAF0A300A65FB3 /* RNSVGImage.m */; }; 10A062FE1CC732020000CEEF /* RNSVGPathManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10A062FB1CC732020000CEEF /* RNSVGPathManager.m */; }; 10A062FF1CC732020000CEEF /* RNSVGSvgViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10A062FD1CC732020000CEEF /* RNSVGSvgViewManager.m */; }; 10A063041CC7320C0000CEEF /* RNSVGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 10A063011CC7320C0000CEEF /* RNSVGPath.m */; }; @@ -74,6 +76,10 @@ 0CF68AFE1AF0549300FF9E5C /* RNSVGRenderableManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGRenderableManager.m; sourceTree = ""; }; 0CF68B031AF0549300FF9E5C /* RNSVGTextManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGTextManager.h; sourceTree = ""; }; 0CF68B041AF0549300FF9E5C /* RNSVGTextManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGTextManager.m; sourceTree = ""; }; + 108FD88A1CDAF09B00A65FB3 /* RNSVGImageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGImageManager.h; sourceTree = ""; }; + 108FD88B1CDAF09B00A65FB3 /* RNSVGImageManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGImageManager.m; sourceTree = ""; }; + 108FD88D1CDAF0A300A65FB3 /* RNSVGImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGImage.h; sourceTree = ""; }; + 108FD88E1CDAF0A300A65FB3 /* RNSVGImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGImage.m; sourceTree = ""; }; 10A062FA1CC732020000CEEF /* RNSVGPathManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGPathManager.h; sourceTree = ""; }; 10A062FB1CC732020000CEEF /* RNSVGPathManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGPathManager.m; sourceTree = ""; }; 10A062FC1CC732020000CEEF /* RNSVGSvgViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGSvgViewManager.h; sourceTree = ""; }; @@ -112,6 +118,8 @@ 0CF68ADE1AF0549300FF9E5C /* RNSVGGroup.m */, 10C068641CCF0F87007C6982 /* RNSVGShape.h */, 10C068651CCF0F87007C6982 /* RNSVGShape.m */, + 108FD88D1CDAF0A300A65FB3 /* RNSVGImage.h */, + 108FD88E1CDAF0A300A65FB3 /* RNSVGImage.m */, 10A063001CC7320C0000CEEF /* RNSVGPath.h */, 10A063011CC7320C0000CEEF /* RNSVGPath.m */, 0CF68ADF1AF0549300FF9E5C /* RNSVGNode.h */, @@ -157,6 +165,8 @@ 0CF68AF81AF0549300FF9E5C /* ViewManagers */ = { isa = PBXGroup; children = ( + 108FD88A1CDAF09B00A65FB3 /* RNSVGImageManager.h */, + 108FD88B1CDAF09B00A65FB3 /* RNSVGImageManager.m */, 10C068681CCF1061007C6982 /* RNSVGShapeManager.h */, 10C068691CCF1061007C6982 /* RNSVGShapeManager.m */, 10A062FA1CC732020000CEEF /* RNSVGPathManager.h */, @@ -240,11 +250,13 @@ 0CF68B051AF0549300FF9E5C /* RNSVGGroup.m in Sources */, 10A062FF1CC732020000CEEF /* RNSVGSvgViewManager.m in Sources */, 0CF68B131AF0549300FF9E5C /* RNSVGRenderableManager.m in Sources */, + 108FD88F1CDAF0A300A65FB3 /* RNSVGImage.m in Sources */, 0CF68B0E1AF0549300FF9E5C /* RNSVGRadialGradient.m in Sources */, 10A063051CC7320C0000CEEF /* RNSVGSvgView.m in Sources */, 0CF68B071AF0549300FF9E5C /* RNSVGRenderable.m in Sources */, 0CF68B101AF0549300FF9E5C /* RCTConvert+RNSVG.m in Sources */, 10C0686A1CCF1061007C6982 /* RNSVGShapeManager.m in Sources */, + 108FD88C1CDAF09B00A65FB3 /* RNSVGImageManager.m in Sources */, 10A062FE1CC732020000CEEF /* RNSVGPathManager.m in Sources */, 0CF68B061AF0549300FF9E5C /* RNSVGNode.m in Sources */, 0CF68B0F1AF0549300FF9E5C /* RNSVGSolidColor.m in Sources */, diff --git a/ios/RNSVGImage.h b/ios/RNSVGImage.h new file mode 100644 index 00000000..6ffb0f7d --- /dev/null +++ b/ios/RNSVGImage.h @@ -0,0 +1,19 @@ +/** + * 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. + */ + +#import + +#import "RNSVGRenderable.h" + +@interface RNSVGImage : RNSVGRenderable +@property (nonatomic, strong) NSDictionary* layout; +@property (nonatomic, assign) id src; + +- (CGFloat)getActualProp:(NSString *)name relative:(float)relative; + +@end diff --git a/ios/RNSVGImage.m b/ios/RNSVGImage.m new file mode 100644 index 00000000..2e67f96a --- /dev/null +++ b/ios/RNSVGImage.m @@ -0,0 +1,67 @@ +/** + * 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. + */ + +#import "RNSVGImage.h" +#import "RCTConvert+RNSVG.h" +#import "RCTLog.h" + +@implementation RNSVGImage +{ + CGImageRef image; +} +- (void)setSrc:(id)src +{ + if (src == _src) { + return; + } + _src = src; + CGImageRelease(image); + image = CGImageRetain([RCTConvert CGImage:src]); + [self invalidate]; +} + +- (void)setLayout:(NSDictionary *)layout +{ + if (layout == _layout) { + return; + } + _layout = layout; + [self invalidate]; +} + +- (void)dealloc +{ + CGImageRelease(image); +} + +- (void)renderLayerTo:(CGContextRef)context +{ + CGRect box = CGContextGetClipBoundingBox(context); + float height = CGRectGetHeight(box); + float width = CGRectGetWidth(box); + + CGFloat x = [self getActualProp:@"x" relative:width]; + CGFloat y = [self getActualProp:@"y" relative:height]; + CGFloat w = [self getActualProp:@"width" relative:width]; + CGFloat h = [self getActualProp:@"height" relative:height]; + [self clip:context]; + CGContextSaveGState(context); + CGContextTranslateCTM(context, 0, h); + CGContextScaleCTM(context, 1.0, -1.0); + CGContextDrawImage(context, CGRectMake(x, -y, w, h), image); + CGContextRestoreGState(context); +} + +- (CGFloat)getActualProp:(NSString *)name relative:(float)relative +{ + NSDictionary *prop = [self.layout objectForKey:name]; + return [super getActualProp:prop relative:relative]; + +} + +@end diff --git a/ios/RNSVGRenderable.h b/ios/RNSVGRenderable.h index c941e081..490dd122 100644 --- a/ios/RNSVGRenderable.h +++ b/ios/RNSVGRenderable.h @@ -24,4 +24,6 @@ @property (nonatomic, assign) RNSVGCGFloatArray strokeDasharray; @property (nonatomic, assign) CGFloat strokeDashoffset; +- (CGFloat)getActualProp:(NSDictionary *) prop relative:(float)relative; + @end diff --git a/ios/RNSVGRenderable.m b/ios/RNSVGRenderable.m index 1d3b324b..6e1b9431 100644 --- a/ios/RNSVGRenderable.m +++ b/ios/RNSVGRenderable.m @@ -81,6 +81,17 @@ CGContextRestoreGState(context); } +- (CGFloat)getActualProp:(NSDictionary *) prop relative:(float)relative +{ + CGFloat value = [[prop objectForKey:@"value"] floatValue]; + if ([[prop objectForKey:@"percentage"] integerValue] == 1) { + return relative * value; + } else { + return value; + } +} + + - (void)renderLayerTo:(CGContextRef)context { // abstract diff --git a/ios/RNSVGShape.h b/ios/RNSVGShape.h index 17a28727..bdf815fe 100644 --- a/ios/RNSVGShape.h +++ b/ios/RNSVGShape.h @@ -14,4 +14,6 @@ @interface RNSVGShape : RNSVGPath @property (nonatomic, strong) NSDictionary* shape; +- (CGFloat)getActualProp:(NSString *)name relative:(float)relative; + @end diff --git a/ios/RNSVGShape.m b/ios/RNSVGShape.m index 38702d32..1fd30bf2 100644 --- a/ios/RNSVGShape.m +++ b/ios/RNSVGShape.m @@ -112,12 +112,7 @@ - (CGFloat)getActualProp:(NSString *)name relative:(float)relative { NSDictionary *prop = [self.shape objectForKey:name]; - CGFloat value = [[prop objectForKey:@"value"] floatValue]; - if ([[prop objectForKey:@"percentage"] integerValue] == 1) { - return relative * value; - } else { - return value; - } + return [super getActualProp:prop relative:relative]; } @end diff --git a/ios/ViewManagers/RNSVGImageManager.h b/ios/ViewManagers/RNSVGImageManager.h new file mode 100644 index 00000000..c799d3e5 --- /dev/null +++ b/ios/ViewManagers/RNSVGImageManager.h @@ -0,0 +1,13 @@ +/** + * 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. + */ + +#import "RNSVGRenderableManager.h" + +@interface RNSVGImageManager : RNSVGRenderableManager + +@end diff --git a/ios/ViewManagers/RNSVGImageManager.m b/ios/ViewManagers/RNSVGImageManager.m new file mode 100644 index 00000000..1284602a --- /dev/null +++ b/ios/ViewManagers/RNSVGImageManager.m @@ -0,0 +1,26 @@ +/** + * 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. + */ + +#import "RNSVGImageManager.h" + +#import "RNSVGImage.h" +#import "RCTConvert+RNSVG.h" + +@implementation RNSVGImageManager + +RCT_EXPORT_MODULE() + +- (RNSVGRenderable *)node +{ + return [RNSVGImage new]; +} + +RCT_EXPORT_VIEW_PROPERTY(layout, NSDictionary) +RCT_EXPORT_VIEW_PROPERTY(src, id) + +@end diff --git a/lib/SerializablePath.js b/lib/SerializablePath.js index 0577e84d..b69cc518 100644 --- a/lib/SerializablePath.js +++ b/lib/SerializablePath.js @@ -17,7 +17,6 @@ export default class SerializablePath { } /* parser */ - push = () => { let p = Array.prototype.join.call(arguments, ' ') .replace(/(\.[\d]+)(\-?\.)/ig, '$1,$2') //-.3-.575 => -.3,-.575 @@ -33,65 +32,27 @@ export default class SerializablePath { while (cmd){ switch (cmd){ - case 'm': - this.move(p[i++], p[i++]); - break; - case 'l': - this.line(p[i++], p[i++]); - break; - case 'c': - this.curve(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); - break; - case 's': - this.curve(p[i++], p[i++], null, null, p[i++], p[i++]); - break; - case 'q': - this.curve(p[i++], p[i++], p[i++], p[i++]); - break; - case 't': - this.curve(p[i++], p[i++]); - break; - case 'a': - this.arc(p[i + 5], p[i + 6], p[i], p[i + 1], p[i + 3], !+p[i + 4], p[i + 2]); i += 7; - break; - case 'h': - this.line(p[i++], 0); - break; - case 'v': - this.line(0, p[i++]); - break; + case 'm': this.move(p[i++], p[i++]); break; + case 'l': this.line(p[i++], p[i++]); break; + case 'c': this.curve(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break; + case 's': this.curve(p[i++], p[i++], null, null, p[i++], p[i++]); break; + case 'q': this.curve(p[i++], p[i++], p[i++], p[i++]); break; + case 't': this.curve(p[i++], p[i++]); break; + case 'a': this.arc(p[i + 5], p[i + 6], p[i], p[i + 1], p[i + 3], !+p[i + 4], p[i + 2]); i += 7; break; + case 'h': this.line(p[i++], 0); break; + case 'v': this.line(0, p[i++]); break; - case 'M': - this.moveTo(p[i++], p[i++]); - break; - case 'L': - this.lineTo(p[i++], p[i++]); - break; - case 'C': - this.curveTo(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); - break; - case 'S': - this.curveTo(p[i++], p[i++], null, null, p[i++], p[i++]); - break; - case 'Q': - this.curveTo(p[i++], p[i++], p[i++], p[i++]); - break; - case 'T': - this.curveTo(p[i++], p[i++]); - break; - case 'A': - this.arcTo(p[i + 5], p[i + 6], p[i], p[i + 1], p[i + 3], !+p[i + 4], p[i + 2]); i += 7; - break; - case 'H': - this.lineTo(p[i++], this.penY); - break; - case 'V': - this.lineTo(this.penX, p[i++]); - break; - case 'Z': - case 'z': - this.close(); - break; + case 'M': this.moveTo(p[i++], p[i++]); break; + case 'L': this.lineTo(p[i++], p[i++]); break; + case 'C': this.curveTo(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break; + case 'S': this.curveTo(p[i++], p[i++], null, null, p[i++], p[i++]); break; + case 'Q': this.curveTo(p[i++], p[i++], p[i++], p[i++]); break; + case 'T': this.curveTo(p[i++], p[i++]); break; + case 'A': this.arcTo(p[i + 5], p[i + 6], p[i], p[i + 1], p[i + 3], !+p[i + 4], p[i + 2]); i += 7; break; + case 'H': this.lineTo(p[i++], this.penY); break; + case 'V': this.lineTo(this.penX, p[i++]); break; + + case 'Z': case 'z': this.close(); break; default: cmd = last; i--; diff --git a/lib/attributes.js b/lib/attributes.js index e982e5e9..d5cf4ecb 100644 --- a/lib/attributes.js +++ b/lib/attributes.js @@ -15,7 +15,7 @@ function arrayDiffer(a, b) { return false; } -function shapeDiffer(a, b) { +function percentageDiffer(a, b) { if (a === b) { return false; } @@ -111,15 +111,24 @@ const TextAttributes = { const ShapeAttributes = { shape: { - diff: shapeDiffer + diff: percentageDiffer }, ...RenderableAttributes }; +const ImageAttributes = { + ...NodeAttributes, + layout: { + diff: percentageDiffer + }, + src: true +}; + export { GroupAttributes, PathAttributes, TextAttributes, - ShapeAttributes + ShapeAttributes, + ImageAttributes }; diff --git a/lib/extract/extractProps.js b/lib/extract/extractProps.js index 355ce61f..bd58553a 100644 --- a/lib/extract/extractProps.js +++ b/lib/extract/extractProps.js @@ -4,7 +4,7 @@ import extractTransform from './extractTransform'; import extractClipping from './extractClipping'; import _ from 'lodash'; -export default function(props, options = {stroke: true, join: true, transform: true, fill: true}) { +export default function(props, options = {stroke: true, transform: true, fill: true}) { if (props.visible === false) { return { opacity: 0 diff --git a/lib/SerializableShape.js b/lib/formatPercentageProps.js similarity index 68% rename from lib/SerializableShape.js rename to lib/formatPercentageProps.js index fca9af43..ddc74156 100644 --- a/lib/SerializableShape.js +++ b/lib/formatPercentageProps.js @@ -38,18 +38,12 @@ function percentageTransform(value) { }; } -export default class { - constructor(props, list) { - this.shape = {}; - list.forEach(name => { - if (!_.isNil(props[name])) { - this.shape[name] = percentageTransform(props[name]); - } - }); - } +export default function (props, list) { + return _.reduce(list, (prev, name) => { + if (!_.isNil(props[name])) { + prev[name] = percentageTransform(props[name]); + } - toJSON = () => { - return this.shape; - }; + return prev; + }, {}); } -