finish gradients refactor

This commit is contained in:
Horcrux
2016-07-20 22:38:45 +08:00
parent 18e1b60823
commit ff2395bcc2
64 changed files with 804 additions and 605 deletions

View File

@@ -18,5 +18,22 @@ import * as Definations from './examples/Definations';
import * as TouchEvents from './examples/TouchEvents';
export {
Svg,
Rect,
Circle,
Ellipse,
Line,
Polygon,
Polyline,
Path,
Text,
Stroking,
G,
//Use,
//Symbol,
Gradients,
Clipping,
Image,
TouchEvents,
Definations
};

View File

@@ -9,7 +9,10 @@ import Svg, {
Use,
Rect,
Circle,
ClipPath
ClipPath,
LinearGradient,
RadialGradient,
Stop
} from 'react-native-svg';
class DefsExample extends Component{
@@ -27,10 +30,21 @@ class DefsExample extends Component{
<ClipPath id="clip">
<Circle r="20%" cx="0" cy="0" />
</ClipPath>
<LinearGradient id="linear" x1="0%" y1="0%" x2="100%" y2="0%">
<Stop offset="0%" stopColor="yellow" />
<Stop offset="50%" stopColor="red" />
<Stop offset="100%" stopColor="blue" />
</LinearGradient>
<RadialGradient id="radial" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
<Stop offset="0%" stopColor="yellow" />
<Stop offset="50%" stopColor="red" />
<Stop offset="100%" stopColor="blue" />
</RadialGradient>
</Defs>
<Use href="url(#path)" x="0" fill="blue" opacity="0.5" />
<Use href="url(#path)" x="20" y="5" fill="#8a3" />
<Use href="url(#path)" x="30" clipPath="url(#clip)" />
<Use href="url(#path)" x="0" fill="blue" opacity="0.2" />
<Use href="url(#path)" x="20" y="5" fill="url(#linear)" />
<Use href="url(#path)" x="50" clipPath="url(#clip)" fillOpacity="0.6" />
<Use href="url(#path)" x="-10" y="20" fill="red" fill="url(#radial)" />
</Svg>;
}
}

View File

@@ -19,7 +19,6 @@ class GExample extends Component{
width="100"
>
<G
r="11"
fill="purple"
stroke="pink"
strokeWidth="3"
@@ -28,26 +27,31 @@ class GExample extends Component{
<Circle
cx="25"
cy="25"
r="11"
/>
</G>
<Circle
cx="25"
cy="75"
r="11"
stroke="red"
/>
<Circle
cx="50"
cy="50"
r="11"
fill="green"
/>
<Circle
cx="75"
cy="25"
r="11"
stroke="red"
/>
<Circle
cx="75"
cy="75"
r="11"
/>
</G>
</Svg>;
@@ -92,7 +96,7 @@ class GTransform extends Component{
>
Text grouped with shapes</Text>
</G>
<Use href="#group" x="5" rotate="0" />
<Use href="url(#group)" x="5" rotate="0" />
</Svg>;
}
}

View File

@@ -111,8 +111,8 @@ const styles = StyleSheet.create({
}
});
//const names = ['Svg', 'Stroking', 'Path', 'Line', 'Rect', 'Polygon', 'Polyline', 'Circle', 'Ellipse', 'G', 'Text', 'Use', 'Symbol', 'Gradients', 'Clipping', 'Image', 'TouchEvents'];
const names = ['Definations'];
const names = ['Svg', 'Stroking', 'Path', 'Line', 'Rect', 'Polygon', 'Polyline', 'Circle', 'Ellipse', 'G', 'Text', 'Use', 'Symbol', 'Gradients', 'Clipping', 'Image', 'TouchEvents'];
//const names = ['Definations'];
class SvgExample extends Component {
constructor() {

View File

@@ -1,16 +1,17 @@
import React, {PropTypes} from 'react';
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
import Shape from './Shape';
import mergeContext from '../lib/mergeContext';
import {CircleAttributes} from '../lib/attributes';
import {circleProps, pathProps, fillProps, strokeProps, numberProp} from '../lib/props';
import {pathProps, numberProp} from '../lib/props';
class Circle extends Shape {
static displayName = 'Circle';
static propTypes = {
...pathProps,
...circleProps
cx: numberProp.isRequired,
cy: numberProp.isRequired,
r: numberProp.isRequired
};
static defaultProps = {
@@ -24,7 +25,7 @@ class Circle extends Shape {
};
render() {
let props = mergeContext(this.props, this.context);
let props = this.props;
return <RNSVGCircle
ref={ele => this.root = ele}
{...this.extractProps(props)}

View File

@@ -1,8 +1,7 @@
import React, {PropTypes} from 'react';
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
import mergeContext from '../lib/mergeContext';
import Shape from './Shape';
import {ellipseProps, pathProps, fillProps, strokeProps, numberProp} from '../lib/props';
import {pathProps, numberProp} from '../lib/props';
import {EllipseAttributes} from '../lib/attributes';
class Ellipse extends Shape{
@@ -10,7 +9,10 @@ class Ellipse extends Shape{
static propTypes = {
...pathProps,
...ellipseProps
cx: numberProp.isRequired,
cy: numberProp.isRequired,
rx: numberProp.isRequired,
ry: numberProp.isRequired
};
static defaultProps = {
@@ -25,7 +27,7 @@ class Ellipse extends Shape{
};
render() {
let props = mergeContext(this.props, this.context);
let props = this.props;
return <RNSVGEllipse
ref={ele => this.root = ele}
{...this.extractProps(props)}

View File

@@ -1,29 +1,14 @@
import React, {Children, Component} from 'react';
import {NativeGroup} from './G';
import {set, remove} from '../lib/extract/patterns';
import percentToFloat from '../lib/percentToFloat';
import Stop from './Stop';
import Color from 'color';
import extractOpacity from '../lib/extract/extractOpacity';
import _ from 'lodash';
class Gradient extends Component{
static displayName = 'Gradient';
constructor() {
super(...arguments);
this.id = this.props.id + ':' + this.props.svgId;
}
componentWillReceiveProps = nextProps => {
let id = nextProps.id + ':' + nextProps.svgId;
if (id !== this.id) {
remove(this.id);
}
};
componentWillUnmount = () => {
remove(this.id);
};
render(generator) {
getGradient = () => {
let stops = {};
Children.forEach(this.props.children, child => {
if (child.type === Stop) {
@@ -32,15 +17,29 @@ class Gradient extends Component{
let offset = percentToFloat(child.props.offset);
// add stop
stops[offset] = Color(child.props.stopColor).alpha(+child.props.stopOpacity);
set(this.id, generator.bind(null, stops));
stops[offset] = Color(child.props.stopColor).alpha(extractOpacity(child.props.stopOpacity));
}
} else {
console.warn(`'Gradient' can only receive 'Stop' elements as children`);
}
});
return <NativeGroup />;
}
let sorted = _.sortBy(_.map(stops, (stop, offset) => {
return {stop, offset};
}), 'offset');
let gradient = [];
sorted.forEach(({stop}) => {
let channels = stop.rgbaArray();
gradient.push(channels[0] / 255);
gradient.push(channels[1] / 255);
gradient.push(channels[2] / 255);
gradient.push(channels[3]);
});
gradient.push(...sorted.map(({offset}) => +offset));
return gradient;
};
}
export default Gradient;

View File

@@ -9,13 +9,13 @@ import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'
class Image extends Shape {
static displayName = 'Image';
static propTypes = {
...responderProps,
...touchableProps,
x: numberProp,
y: numberProp,
width: numberProp.isRequired,
height: numberProp.isRequired,
href: PropTypes.number.isRequired,
...responderProps,
...touchableProps
href: PropTypes.number.isRequired
//preserveAspectRatio: PropTypes.string
};

View File

@@ -1,16 +1,18 @@
import React, {PropTypes} from 'react';
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
import {LineAttributes} from '../lib/attributes';
import mergeContext from '../lib/mergeContext';
import Shape from './Shape';
import {lineProps, pathProps, fillProps, strokeProps, numberProp} from '../lib/props';
import {pathProps, numberProp} from '../lib/props';
class Line extends Shape {
static displayName = 'Line';
static propTypes = {
...pathProps,
...lineProps
x1: numberProp.isRequired,
x2: numberProp.isRequired,
y1: numberProp.isRequired,
y2: numberProp.isRequired
};
static defaultProps = {
@@ -25,7 +27,7 @@ class Line extends Shape {
};
render() {
let props = mergeContext(this.props, this.context);
let props = this.props;
return <RNSVGLine
ref={ele => this.root = ele}
{...this.extractProps(props)}

View File

@@ -1,41 +1,44 @@
import {PropTypes} from 'react';
import stopsOpacity from '../lib/stopsOpacity';
import React, {PropTypes} from 'react';
import {numberProp} from '../lib/props';
import Gradient from './Gradient';
import {LINEAR_GRADIENT} from '../lib/extract/extractBrush';
import insertColorStopsIntoArray from '../lib/insertProcessor';
function LinearGradientGenerator(stops, x1, y1, x2, y2) {
let brushData = [LINEAR_GRADIENT, ...[x1, y1, x2, y2].map(prop => prop.toString())];
insertColorStopsIntoArray(stops, brushData, 5);
this._brush = brushData;
}
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
import {LinearGradientAttributes} from '../lib/attributes';
class LinearGradient extends Gradient{
static displayName = 'LinearGradient';
static propTypes = {
x1: numberProp,
x2: numberProp,
y1: numberProp,
y2: numberProp,
x1: numberProp.isRequired,
x2: numberProp.isRequired,
y1: numberProp.isRequired,
y2: numberProp.isRequired,
id: PropTypes.string.isRequired
};
static defaultProps = {
x1: '0%',
y1: '0%',
x2: '100%',
y2: '0%'
};
render() {
let {
x1,
y1,
x2,
y2
} = this.props;
return super.render(
(stops, opacity) => {
return new LinearGradientGenerator(stopsOpacity(stops, opacity), ...[x1, y1, x2, y2]);
}
);
let {props} = this;
return <RNSVGLinearGradient
x1={props.x1.toString()}
y1={props.y1.toString()}
x2={props.x2.toString()}
y2={props.y2.toString()}
gradient={this.getGradient()}
name={props.id}
/>;
}
}
const RNSVGLinearGradient = createReactNativeComponentClass({
validAttributes: LinearGradientAttributes,
uiViewClassName: 'RNSVGLinearGradient'
});
export default LinearGradient;
export {LinearGradientGenerator};

View File

@@ -2,7 +2,6 @@ import React, {PropTypes} from 'react';
import SerializablePath from '../lib/SerializablePath';
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
import {PathAttributes} from '../lib/attributes';
import mergeContext from '../lib/mergeContext';
import Shape from './Shape';
import {pathProps, numberProp} from '../lib/props';
@@ -10,8 +9,8 @@ class Path extends Shape {
static displayName = 'Path';
static propTypes = {
d: PropTypes.string.isRequired,
...pathProps
...pathProps,
d: PropTypes.string.isRequired
};
setNativeProps = (...args) => {
@@ -19,7 +18,7 @@ class Path extends Shape {
};
render() {
let props = mergeContext(this.props, this.context);
let props = this.props;
let d = new SerializablePath(props.d).toJSON();
return (

View File

@@ -1,48 +1,49 @@
import {PropTypes} from 'react';
import stopsOpacity from '../lib/stopsOpacity';
import React, {PropTypes} from 'react';
import {numberProp} from '../lib/props';
import Gradient from './Gradient';
import {RADIAL_GRADIENT} from '../lib/extract/extractBrush';
import insertColorStopsIntoArray from '../lib/insertProcessor';
function RadialGradientGenerator(stops, fx, fy, rx, ry, cx, cy) {
let brushData = [RADIAL_GRADIENT, ...[fx, fy, rx, ry, cx, cy].map(prop => prop.toString())];
insertColorStopsIntoArray(stops, brushData, 7);
this._brush = brushData;
}
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
import {RadialGradientAttributes} from '../lib/attributes';
class RadialGradient extends Gradient{
static displayName = 'RadialGradient';
static propTypes = {
fx: numberProp,
fy: numberProp,
fx: numberProp.isRequired,
fy: numberProp.isRequired,
rx: numberProp,
ry: numberProp,
cx: numberProp,
cy: numberProp,
cx: numberProp.isRequired,
cy: numberProp.isRequired,
r: numberProp,
id: PropTypes.string.isRequired
};
render() {
let {
fx,
fy,
rx,
ry,
cx,
cy,
r
} = this.props;
return super.render(
(stops, opacity) => {
static defaultProps = {
fx: '50%',
fy: '50%',
cx: '50%',
cy: '50%',
r: '50%'
};
render() {
let {props} = this;
return <RNSVGRadialGradient
fx={props.fx.toString()}
fy={props.fy.toString()}
rx={(props.rx || props.r).toString()}
ry={(props.ry || props.r).toString()}
cx={props.cx.toString()}
cy={props.cy.toString()}
gradient={this.getGradient()}
name={props.id}
/>;
return new RadialGradientGenerator(stopsOpacity(stops, opacity), ...[fx, fy, rx || r, ry || r, cx, cy]);
}
);
}
}
const RNSVGRadialGradient = createReactNativeComponentClass({
validAttributes: RadialGradientAttributes,
uiViewClassName: 'RNSVGRadialGradient'
});
export default RadialGradient;
export {RadialGradientGenerator};

View File

@@ -1,8 +1,7 @@
import React, {PropTypes} from 'react';
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 createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
import mergeContext from '../lib/mergeContext';
import {rectProps, pathProps, fillProps, strokeProps, numberProp} from '../lib/props';
import {pathProps, numberProp} from '../lib/props';
import {RectAttributes} from '../lib/attributes';
import Shape from './Shape';
@@ -11,7 +10,12 @@ class Rect extends Shape {
static propTypes = {
...pathProps,
...rectProps
x: numberProp.isRequired,
y: numberProp.isRequired,
width: numberProp.isRequired,
height: numberProp.isRequired,
rx: numberProp,
ry: numberProp
};
static defaultProps = {
@@ -28,7 +32,7 @@ class Rect extends Shape {
};
render() {
let props = mergeContext(this.props, this.context);
let props = this.props;
return <RNSVGRect
ref={ele => this.root = ele}

View File

@@ -9,6 +9,7 @@ class Stop extends Component{
};
static defaultProps = {
stopColor: '#000',
stopOpacity: 1
};

View File

@@ -3,8 +3,7 @@ import createReactNativeComponentClass from 'react/lib/createReactNativeComponen
import Defs from './Defs';
import extractProps from '../lib/extract/extractProps';
import extractText from '../lib/extract/extractText';
import mergeContext from '../lib/mergeContext';
import {numberProp, textProps, fillProps, strokeProps, pathProps} from '../lib/props';
import {numberProp, pathProps} from '../lib/props';
import {TextAttributes} from '../lib/attributes';
import Shape from './Shape';
@@ -12,10 +11,17 @@ class Text extends Shape {
static displayName = 'Text';
static propTypes = {
...pathProps,
dx: numberProp,
dy: numberProp,
...textProps,
...pathProps
textAnchor: PropTypes.oneOf(['start', 'middle', 'end']),
path: PropTypes.string,
fontFamily: PropTypes.string,
fontSize: numberProp,
fontWeight: PropTypes.string,
fontStyle: PropTypes.string,
font: PropTypes.object,
lines: numberProp
};
static defaultProps = {
@@ -28,7 +34,7 @@ class Text extends Shape {
};
render() {
let props = mergeContext(this.props, this.context);
let props = this.props;
let x = 0;
if (props.x) {

View File

@@ -0,0 +1,17 @@
/**
* 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 "RNSVGBrush.h"
@interface RNSVGBaseBrush : RNSVGBrush
- (instancetype)initWithArray:(NSArray *)array;
- (void)paint:(CGContextRef)context opacity:(CGFloat)opacity brushConverter:(RNSVGBrushConverter *)brushConverter;
@end

View File

@@ -0,0 +1,41 @@
/**
* 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 "RNSVGBaseBrush.h"
#import "RCTConvert+RNSVG.h"
#import "RCTLog.h"
@implementation RNSVGBaseBrush
- (instancetype)initWithArray:(NSArray *)array
{
if ((self = [super initWithArray:array])) {
if (array.count != 2) {
RCTLogError(@"-[%@ %@] expects 2 elements, received %@",
self.class, NSStringFromSelector(_cmd), array);
return nil;
}
self.brushRef = [array objectAtIndex:1];
}
return self;
}
- (void)paint:(CGContextRef)context opacity:(CGFloat)opacity brushConverter:(RNSVGBrushConverter *)brushConverter
{
if (brushConverter.type == kRNSVGLinearGradient) {
[brushConverter drawLinearGradient:context];
} else if (brushConverter.type == kRNSVGRadialGradient) {
[brushConverter drawRidialGradient:context];
} else if (brushConverter.type == kRNSVGPattern) {
// todo:
}
}
@end

View File

@@ -9,12 +9,15 @@
#import <CoreGraphics/CoreGraphics.h>
#import <Foundation/Foundation.h>
#import "RNSVGPercentageConverter.h"
#import "RNSVGBrushConverter.h"
@interface RNSVGBrush : NSObject
{
NSArray *_points;
}
@property (nonatomic, strong) NSString* brushRef;
/* @abstract */
- (instancetype)initWithArray:(NSArray *)data NS_DESIGNATED_INITIALIZER;
@@ -26,15 +29,15 @@
* return NO and paint gets called instead.
* @abstract
*/
- (BOOL)applyFillColor:(CGContextRef)context;
- (BOOL)applyFillColor:(CGContextRef)context opacity:(CGFloat)opacity;
- (BOOL)applyStrokeColor:(CGContextRef)context;
- (BOOL)applyStrokeColor:(CGContextRef)context opacity:(CGFloat)opacity;
/**
* paint fills the context with a brush. The context is assumed to
* be clipped.
* @abstract
*/
- (void)paint:(CGContextRef)context;
- (void)paint:(CGContextRef)context opacity:(CGFloat)opacity brushConverter:(RNSVGBrushConverter *)brushConverter;
@end

View File

@@ -19,19 +19,18 @@
RCT_NOT_IMPLEMENTED(- (instancetype)init)
- (BOOL)applyFillColor:(CGContextRef)context
- (BOOL)applyFillColor:(CGContextRef)context opacity:(CGFloat)opacity
{
return NO;
}
- (BOOL)applyStrokeColor:(CGContextRef)context
- (BOOL)applyStrokeColor:(CGContextRef)context opacity:(CGFloat)opacity
{
return NO;
}
- (void)paint:(CGContextRef)context
- (void)paint:(CGContextRef)context opacity:(CGFloat)opacity brushConverter:(RNSVGBrushConverter *)brushConverter
{
// abstract
}
@end

View File

@@ -0,0 +1,22 @@
/**
* 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 "RCTConvert+RNSVG.h"
#import "RNSVGBrushType.h"
@interface RNSVGBrushConverter : NSObject
@property (nonatomic, copy) NSArray<NSString *> *points;
@property (nonatomic, copy) NSArray<NSNumber *> *colors;
@property (nonatomic, assign) RNSVGBrushType type;
- (void) drawLinearGradient:(CGContextRef)context;
- (void)drawRidialGradient:(CGContextRef)context;
@end

View File

@@ -0,0 +1,130 @@
/**
* 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 "RNSVGBrushConverter.h"
#import "RNSVGPercentageConverter.h"
@implementation RNSVGBrushConverter
- (void)drawLinearGradient:(CGContextRef)context
{
CGGradientRef gradient = CGGradientRetain([RCTConvert CGGradient:self.colors offset:0]);
CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
CGRect box = CGContextGetClipBoundingBox(context);
float height = CGRectGetHeight(box);
float width = CGRectGetWidth(box);
float midX = CGRectGetMidX(box);
float midY = CGRectGetMidY(box);
float offsetX = (midX - width / 2);
float offsetY = (midY - height / 2);
RNSVGPercentageConverter* convert = [[RNSVGPercentageConverter alloc] init];
CGFloat x1 = [convert stringToFloat:(NSString *)[self.points objectAtIndex:0] relative:width offset:offsetX];
CGFloat y1 = [convert stringToFloat:(NSString *)[self.points objectAtIndex:1] relative:height offset:offsetY];
CGFloat x2 = [convert stringToFloat:(NSString *)[self.points objectAtIndex:2] relative:width offset:offsetX];
CGFloat y2 = [convert stringToFloat:(NSString *)[self.points objectAtIndex:3] relative:height offset:offsetY];
CGContextDrawLinearGradient(context, gradient, CGPointMake(x1, y1), CGPointMake(x2, y2), extendOptions);
CGGradientRelease(gradient);
}
- (void)drawRidialGradient:(CGContextRef)context
{
CGGradientRef gradient = CGGradientRetain([RCTConvert CGGradient:self.colors offset:0]);
CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
CGRect box = CGContextGetClipBoundingBox(context);
float height = CGRectGetHeight(box);
float width = CGRectGetWidth(box);
float midX = CGRectGetMidX(box);
float midY = CGRectGetMidY(box);
float offsetX = (midX - width / 2);
float offsetY = (midY - height / 2);
RNSVGPercentageConverter* convert = [[RNSVGPercentageConverter alloc] init];
CGFloat rx = [convert stringToFloat:(NSString *)[_points objectAtIndex:2] relative:width offset:0];
CGFloat ry = [convert stringToFloat:(NSString *)[_points objectAtIndex:3] relative:height offset:0];
CGFloat fx = [convert stringToFloat:(NSString *)[_points objectAtIndex:0] relative:width offset:offsetX];
CGFloat fy = [convert stringToFloat:(NSString *)[_points objectAtIndex:1] relative:height offset:offsetY] / (ry / rx);
CGFloat cx = [convert stringToFloat:(NSString *)[_points objectAtIndex:4] relative:width offset:offsetX];
CGFloat cy = [convert stringToFloat:(NSString *)[_points objectAtIndex:5] relative:height offset:offsetY] / (ry / rx);
CGAffineTransform transform = CGAffineTransformMakeScale(1, ry / rx);
CGContextConcatCTM(context, transform);
CGContextDrawRadialGradient(context, gradient, CGPointMake(fx, fy), 0, CGPointMake(cx, cy), rx, extendOptions);
}
@end
//{
// CGGradientRef _gradient;
//}
//
//- (instancetype)initWithArray:(NSArray *)array
//{
// if ((self = [super initWithArray:array])) {
// if (array.count < 7) {
// RCTLogError(@"-[%@ %@] expects 7 elements, received %@",
// self.class, NSStringFromSelector(_cmd), array);
// return nil;
// }
// _points = [array subarrayWithRange:NSMakeRange(1, 6)];
//
// NSMutableArray *gradient = [[NSMutableArray alloc] init];
// int count = ([array count] - 7) / 5;
// int startStops = [array count] - count;
// for (int i = 0; i < count; i++) {
// [gradient insertObject:[array objectAtIndex:(i * 4 + 7)] atIndex:(i * 4)];
// [gradient insertObject:[array objectAtIndex:(i * 4 + 8)] atIndex:(i * 4 + 1)];
// [gradient insertObject:[array objectAtIndex:(i * 4 + 9)] atIndex:(i * 4 + 2)];
// [gradient insertObject:[array objectAtIndex:(i * 4 + 10)] atIndex:(i * 4 + 3)];
// NSNumber *stop = [NSNumber numberWithFloat:[[array objectAtIndex:(startStops + (count - i - 1))] floatValue]];
//
// [gradient insertObject:stop atIndex:i * 4 + 4];
//
// }
//
// _gradient = CGGradientRetain([RCTConvert CGGradient:gradient offset:0]);
// }
// return self;
//}
//
//- (void)dealloc
//{
// CGGradientRelease(_gradient);
//}
//
//- (void)paint:(CGContextRef)context opacity:(CGFloat)opacity brushConverter:(RNSVGBrushConverter *)brushConverter;
//{
//
// CGRect box = CGContextGetClipBoundingBox(context);
// float height = CGRectGetHeight(box);
// float width = CGRectGetWidth(box);
// float midX = CGRectGetMidX(box);
// float midY = CGRectGetMidY(box);
// float offsetX = (midX - width / 2);
// float offsetY = (midY - height / 2);
//
//
// RNSVGPercentageConverter* convert = [[RNSVGPercentageConverter alloc] init];
// CGFloat rx = [convert stringToFloat:(NSString *)[_points objectAtIndex:2] relative:width offset:0];
// CGFloat ry = [convert stringToFloat:(NSString *)[_points objectAtIndex:3] relative:height offset:0];
// CGFloat fx = [convert stringToFloat:(NSString *)[_points objectAtIndex:0] relative:width offset:offsetX];
// CGFloat fy = [convert stringToFloat:(NSString *)[_points objectAtIndex:1] relative:height offset:offsetY] / (ry / rx);
// CGFloat cx = [convert stringToFloat:(NSString *)[_points objectAtIndex:4] relative:width offset:offsetX];
// CGFloat cy = [convert stringToFloat:(NSString *)[_points objectAtIndex:5] relative:height offset:offsetY] / (ry / rx);
//
// CGAffineTransform transform = CGAffineTransformMakeScale(1, ry / rx);
// CGContextConcatCTM(context, transform);
// CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
//
// CGContextDrawRadialGradient(context, _gradient, CGPointMake(fx, fy), 0, CGPointMake(cx, cy), rx, extendOptions);
//}

View File

@@ -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.
*/
typedef enum {
kRNSVGLinearGradient,
kRNSVGRadialGradient,
kRNSVGPattern
} RNSVGBrushType;

View File

@@ -1,60 +0,0 @@
/**
* 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 "RNSVGLinearGradient.h"
#import "RCTConvert+RNSVG.h"
#import "RCTLog.h"
@implementation RNSVGLinearGradient
{
CGGradientRef _gradient;
}
- (instancetype)initWithArray:(NSArray *)array
{
if ((self = [super initWithArray:array])) {
if (array.count < 5) {
RCTLogError(@"-[%@ %@] expects 5 elements, received %@",
self.class, NSStringFromSelector(_cmd), array);
return nil;
}
_points = [array subarrayWithRange:NSMakeRange(1, 4)];
_gradient = CGGradientRetain([RCTConvert CGGradient:array offset:5]);
}
return self;
}
- (void)dealloc
{
CGGradientRelease(_gradient);
}
- (void)paint:(CGContextRef)context
{
CGGradientDrawingOptions extendOptions =
kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
CGRect box = CGContextGetClipBoundingBox(context);
float height = CGRectGetHeight(box);
float width = CGRectGetWidth(box);
float midX = CGRectGetMidX(box);
float midY = CGRectGetMidY(box);
float offsetX = (midX - width / 2);
float offsetY = (midY - height / 2);
RNSVGPercentageConverter* convert = [[RNSVGPercentageConverter alloc] init];
CGFloat x1 = [convert stringToFloat:(NSString *)[_points objectAtIndex:0] relative:width offset:offsetX];
CGFloat y1 = [convert stringToFloat:(NSString *)[_points objectAtIndex:1] relative:height offset:offsetY];
CGFloat x2 = [convert stringToFloat:(NSString *)[_points objectAtIndex:2] relative:width offset:offsetX];
CGFloat y2 = [convert stringToFloat:(NSString *)[_points objectAtIndex:3] relative:height offset:offsetY];
CGContextDrawLinearGradient(context, _gradient, CGPointMake(x1, y1), CGPointMake(x2, y2), extendOptions);
}
@end

View File

@@ -39,7 +39,7 @@
// Note: This could use applyFillColor with a pattern. This could be more efficient but
// to do that, we need to calculate our own user space CTM.
- (void)paint:(CGContextRef)context
- (void)paint:(CGContextRef)context opacity:(CGFloat)opacity brushConverter:(RNSVGBrushConverter *)brushConverter;
{
CGContextDrawTiledImage(context, _rect, _image);
}

View File

@@ -1,81 +0,0 @@
/**
* 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 "RNSVGRadialGradient.h"
#import "RCTConvert+RNSVG.h"
#import "RNSVGNode.h"
#import "RCTLog.h"
@implementation RNSVGRadialGradient
{
CGGradientRef _gradient;
}
- (instancetype)initWithArray:(NSArray *)array
{
if ((self = [super initWithArray:array])) {
if (array.count < 7) {
RCTLogError(@"-[%@ %@] expects 7 elements, received %@",
self.class, NSStringFromSelector(_cmd), array);
return nil;
}
_points = [array subarrayWithRange:NSMakeRange(1, 6)];
NSMutableArray *gradient = [[NSMutableArray alloc] init];
int count = ([array count] - 7) / 5;
int startStops = [array count] - count;
for (int i = 0; i < count; i++) {
[gradient insertObject:[array objectAtIndex:(i * 4 + 7)] atIndex:(i * 4)];
[gradient insertObject:[array objectAtIndex:(i * 4 + 8)] atIndex:(i * 4 + 1)];
[gradient insertObject:[array objectAtIndex:(i * 4 + 9)] atIndex:(i * 4 + 2)];
[gradient insertObject:[array objectAtIndex:(i * 4 + 10)] atIndex:(i * 4 + 3)];
NSNumber *stop = [NSNumber numberWithFloat:[[array objectAtIndex:(startStops + (count - i - 1))] floatValue]];
[gradient insertObject:stop atIndex:i * 4 + 4];
}
_gradient = CGGradientRetain([RCTConvert CGGradient:gradient offset:0]);
}
return self;
}
- (void)dealloc
{
CGGradientRelease(_gradient);
}
- (void)paint:(CGContextRef)context
{
CGRect box = CGContextGetClipBoundingBox(context);
float height = CGRectGetHeight(box);
float width = CGRectGetWidth(box);
float midX = CGRectGetMidX(box);
float midY = CGRectGetMidY(box);
float offsetX = (midX - width / 2);
float offsetY = (midY - height / 2);
RNSVGPercentageConverter* convert = [[RNSVGPercentageConverter alloc] init];
CGFloat rx = [convert stringToFloat:(NSString *)[_points objectAtIndex:2] relative:width offset:0];
CGFloat ry = [convert stringToFloat:(NSString *)[_points objectAtIndex:3] relative:height offset:0];
CGFloat fx = [convert stringToFloat:(NSString *)[_points objectAtIndex:0] relative:width offset:offsetX];
CGFloat fy = [convert stringToFloat:(NSString *)[_points objectAtIndex:1] relative:height offset:offsetY] / (ry / rx);
CGFloat cx = [convert stringToFloat:(NSString *)[_points objectAtIndex:4] relative:width offset:offsetX];
CGFloat cy = [convert stringToFloat:(NSString *)[_points objectAtIndex:5] relative:height offset:offsetY] / (ry / rx);
CGAffineTransform transform = CGAffineTransformMakeScale(1, ry / rx);
CGContextConcatCTM(context, transform);
CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
CGContextDrawRadialGradient(context, _gradient, CGPointMake(fx, fy), 0, CGPointMake(cx, cy), rx, extendOptions);
}
@end

View File

@@ -1,44 +0,0 @@
/**
* 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 "RNSVGSolidColor.h"
#import "RCTConvert+RNSVG.h"
#import "RCTLog.h"
@implementation RNSVGSolidColor
{
CGColorRef _color;
}
- (instancetype)initWithArray:(NSArray<NSNumber *> *)array
{
if ((self = [super initWithArray:array])) {
_color = CGColorRetain([RCTConvert CGColor:array offset:1]);
}
return self;
}
- (void)dealloc
{
CGColorRelease(_color);
}
- (BOOL)applyFillColor:(CGContextRef)context
{
CGContextSetFillColorWithColor(context, _color);
return YES;
}
- (BOOL)applyStrokeColor:(CGContextRef)context
{
CGContextSetStrokeColorWithColor(context, _color);
return YES;
}
@end

View File

@@ -8,6 +8,6 @@
#import "RNSVGBrush.h"
@interface RNSVGLinearGradient : RNSVGBrush
@interface RNSVGSolidColorBrush : RNSVGBrush
@end

View File

@@ -0,0 +1,50 @@
/**
* 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 "RNSVGSolidColorBrush.h"
#import "RCTConvert+RNSVG.h"
#import "RCTLog.h"
@implementation RNSVGSolidColorBrush
{
CGColorRef _color;
}
- (instancetype)initWithArray:(NSArray<NSNumber *> *)array
{
if ((self = [super initWithArray:array])) {
_color = CGColorRetain([RCTConvert CGColor:array offset:1]);
}
return self;
}
- (void)dealloc
{
CGColorRelease(_color);
}
- (BOOL)applyFillColor:(CGContextRef)context opacity:(CGFloat)opacity
{
CGFloat aplpha = CGColorGetAlpha(_color);
CGColorRef color = CGColorCreateCopyWithAlpha(_color, opacity * aplpha);
CGContextSetFillColorWithColor(context, color);
CGColorRelease(color);
return YES;
}
- (BOOL)applyStrokeColor:(CGContextRef)context opacity:(CGFloat)opacity
{
CGFloat aplpha = CGColorGetAlpha(_color);
CGColorRef color = CGColorCreateCopyWithAlpha(_color, opacity * aplpha);
CGContextSetStrokeColorWithColor(context, color);
CGColorRelease(color);
return YES;
}
@end

View File

@@ -14,8 +14,4 @@
@interface RNSVGDefination : RNSVGNode
- (void)renderTo:(CGContextRef)context;
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
@end

View File

@@ -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 "RNSVGNode.h"
@interface RNSVGLinearGradient : RNSVGNode
@property (nonatomic, strong) NSString *x1;
@property (nonatomic, strong) NSString *y1;
@property (nonatomic, strong) NSString *x2;
@property (nonatomic, strong) NSString *y2;
@property (nonatomic, copy) NSArray<NSNumber *> *gradient;
@end

View File

@@ -0,0 +1,44 @@
/**
* 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 "RNSVGLinearGradient.h"
#import "RNSVGBrushConverter.h"
#import "RNSVGBrushType.h"
@implementation RNSVGLinearGradient
- (void)setGradient:(NSArray<NSNumber *> *)gradient
{
if (gradient == _gradient) {
return;
}
_gradient = gradient;
[self invalidate];
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
return nil;
}
- (void)saveDefination:(CGContextRef)context
{
RNSVGBrushConverter *converter = [[RNSVGBrushConverter alloc] init];
converter.colors = self.gradient;
converter.points = @[self.x1, self.y1, self.x2, self.y2];
converter.type = kRNSVGLinearGradient;
[[self getSvgView] defineBrushConverter:converter brushConverterRef:self.name];
}
- (void)removeDefination
{
[[self getSvgView] removeBrushConverter:self.name];
}
@end

View File

@@ -49,7 +49,7 @@
if (self.fill) {
mode = self.fillRule == kRNSVGCGFCRuleEvenodd ? kCGPathEOFill : kCGPathFill;
fillColor = [self.fill applyFillColor:context];
fillColor = [self.fill applyFillColor:context opacity:self.fillOpacity];
if (!fillColor) {
[self clip:context];
@@ -57,7 +57,8 @@
CGContextSaveGState(context);
CGContextAddPath(context, self.d);
CGContextClip(context);
[self.fill paint:context];
RNSVGBrushConverter *brushConverter = [[self getSvgView] getDefinedBrushConverter:[self.fill brushRef]];
[self.fill paint:context opacity:self.strokeOpacity brushConverter:brushConverter];
CGContextRestoreGState(context);
if (!self.stroke) {
return;
@@ -80,7 +81,7 @@
CGContextClip(context);
}
if ([self.stroke applyStrokeColor:context]) {
if ([self.stroke applyStrokeColor:context opacity:self.strokeOpacity]) {
if (mode == kCGPathFill) {
mode = kCGPathFillStroke;
} else if (mode == kCGPathEOFill) {
@@ -96,8 +97,8 @@
CGContextAddPath(context, self.d);
CGContextReplacePathWithStrokedPath(context);
CGContextClip(context);
[self.stroke paint:context];
RNSVGBrushConverter *brushConverter = [[self getSvgView] getDefinedBrushConverter:[self.stroke brushRef]];
[self.stroke paint:context opacity:self.strokeOpacity brushConverter:brushConverter];
return;
}
}

View File

@@ -0,0 +1,21 @@
/**
* 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 "RNSVGNode.h"
@interface RNSVGRadialGradient : RNSVGNode
@property (nonatomic, strong) NSString *fx;
@property (nonatomic, strong) NSString *fy;
@property (nonatomic, strong) NSString *rx;
@property (nonatomic, strong) NSString *ry;
@property (nonatomic, strong) NSString *cx;
@property (nonatomic, strong) NSString *cy;
@property (nonatomic, copy) NSArray<NSNumber *> *gradient;
@end

View File

@@ -0,0 +1,42 @@
/**
* 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 "RNSVGRadialGradient.h"
@implementation RNSVGRadialGradient
- (void)setGradient:(NSArray<NSNumber *> *)gradient
{
if (gradient == _gradient) {
return;
}
_gradient = gradient;
[self invalidate];
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
return nil;
}
- (void)saveDefination:(CGContextRef)context
{
RNSVGBrushConverter *converter = [[RNSVGBrushConverter alloc] init];
converter.colors = self.gradient;
converter.points = @[self.fx, self.fy, self.rx, self.ry, self.cx, self.cy];
converter.type = kRNSVGRadialGradient;
[[self getSvgView] defineBrushConverter:converter brushConverterRef:self.name];
}
- (void)removeDefination
{
[[self getSvgView] removeBrushConverter:self.name];
}
@end

View File

@@ -7,7 +7,7 @@
*/
#import <UIKit/UIKit.h>
#import "RNSVGBrushCOnverter.h"
#import "RNSVGContainer.h"
@class RNSVGNode;
@@ -25,10 +25,18 @@
- (RNSVGNode *)getDefinedClipPath:(NSString *)clipPathRef;
- (void)defineTemplate:(__kindof RNSVGNode *)template templateRef:(NSString *)templateRef;
- (void)removeTemplate:(NSString *)tempalteRef;
- (RNSVGNode *)getDefinedTemplate:(NSString *)tempalteRef;
- (void)defineBrushConverter:(RNSVGBrushConverter *)brushConverter brushConverterRef:(NSString *)brushConverterRef;
- (void)removeBrushConverter:(NSString *)brushConverterRef;
- (RNSVGBrushConverter *)getDefinedBrushConverter:(NSString *)brushConverterRef;
@end

View File

@@ -15,6 +15,7 @@
{
NSMutableDictionary<NSString *, RNSVGNode *> *clipPaths;
NSMutableDictionary<NSString *, RNSVGNode *> *templates;
NSMutableDictionary<NSString *, RNSVGBrushConverter *> *brushConverters;
}
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
@@ -104,4 +105,25 @@
return templates ? [templates objectForKey:tempalteRef] : nil;
}
- (void)defineBrushConverter:(RNSVGBrushConverter *)brushConverter brushConverterRef:(NSString *)brushConverterRef
{
if (!brushConverters) {
brushConverters = [[NSMutableDictionary alloc] init];
}
[brushConverters setObject:brushConverter forKey:brushConverterRef];
}
- (void)removeBrushConverter:(NSString *)brushConverterRef
{
if (brushConverters) {
[brushConverters removeObjectForKey:brushConverterRef];
}
}
- (RNSVGBrushConverter *)getDefinedBrushConverter:(NSString *)brushConverterRef
{
return brushConverters ? [brushConverters objectForKey:brushConverterRef] : nil;
}
@end

View File

@@ -9,10 +9,8 @@
/* Begin PBXBuildFile section */
0CF68B071AF0549300FF9E5C /* RNSVGRenderable.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE21AF0549300FF9E5C /* RNSVGRenderable.m */; };
0CF68B0B1AF0549300FF9E5C /* RNSVGBrush.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AEC1AF0549300FF9E5C /* RNSVGBrush.m */; };
0CF68B0C1AF0549300FF9E5C /* RNSVGLinearGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AEE1AF0549300FF9E5C /* RNSVGLinearGradient.m */; };
0CF68B0D1AF0549300FF9E5C /* RNSVGPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF01AF0549300FF9E5C /* RNSVGPattern.m */; };
0CF68B0E1AF0549300FF9E5C /* RNSVGRadialGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF21AF0549300FF9E5C /* RNSVGRadialGradient.m */; };
0CF68B0F1AF0549300FF9E5C /* RNSVGSolidColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF41AF0549300FF9E5C /* RNSVGSolidColor.m */; };
0CF68B0F1AF0549300FF9E5C /* RNSVGSolidColorBrush.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF41AF0549300FF9E5C /* RNSVGSolidColorBrush.m */; };
1023B48D1D3DDCCE0051496D /* RNSVGDefinationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1023B48C1D3DDCCE0051496D /* RNSVGDefinationManager.m */; };
1023B4901D3DF4C40051496D /* RNSVGDefination.m in Sources */ = {isa = PBXBuildFile; fileRef = 1023B48F1D3DF4C40051496D /* RNSVGDefination.m */; };
1023B4931D3DF5060051496D /* RNSVGUse.m in Sources */ = {isa = PBXBuildFile; fileRef = 1023B4921D3DF5060051496D /* RNSVGUse.m */; };
@@ -41,9 +39,15 @@
10BA0D491CE74E3D00887C2B /* RNSVGEllipse.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D431CE74E3D00887C2B /* RNSVGEllipse.m */; };
10BA0D4A1CE74E3D00887C2B /* RNSVGLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D451CE74E3D00887C2B /* RNSVGLine.m */; };
10BA0D4B1CE74E3D00887C2B /* RNSVGRect.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D471CE74E3D00887C2B /* RNSVGRect.m */; };
10BEC1BC1D3F66F500FDCB19 /* RNSVGLinearGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BEC1B91D3F66F500FDCB19 /* RNSVGLinearGradient.m */; };
10BEC1BD1D3F66F500FDCB19 /* RNSVGRadialGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BEC1BB1D3F66F500FDCB19 /* RNSVGRadialGradient.m */; };
10BEC1C21D3F680F00FDCB19 /* RNSVGLinearGradientManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BEC1BF1D3F680F00FDCB19 /* RNSVGLinearGradientManager.m */; };
10BEC1C31D3F680F00FDCB19 /* RNSVGRadialGradientManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BEC1C11D3F680F00FDCB19 /* RNSVGRadialGradientManager.m */; };
10BEC1C61D3F7BD300FDCB19 /* RNSVGBrushConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BEC1C51D3F7BD300FDCB19 /* RNSVGBrushConverter.m */; };
10ED4A9B1CF065260078BC02 /* RNSVGClipPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 10ED4A9A1CF065260078BC02 /* RNSVGClipPath.m */; };
10ED4A9E1CF0656A0078BC02 /* RNSVGClipPathManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10ED4A9D1CF0656A0078BC02 /* RNSVGClipPathManager.m */; };
10ED4AA21CF078830078BC02 /* RNSVGNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 10ED4AA11CF078830078BC02 /* RNSVGNode.m */; };
10FDEEB21D3FB60500A5C46C /* RNSVGBaseBrush.m in Sources */ = {isa = PBXBuildFile; fileRef = 10FDEEB11D3FB60500A5C46C /* RNSVGBaseBrush.m */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -64,14 +68,10 @@
0CF68AE21AF0549300FF9E5C /* RNSVGRenderable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGRenderable.m; sourceTree = "<group>"; };
0CF68AEB1AF0549300FF9E5C /* RNSVGBrush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGBrush.h; sourceTree = "<group>"; };
0CF68AEC1AF0549300FF9E5C /* RNSVGBrush.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGBrush.m; sourceTree = "<group>"; };
0CF68AED1AF0549300FF9E5C /* RNSVGLinearGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGLinearGradient.h; sourceTree = "<group>"; };
0CF68AEE1AF0549300FF9E5C /* RNSVGLinearGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGLinearGradient.m; sourceTree = "<group>"; };
0CF68AEF1AF0549300FF9E5C /* RNSVGPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGPattern.h; sourceTree = "<group>"; };
0CF68AF01AF0549300FF9E5C /* RNSVGPattern.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGPattern.m; sourceTree = "<group>"; };
0CF68AF11AF0549300FF9E5C /* RNSVGRadialGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGRadialGradient.h; sourceTree = "<group>"; };
0CF68AF21AF0549300FF9E5C /* RNSVGRadialGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGRadialGradient.m; sourceTree = "<group>"; };
0CF68AF31AF0549300FF9E5C /* RNSVGSolidColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGSolidColor.h; sourceTree = "<group>"; };
0CF68AF41AF0549300FF9E5C /* RNSVGSolidColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGSolidColor.m; sourceTree = "<group>"; };
0CF68AF31AF0549300FF9E5C /* RNSVGSolidColorBrush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGSolidColorBrush.h; sourceTree = "<group>"; };
0CF68AF41AF0549300FF9E5C /* RNSVGSolidColorBrush.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGSolidColorBrush.m; sourceTree = "<group>"; };
1023B48B1D3DDCCE0051496D /* RNSVGDefinationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGDefinationManager.h; sourceTree = "<group>"; };
1023B48C1D3DDCCE0051496D /* RNSVGDefinationManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGDefinationManager.m; sourceTree = "<group>"; };
1023B48E1D3DF4C40051496D /* RNSVGDefination.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGDefination.h; path = Elements/RNSVGDefination.h; sourceTree = "<group>"; };
@@ -132,12 +132,25 @@
10BA0D451CE74E3D00887C2B /* RNSVGLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGLine.m; path = Shapes/RNSVGLine.m; sourceTree = "<group>"; };
10BA0D461CE74E3D00887C2B /* RNSVGRect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGRect.h; path = Shapes/RNSVGRect.h; sourceTree = "<group>"; };
10BA0D471CE74E3D00887C2B /* RNSVGRect.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGRect.m; path = Shapes/RNSVGRect.m; sourceTree = "<group>"; };
10BEC1B81D3F66F500FDCB19 /* RNSVGLinearGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGLinearGradient.h; path = Elements/RNSVGLinearGradient.h; sourceTree = "<group>"; };
10BEC1B91D3F66F500FDCB19 /* RNSVGLinearGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGLinearGradient.m; path = Elements/RNSVGLinearGradient.m; sourceTree = "<group>"; };
10BEC1BA1D3F66F500FDCB19 /* RNSVGRadialGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGRadialGradient.h; path = Elements/RNSVGRadialGradient.h; sourceTree = "<group>"; };
10BEC1BB1D3F66F500FDCB19 /* RNSVGRadialGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGRadialGradient.m; path = Elements/RNSVGRadialGradient.m; sourceTree = "<group>"; };
10BEC1BE1D3F680F00FDCB19 /* RNSVGLinearGradientManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGLinearGradientManager.h; sourceTree = "<group>"; };
10BEC1BF1D3F680F00FDCB19 /* RNSVGLinearGradientManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGLinearGradientManager.m; sourceTree = "<group>"; };
10BEC1C01D3F680F00FDCB19 /* RNSVGRadialGradientManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGRadialGradientManager.h; sourceTree = "<group>"; };
10BEC1C11D3F680F00FDCB19 /* RNSVGRadialGradientManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGRadialGradientManager.m; sourceTree = "<group>"; };
10BEC1C41D3F793100FDCB19 /* RNSVGBrushConverter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNSVGBrushConverter.h; sourceTree = "<group>"; };
10BEC1C51D3F7BD300FDCB19 /* RNSVGBrushConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGBrushConverter.m; sourceTree = "<group>"; };
10ED4A991CF065260078BC02 /* RNSVGClipPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGClipPath.h; path = Elements/RNSVGClipPath.h; sourceTree = "<group>"; };
10ED4A9A1CF065260078BC02 /* RNSVGClipPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGClipPath.m; path = Elements/RNSVGClipPath.m; sourceTree = "<group>"; };
10ED4A9C1CF0656A0078BC02 /* RNSVGClipPathManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGClipPathManager.h; sourceTree = "<group>"; };
10ED4A9D1CF0656A0078BC02 /* RNSVGClipPathManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGClipPathManager.m; sourceTree = "<group>"; };
10ED4AA01CF078830078BC02 /* RNSVGNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGNode.h; sourceTree = "<group>"; };
10ED4AA11CF078830078BC02 /* RNSVGNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGNode.m; sourceTree = "<group>"; };
10FDEEB01D3FB60500A5C46C /* RNSVGBaseBrush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGBaseBrush.h; sourceTree = "<group>"; };
10FDEEB11D3FB60500A5C46C /* RNSVGBaseBrush.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGBaseBrush.m; sourceTree = "<group>"; };
10FDEEB31D3FBED400A5C46C /* RNSVGBrushType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGBrushType.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -180,16 +193,17 @@
0CF68AEA1AF0549300FF9E5C /* Brushes */ = {
isa = PBXGroup;
children = (
10FDEEB31D3FBED400A5C46C /* RNSVGBrushType.h */,
10FDEEB01D3FB60500A5C46C /* RNSVGBaseBrush.h */,
10FDEEB11D3FB60500A5C46C /* RNSVGBaseBrush.m */,
0CF68AEB1AF0549300FF9E5C /* RNSVGBrush.h */,
0CF68AEC1AF0549300FF9E5C /* RNSVGBrush.m */,
0CF68AED1AF0549300FF9E5C /* RNSVGLinearGradient.h */,
0CF68AEE1AF0549300FF9E5C /* RNSVGLinearGradient.m */,
0CF68AEF1AF0549300FF9E5C /* RNSVGPattern.h */,
0CF68AF01AF0549300FF9E5C /* RNSVGPattern.m */,
0CF68AF11AF0549300FF9E5C /* RNSVGRadialGradient.h */,
0CF68AF21AF0549300FF9E5C /* RNSVGRadialGradient.m */,
0CF68AF31AF0549300FF9E5C /* RNSVGSolidColor.h */,
0CF68AF41AF0549300FF9E5C /* RNSVGSolidColor.m */,
0CF68AF31AF0549300FF9E5C /* RNSVGSolidColorBrush.h */,
0CF68AF41AF0549300FF9E5C /* RNSVGSolidColorBrush.m */,
10BEC1C41D3F793100FDCB19 /* RNSVGBrushConverter.h */,
10BEC1C51D3F7BD300FDCB19 /* RNSVGBrushConverter.m */,
);
path = Brushes;
sourceTree = "<group>";
@@ -197,6 +211,10 @@
0CF68AF81AF0549300FF9E5C /* ViewManagers */ = {
isa = PBXGroup;
children = (
10BEC1BE1D3F680F00FDCB19 /* RNSVGLinearGradientManager.h */,
10BEC1BF1D3F680F00FDCB19 /* RNSVGLinearGradientManager.m */,
10BEC1C01D3F680F00FDCB19 /* RNSVGRadialGradientManager.h */,
10BEC1C11D3F680F00FDCB19 /* RNSVGRadialGradientManager.m */,
1023B4941D3DF57D0051496D /* RNSVGUseManager.h */,
1023B4951D3DF57D0051496D /* RNSVGUseManager.m */,
1023B48B1D3DDCCE0051496D /* RNSVGDefinationManager.h */,
@@ -261,6 +279,10 @@
1039D2801CE71DCF001E90A8 /* Elements */ = {
isa = PBXGroup;
children = (
10BEC1B81D3F66F500FDCB19 /* RNSVGLinearGradient.h */,
10BEC1B91D3F66F500FDCB19 /* RNSVGLinearGradient.m */,
10BEC1BA1D3F66F500FDCB19 /* RNSVGRadialGradient.h */,
10BEC1BB1D3F66F500FDCB19 /* RNSVGRadialGradient.m */,
1023B4911D3DF5060051496D /* RNSVGUse.h */,
1023B4921D3DF5060051496D /* RNSVGUse.m */,
1023B48E1D3DF4C40051496D /* RNSVGDefination.h */,
@@ -352,25 +374,28 @@
10BA0D4B1CE74E3D00887C2B /* RNSVGRect.m in Sources */,
10BA0D341CE74E3100887C2B /* RNSVGCircleManager.m in Sources */,
1039D2941CE71EC2001E90A8 /* RnSVGGlyphCache.m in Sources */,
10BEC1BC1D3F66F500FDCB19 /* RNSVGLinearGradient.m in Sources */,
1039D2B01CE72F27001E90A8 /* RNSVGPercentageConverter.m in Sources */,
10BA0D491CE74E3D00887C2B /* RNSVGEllipse.m in Sources */,
1039D28B1CE71EB7001E90A8 /* RNSVGPath.m in Sources */,
0CF68B0D1AF0549300FF9E5C /* RNSVGPattern.m in Sources */,
1023B4931D3DF5060051496D /* RNSVGUse.m in Sources */,
0CF68B0E1AF0549300FF9E5C /* RNSVGRadialGradient.m in Sources */,
10BEC1C21D3F680F00FDCB19 /* RNSVGLinearGradientManager.m in Sources */,
1039D2951CE71EC2001E90A8 /* RNSVGText.m in Sources */,
10BA0D3B1CE74E3100887C2B /* RNSVGRectManager.m in Sources */,
0CF68B071AF0549300FF9E5C /* RNSVGRenderable.m in Sources */,
1039D2891CE71EB7001E90A8 /* RNSVGGroup.m in Sources */,
10ED4A9E1CF0656A0078BC02 /* RNSVGClipPathManager.m in Sources */,
10BEC1C61D3F7BD300FDCB19 /* RNSVGBrushConverter.m in Sources */,
10ED4AA21CF078830078BC02 /* RNSVGNode.m in Sources */,
10ED4A9B1CF065260078BC02 /* RNSVGClipPath.m in Sources */,
10BA0D3E1CE74E3100887C2B /* RNSVGSvgViewManager.m in Sources */,
0CF68B0F1AF0549300FF9E5C /* RNSVGSolidColor.m in Sources */,
0CF68B0F1AF0549300FF9E5C /* RNSVGSolidColorBrush.m in Sources */,
10BA0D3A1CE74E3100887C2B /* RNSVGPathManager.m in Sources */,
1039D2961CE71EC2001E90A8 /* UIBezierPath-Points.m in Sources */,
10BA0D3C1CE74E3100887C2B /* RNSVGRenderableManager.m in Sources */,
0CF68B0C1AF0549300FF9E5C /* RNSVGLinearGradient.m in Sources */,
10BEC1BD1D3F66F500FDCB19 /* RNSVGRadialGradient.m in Sources */,
10BEC1C31D3F680F00FDCB19 /* RNSVGRadialGradientManager.m in Sources */,
10BA0D371CE74E3100887C2B /* RNSVGImageManager.m in Sources */,
10BA0D391CE74E3100887C2B /* RNSVGNodeManager.m in Sources */,
1023B4901D3DF4C40051496D /* RNSVGDefination.m in Sources */,
@@ -381,6 +406,7 @@
0CF68B0B1AF0549300FF9E5C /* RNSVGBrush.m in Sources */,
10BA0D361CE74E3100887C2B /* RNSVGGroupManager.m in Sources */,
10BA0D4A1CE74E3D00887C2B /* RNSVGLine.m in Sources */,
10FDEEB21D3FB60500A5C46C /* RNSVGBaseBrush.m in Sources */,
1039D28C1CE71EB7001E90A8 /* RNSVGSvgView.m in Sources */,
1023B4961D3DF57D0051496D /* RNSVGUseManager.m in Sources */,
1023B48D1D3DDCCE0051496D /* RNSVGDefinationManager.m in Sources */,

View File

@@ -105,6 +105,16 @@
_clipPath = CGPathRetain(clipPath);
}
- (void)setClipPathRef:(NSString *)clipPathRef
{
if (_clipPathRef == clipPathRef) {
return;
}
[self invalidate];
self.clipPath = nil;
_clipPathRef = clipPathRef;
}
- (CGPathRef)getPath: (CGContextRef) context
{
// abstract

View File

@@ -16,8 +16,10 @@
@interface RNSVGRenderable : RNSVGNode
@property (nonatomic, strong) RNSVGBrush *fill;
@property (nonatomic, assign) CGFloat fillOpacity;
@property (nonatomic, assign) RNSVGCGFCRule fillRule;
@property (nonatomic, strong) RNSVGBrush *stroke;
@property (nonatomic, assign) CGFloat strokeOpacity;
@property (nonatomic, assign) CGFloat strokeWidth;
@property (nonatomic, assign) CGLineCap strokeLinecap;
@property (nonatomic, assign) CGLineJoin strokeLinejoin;

View File

@@ -8,7 +8,6 @@
#import <Foundation/Foundation.h>
#import "RNSVGRenderable.h"
#import "RNSVGPath.h"
@interface RNSVGCircle : RNSVGPath

View File

@@ -56,7 +56,7 @@
CGFloat cy = [convert stringToFloat:self.cy relative:height offset:0];
CGFloat r;
// radius in percentage calculate formula:
// radius percentage calculate formula:
// radius = sqrt(pow((width*percent), 2) + pow((height*percent), 2)) / sqrt(2)
if ([convert isPercentage:self.r]) {

View File

@@ -8,7 +8,6 @@
#import <Foundation/Foundation.h>
#import "RNSVGRenderable.h"
#import "RNSVGPath.h"
@interface RNSVGEllipse : RNSVGPath

View File

@@ -8,7 +8,6 @@
#import <Foundation/Foundation.h>
#import "RNSVGRenderable.h"
#import "RNSVGPath.h"
@interface RNSVGLine : RNSVGPath

View File

@@ -8,7 +8,6 @@
#import <Foundation/Foundation.h>
#import "RNSVGRenderable.h"
#import "RNSVGPath.h"
@interface RNSVGRect : RNSVGPath

View File

@@ -7,13 +7,14 @@
*/
#import <QuartzCore/QuartzCore.h>
#import "RNSVGBrush.h"
#import "RCTConvert+RNSVG.h"
#import "RNSVGCGFloatArray.h"
#import "RNSVGTextFrame.h"
#import "RCTConvert.h"
#import "RNSVGCGFCRule.h"
@class RNSVGBrush;
@interface RCTConvert (RNSVG)
+ (CGPathRef)CGPath:(id)json;

View File

@@ -8,10 +8,9 @@
#import "RCTConvert+RNSVG.h"
#import "RNSVGLinearGradient.h"
#import "RNSVGBaseBrush.h"
#import "RNSVGPattern.h"
#import "RNSVGRadialGradient.h"
#import "RNSVGSolidColor.h"
#import "RNSVGSolidColorBrush.h"
#import "RCTLog.h"
#import "RNSVGCGFCRule.h"
@@ -155,15 +154,9 @@ RCT_ENUM_CONVERTER(RNSVGCGFCRule, (@{
case 0: // solid color
// These are probably expensive allocations since it's often the same value.
// We should memoize colors but look ups may be just as expensive.
return [[RNSVGSolidColor alloc] initWithArray:arr];
case 1: // linear gradient
return [[RNSVGLinearGradient alloc] initWithArray:arr];
case 2: // radial gradient
return [[RNSVGRadialGradient alloc] initWithArray:arr];
case 3: // pattern
// TODO:
return nil;
return [[RNSVGPattern alloc] initWithArray:arr];
return [[RNSVGSolidColorBrush alloc] initWithArray:arr];
case 1: // brush
return [[RNSVGBaseBrush alloc] initWithArray:arr];
default:
RCTLogError(@"Unknown brush type: %zd", type);
return nil;

View File

@@ -18,6 +18,4 @@ RCT_EXPORT_MODULE()
return [RNSVGClipPath new];
}
RCT_EXPORT_VIEW_PROPERTY(name, NSString)
@end

View File

@@ -6,8 +6,8 @@
* LICENSE file in the root directory of this source tree.
*/
#import "RNSVGBrush.h"
#import "RNSVGNodeManager.h"
@interface RNSVGSolidColor : RNSVGBrush
@interface RNSVGLinearGradientManager : RNSVGNodeManager
@end

View File

@@ -0,0 +1,27 @@
/**
* 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 "RNSVGLinearGradientManager.h"
#import "RNSVGLinearGradient.h"
@implementation RNSVGLinearGradientManager
RCT_EXPORT_MODULE()
- (RNSVGNode *)node
{
return [RNSVGLinearGradient new];
}
RCT_EXPORT_VIEW_PROPERTY(x1, NSString)
RCT_EXPORT_VIEW_PROPERTY(y1, NSString)
RCT_EXPORT_VIEW_PROPERTY(x2, NSString)
RCT_EXPORT_VIEW_PROPERTY(y2, NSString)
RCT_EXPORT_VIEW_PROPERTY(gradient, NSArray<NSNumber *>)
@end

View File

@@ -6,8 +6,8 @@
* LICENSE file in the root directory of this source tree.
*/
#import "RNSVGBrush.h"
#import "RNSVGNodeManager.h"
@interface RNSVGRadialGradient : RNSVGBrush
@interface RNSVGRadialGradientManager : RNSVGNodeManager
@end

View File

@@ -0,0 +1,29 @@
/**
* 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 "RNSVGRadialGradientManager.h"
#import "RNSVGRadialGradient.h"
@implementation RNSVGRadialGradientManager
RCT_EXPORT_MODULE()
- (RNSVGNode *)node
{
return [RNSVGRadialGradient new];
}
RCT_EXPORT_VIEW_PROPERTY(fx, NSString)
RCT_EXPORT_VIEW_PROPERTY(fy, NSString)
RCT_EXPORT_VIEW_PROPERTY(rx, NSString)
RCT_EXPORT_VIEW_PROPERTY(ry, NSString)
RCT_EXPORT_VIEW_PROPERTY(cx, NSString)
RCT_EXPORT_VIEW_PROPERTY(cy, NSString)
RCT_EXPORT_VIEW_PROPERTY(gradient, NSArray<NSNumber *>)
@end

View File

@@ -21,8 +21,10 @@ RCT_EXPORT_MODULE()
}
RCT_EXPORT_VIEW_PROPERTY(fill, RNSVGBrush)
RCT_EXPORT_VIEW_PROPERTY(fillOpacity, CGFloat)
RCT_EXPORT_VIEW_PROPERTY(fillRule, RNSVGCGFCRule)
RCT_EXPORT_VIEW_PROPERTY(stroke, RNSVGBrush)
RCT_EXPORT_VIEW_PROPERTY(strokeOpacity, CGFloat)
RCT_EXPORT_VIEW_PROPERTY(strokeWidth, CGFloat)
RCT_EXPORT_VIEW_PROPERTY(strokeLinecap, CGLineCap)
RCT_EXPORT_VIEW_PROPERTY(strokeLinejoin, CGLineJoin)

View File

@@ -18,7 +18,7 @@ RCT_EXPORT_MODULE()
return [RNSVGUse new];
}
RCT_EXPORT_VIEW_PROPERTY(href, NSString)
RCT_EXPORT_VIEW_PROPERTY(mergeList, NSArray<NSString *>)
@end

View File

@@ -55,10 +55,12 @@ const RenderableOnlyAttributes = {
fill: {
diff: arrayDiffer
},
fillOpacity: true,
fillRule: true,
stroke: {
diff: arrayDiffer
},
fillRule: true,
strokeOpacity: true,
strokeWidth: true,
strokeLinecap: true,
strokeLinejoin: true,
@@ -109,6 +111,30 @@ const ClipPathAttributes = {
name: true
};
const LinearGradientAttributes = merge({
x1: true,
y1: true,
x2: true,
y2: true,
gradient: {
diff: arrayDiffer
}
}, ClipPathAttributes);
const RadialGradientAttributes = merge({
fx: true,
fy: true,
rx: true,
ry: true,
cx: true,
cy: true,
r: true,
gradient: {
diff: arrayDiffer
}
}, ClipPathAttributes);
const CircleAttributes = merge({
cx: true,
cy: true,
@@ -146,7 +172,6 @@ const RectAttributes = merge({
ry: true
}, RenderableAttributes);
export {
PathAttributes,
TextAttributes,
@@ -158,5 +183,7 @@ export {
LineAttributes,
RectAttributes,
UseAttributes,
RenderableOnlyAttributes
RenderableOnlyAttributes,
LinearGradientAttributes,
RadialGradientAttributes
};

View File

@@ -1,23 +1,22 @@
import Color from 'color';
const SOLID_COLOR = 0;
const LINEAR_GRADIENT = 1;
const RADIAL_GRADIENT = 2;
const PATTERN = 3;
import _ from 'lodash';
import patternReg from './patternReg';
export default function (colorOrBrush) {
if (!colorOrBrush) {
if (colorOrBrush === 'none') {
return null;
}
if (colorOrBrush._brush) {
return colorOrBrush._brush;
} else if (_.isNil(colorOrBrush)) {
colorOrBrush = '#000';
}
let c = new Color(colorOrBrush).rgbaArray();
return [SOLID_COLOR, c[0] / 255, c[1] / 255, c[2] / 255, c[3]];
let matched = colorOrBrush.match(patternReg);
// brush
if (matched) {
return [1, matched[1]];
//todo:
} else { // solid color
let c = new Color(colorOrBrush).rgbaArray();
return [0, c[0] / 255, c[1] / 255, c[2] / 255, c[3]];
}
}
export {
LINEAR_GRADIENT,
RADIAL_GRADIENT,
PATTERN
};

View File

@@ -1,33 +1,15 @@
import rgba from '../rgba';
import extractBrush from './extractBrush';
import patterns from './patterns';
import extractOpacity from './extractOpacity';
const fillRules = {
evenodd: 0,
nonzero: 1
};
function fillFilter(props) {
let {fill} = props;
let fillOpacity = +props.fillOpacity;
if (fill === 'none') {
return null;
} else if (fill) {
return patterns(fill, fillOpacity);
} else if (props.fill === undefined) {
return rgba('#000', isNaN(fillOpacity) ? 1 : fillOpacity).rgbaString();
} else {
return null;
}
}
export default function(props) {
let fill = extractBrush(fillFilter(props), props);
let fillRule = fillRules[props.fillRule] === 0 ? 0 : 1;
return {
fill,
fillRule
fill: extractBrush(props.fill),
fillOpacity: extractOpacity(props.fillOpacity),
fillRule: fillRules[props.fillRule] === 0 ? 0 : 1
};
}

View File

@@ -0,0 +1,6 @@
import _ from 'lodash';
export default function (opacity) {
let value = +opacity;
return (_.isNil(opacity) || isNaN(value)) ? 1 : value;
}

View File

@@ -1,6 +1,5 @@
import extractBrush from './extractBrush';
import patterns from './patterns';
import extractOpacity from './extractOpacity';
let separator = /\s*,\s*/;
const caps = {
@@ -15,7 +14,7 @@ const joins = {
round: 1
};
function strokeFilter(props) {
export default function(props) {
let strokeWidth = +props.strokeWidth;
let {stroke} = props;
if (!strokeWidth && !stroke) {
@@ -37,9 +36,9 @@ function strokeFilter(props) {
stroke = '#000';
}
// TODO: propTypes check
return {
stroke: patterns(stroke, +props.strokeOpacity),
stroke: extractBrush(stroke),
strokeOpacity: extractOpacity(props.strokeOpacity),
strokeLinecap: caps[props.strokeLinecap] || 0,
strokeLinejoin: joins[props.strokeLinejoin] || 0,
strokeDasharray: strokeDasharray || null,
@@ -48,12 +47,3 @@ function strokeFilter(props) {
strokeMiterlimit: props.strokeMiterlimit || 4
};
}
export default function(props) {
let strokeProps = strokeFilter(props);
return strokeProps ? {
...strokeProps,
stroke: extractBrush(strokeProps.stroke, props)
} : null;
}

View File

@@ -1,45 +0,0 @@
import rgba from '../rgba';
let patterns = {};
import patternReg from './patternReg';
import {LinearGradientGenerator} from '../../elements/LinearGradient';
import {RadialGradientGenerator} from '../../elements/RadialGradient';
function isGradient(obj) {
return obj instanceof LinearGradientGenerator || obj instanceof RadialGradientGenerator;
}
function set(id, pattern) {
patterns[id] = pattern;
}
function remove(id) {
delete patterns[id];
}
export {
set,
remove
};
export default function(patternSting, opacity, svgId) {
if (isGradient(patternSting)) {
return patternSting;
}
// 尝试匹配 "url(#pattern)"
let matched = patternSting.match(patternReg);
if (matched) {
let patternName = `${matched[1]}:${svgId}`;
let pattern = patterns[patternName];
if (pattern) {
return pattern(opacity);
}
return null;
}
return rgba(patternSting, opacity).rgbaString();
}

View File

@@ -1,59 +0,0 @@
import Color from 'color';
import _ from 'lodash';
function insertColorIntoArray(color, targetArray, atIndex) {
var c = new Color(color).rgbaArray();
targetArray[atIndex + 0] = c[0] / 255;
targetArray[atIndex + 1] = c[1] / 255;
targetArray[atIndex + 2] = c[2] / 255;
targetArray[atIndex + 3] = c[3];
}
function insertColorsIntoArray(stops, targetArray, atIndex) {
let i = 0;
if ('length' in stops) {
while (i < stops.length) {
insertColorIntoArray(stops[i], targetArray, atIndex + i * 4);
i++;
}
} else {
let sorted = _.sortBy(_.map(stops, (value, key) => ({key, value})), 'key');
sorted.forEach(({value:stop}) => {
insertColorIntoArray(stop, targetArray, atIndex + i * 4);
i++;
});
}
return atIndex + i * 4;
}
function insertColorStopsIntoArray(stops, targetArray, atIndex) {
let lastIndex = insertColorsIntoArray(stops, targetArray, atIndex);
insertOffsetsIntoArray(stops, targetArray, lastIndex);
}
function insertOffsetsIntoArray(stops, targetArray, atIndex) {
let offsetNumber;
let i = 0;
let arr = [];
if ('length' in stops) {
while (i < stops.length) {
offsetNumber = i / (stops.length - 1);
targetArray[atIndex + i] = offsetNumber;
i++;
}
} else {
_.forEach(stops, (stop, offsetString) => {
offsetNumber = (+offsetString);
arr.push(offsetNumber);
i++;
});
arr.sort();
targetArray.splice(atIndex, 0, ...arr);
}
return atIndex + i;
}
export default insertColorStopsIntoArray;

View File

@@ -1,11 +0,0 @@
import _ from 'lodash';
export default function (props, context) {
if (context.isInGroup) {
props = _.defaults({}, props, context, {
isInGroup: null
});
}
return props;
}

View File

@@ -52,17 +52,6 @@ const strokeProps = {
strokeMiterlimit: numberProp
};
const textProps = {
textAnchor: PropTypes.oneOf(['start', 'middle', 'end']),
path: PropTypes.string,
fontFamily: PropTypes.string,
fontSize: numberProp,
fontWeight: PropTypes.string,
fontStyle: PropTypes.string,
font: PropTypes.object,
lines: numberProp
};
const transformProps = {
scale: numberProp,
scaleX: numberProp,
@@ -85,46 +74,12 @@ const pathProps = {
...definationProps
};
const circleProps = {
cx: numberProp.isRequired,
cy: numberProp.isRequired,
r: numberProp.isRequired
};
const ellipseProps = {
cx: numberProp.isRequired,
cy: numberProp.isRequired,
rx: numberProp.isRequired,
ry: numberProp.isRequired
};
const lineProps = {
x1: numberProp.isRequired,
x2: numberProp.isRequired,
y1: numberProp.isRequired,
y2: numberProp.isRequired
};
const rectProps = {
x: numberProp.isRequired,
y: numberProp.isRequired,
width: numberProp.isRequired,
height: numberProp.isRequired,
rx: numberProp,
ry: numberProp
};
export {
numberProp,
fillProps,
clipProps,
strokeProps,
transformProps,
textProps,
circleProps,
ellipseProps,
lineProps,
rectProps,
pathProps,
responderProps,
responderPropsKeys,

View File

@@ -1,14 +0,0 @@
import Color from 'color';
let noneFill = ['transparent', 'none'];
export default function (color, opacity) {
if (noneFill.indexOf(color) !== -1 || !color) {
return Color('#000');
} else {
let c = Color(color);
if (!isNaN(opacity)) {
c = c.alpha(opacity);
}
return c;
}
}

View File

@@ -1,11 +0,0 @@
import _ from 'lodash';
export default function (stops, opacity) {
if (isNaN(opacity)) {
opacity = 1;
}
return _.reduce(stops, (ret, color, key) => {
ret[key] = color.alpha(color.alpha() * opacity).rgbaString();
return ret;
}, {});
}