mirror of
https://github.com/zoriya/react-native-svg.git
synced 2025-12-20 05:55:10 +00:00
complete ClipPath refactor
This commit is contained in:
@@ -7,7 +7,9 @@ import Svg, {
|
|||||||
G,
|
G,
|
||||||
Path,
|
Path,
|
||||||
Use,
|
Use,
|
||||||
Rect
|
Rect,
|
||||||
|
Circle,
|
||||||
|
ClipPath
|
||||||
} from 'react-native-svg';
|
} from 'react-native-svg';
|
||||||
|
|
||||||
class DefsExample extends Component{
|
class DefsExample extends Component{
|
||||||
@@ -19,12 +21,16 @@ class DefsExample extends Component{
|
|||||||
width="100"
|
width="100"
|
||||||
>
|
>
|
||||||
<Defs>
|
<Defs>
|
||||||
<G id="path" x="5" y="2">
|
<G id="path" x="5" y="2" opacity="0.9">
|
||||||
<Path id="test" fill='red' d="M38.459,1.66A0.884,0.884,0,0,1,39,2.5a0.7,0.7,0,0,1-.3.575L23.235,16.092,27.58,26.1a1.4,1.4,0,0,1,.148.3,1.3,1.3,0,0,1,0,.377,1.266,1.266,0,0,1-2.078.991L15.526,20.6l-7.58,4.35a1.255,1.255,0,0,1-.485,0,1.267,1.267,0,0,1-1.277-1.258q0-.01,0-0.02a1.429,1.429,0,0,1,0-.446C7.243,20.253,8.6,16.369,8.6,16.29L3.433,13.545A0.743,0.743,0,0,1,2.9,12.822a0.822,0.822,0,0,1,.623-0.773l8.164-2.972,3.018-8.5A0.822,0.822,0,0,1,15.427,0a0.752,0.752,0,0,1,.752.555l2.563,6.936S37.65,1.727,37.792,1.685A1.15,1.15,0,0,1,38.459,1.66Z"/>
|
<Path id="test" fill='red' d="M38.459,1.66A0.884,0.884,0,0,1,39,2.5a0.7,0.7,0,0,1-.3.575L23.235,16.092,27.58,26.1a1.4,1.4,0,0,1,.148.3,1.3,1.3,0,0,1,0,.377,1.266,1.266,0,0,1-2.078.991L15.526,20.6l-7.58,4.35a1.255,1.255,0,0,1-.485,0,1.267,1.267,0,0,1-1.277-1.258q0-.01,0-0.02a1.429,1.429,0,0,1,0-.446C7.243,20.253,8.6,16.369,8.6,16.29L3.433,13.545A0.743,0.743,0,0,1,2.9,12.822a0.822,0.822,0,0,1,.623-0.773l8.164-2.972,3.018-8.5A0.822,0.822,0,0,1,15.427,0a0.752,0.752,0,0,1,.752.555l2.563,6.936S37.65,1.727,37.792,1.685A1.15,1.15,0,0,1,38.459,1.66Z"/>
|
||||||
</G>
|
</G>
|
||||||
|
<ClipPath id="clip">
|
||||||
|
<Circle r="20%" cx="0" cy="0" />
|
||||||
|
</ClipPath>
|
||||||
</Defs>
|
</Defs>
|
||||||
<Use href="url(#path)" x="0" fill="blue" />
|
<Use href="url(#path)" x="0" fill="blue" opacity="0.5" />
|
||||||
<Use href="url(#path)" x="10" fill="#3a8" />
|
<Use href="url(#path)" x="20" y="5" fill="#8a3" />
|
||||||
|
<Use href="url(#path)" x="30" clipPath="url(#clip)" />
|
||||||
</Svg>;
|
</Svg>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,11 +40,11 @@ const icon = <Svg
|
|||||||
width="20"
|
width="20"
|
||||||
>
|
>
|
||||||
<Defs>
|
<Defs>
|
||||||
<G id="path">
|
<G id="path" scale="0.5">
|
||||||
<Path fill='red' d="M38.459,1.66A0.884,0.884,0,0,1,39,2.5a0.7,0.7,0,0,1-.3.575L23.235,16.092,27.58,26.1a1.4,1.4,0,0,1,.148.3,1.3,1.3,0,0,1,0,.377,1.266,1.266,0,0,1-2.078.991L15.526,20.6l-7.58,4.35a1.255,1.255,0,0,1-.485,0,1.267,1.267,0,0,1-1.277-1.258q0-.01,0-0.02a1.429,1.429,0,0,1,0-.446C7.243,20.253,8.6,16.369,8.6,16.29L3.433,13.545A0.743,0.743,0,0,1,2.9,12.822a0.822,0.822,0,0,1,.623-0.773l8.164-2.972,3.018-8.5A0.822,0.822,0,0,1,15.427,0a0.752,0.752,0,0,1,.752.555l2.563,6.936S37.65,1.727,37.792,1.685A1.15,1.15,0,0,1,38.459,1.66Z"/>
|
<Path fill='red' d="M38.459,1.66A0.884,0.884,0,0,1,39,2.5a0.7,0.7,0,0,1-.3.575L23.235,16.092,27.58,26.1a1.4,1.4,0,0,1,.148.3,1.3,1.3,0,0,1,0,.377,1.266,1.266,0,0,1-2.078.991L15.526,20.6l-7.58,4.35a1.255,1.255,0,0,1-.485,0,1.267,1.267,0,0,1-1.277-1.258q0-.01,0-0.02a1.429,1.429,0,0,1,0-.446C7.243,20.253,8.6,16.369,8.6,16.29L3.433,13.545A0.743,0.743,0,0,1,2.9,12.822a0.822,0.822,0,0,1,.623-0.773l8.164-2.972,3.018-8.5A0.822,0.822,0,0,1,15.427,0a0.752,0.752,0,0,1,.752.555l2.563,6.936S37.65,1.727,37.792,1.685A1.15,1.15,0,0,1,38.459,1.66Z"/>
|
||||||
</G>
|
</G>
|
||||||
</Defs>
|
</Defs>
|
||||||
<Use href="url(#path)" x="10" fill="#3a8" />
|
<Use href="url(#path)" fill="#3a8" />
|
||||||
</Svg>;
|
</Svg>;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,15 +7,16 @@ import {circleProps, pathProps, fillProps, strokeProps, numberProp} from '../lib
|
|||||||
|
|
||||||
class Circle extends Shape {
|
class Circle extends Shape {
|
||||||
static displayName = 'Circle';
|
static displayName = 'Circle';
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
...pathProps,
|
...pathProps,
|
||||||
...circleProps
|
...circleProps
|
||||||
};
|
};
|
||||||
|
|
||||||
static contextTypes = {
|
static defaultProps = {
|
||||||
...fillProps,
|
cx: 0,
|
||||||
...strokeProps,
|
cy: 0,
|
||||||
...circleProps
|
r: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
setNativeProps = (...args) => {
|
setNativeProps = (...args) => {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import React, {Component, PropTypes} from 'react';
|
import React, {Component, PropTypes} from 'react';
|
||||||
import {set, remove} from '../lib/extract/extractClipping';
|
|
||||||
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
|
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
|
||||||
import {ClipPathAttributes} from '../lib/attributes';
|
import {ClipPathAttributes} from '../lib/attributes';
|
||||||
|
|
||||||
@@ -9,26 +8,9 @@ class ClipPath extends Component{
|
|||||||
id: PropTypes.string.isRequired
|
id: PropTypes.string.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
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() {
|
render() {
|
||||||
set(this.id, this.id);
|
|
||||||
return <RNSVGClipPath
|
return <RNSVGClipPath
|
||||||
name={this.id}
|
name={this.props.id}
|
||||||
>{this.props.children}</RNSVGClipPath>;
|
>{this.props.children}</RNSVGClipPath>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,15 +7,17 @@ import {EllipseAttributes} from '../lib/attributes';
|
|||||||
|
|
||||||
class Ellipse extends Shape{
|
class Ellipse extends Shape{
|
||||||
static displayName = 'Ellipse';
|
static displayName = 'Ellipse';
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
...pathProps,
|
...pathProps,
|
||||||
...ellipseProps
|
...ellipseProps
|
||||||
};
|
};
|
||||||
|
|
||||||
static contextTypes = {
|
static defaultProps = {
|
||||||
...fillProps,
|
cx: 0,
|
||||||
...strokeProps,
|
cy: 0,
|
||||||
...ellipseProps
|
rx: 0,
|
||||||
|
ry: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
setNativeProps = (...args) => {
|
setNativeProps = (...args) => {
|
||||||
|
|||||||
@@ -1,31 +1,14 @@
|
|||||||
import React, {Component, PropTypes} from 'react';
|
import React, {Component, PropTypes} from 'react';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
|
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
|
||||||
import {numberProp, contextProps} from '../lib/props';
|
import {transformProps} from '../lib/props';
|
||||||
import {GroupAttributes} from '../lib/attributes';
|
import {GroupAttributes} from '../lib/attributes';
|
||||||
import extractProps from '../lib/extract/extractProps';
|
import extractProps from '../lib/extract/extractProps';
|
||||||
|
|
||||||
class G extends Component{
|
class G extends Component{
|
||||||
static displayName = 'G';
|
static displayName = 'G';
|
||||||
|
|
||||||
static contextTypes = {
|
static propTypes = transformProps;
|
||||||
...contextProps
|
|
||||||
};
|
|
||||||
|
|
||||||
static childContextTypes = {
|
|
||||||
...contextProps
|
|
||||||
};
|
|
||||||
|
|
||||||
getChildContext = () => {
|
|
||||||
let context = _.reduce(contextProps, (props, value, key) => {
|
|
||||||
if (!_.isNil(this.props[key])) {
|
|
||||||
props[key] = this.props[key];
|
|
||||||
}
|
|
||||||
return props;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
return _.defaults({}, this.context, context);
|
|
||||||
};
|
|
||||||
|
|
||||||
setNativeProps = (...args) => {
|
setNativeProps = (...args) => {
|
||||||
this.root.setNativeProps(...args);
|
this.root.setNativeProps(...args);
|
||||||
|
|||||||
@@ -11,14 +11,21 @@ class Image extends Shape {
|
|||||||
static propTypes = {
|
static propTypes = {
|
||||||
x: numberProp,
|
x: numberProp,
|
||||||
y: numberProp,
|
y: numberProp,
|
||||||
width: numberProp,
|
width: numberProp.isRequired,
|
||||||
height: numberProp,
|
height: numberProp.isRequired,
|
||||||
href: PropTypes.number.isRequired,
|
href: PropTypes.number.isRequired,
|
||||||
...responderProps,
|
...responderProps,
|
||||||
...touchableProps
|
...touchableProps
|
||||||
//preserveAspectRatio: PropTypes.string
|
//preserveAspectRatio: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: 0,
|
||||||
|
height: 0
|
||||||
|
};
|
||||||
|
|
||||||
setNativeProps = (...args) => {
|
setNativeProps = (...args) => {
|
||||||
this.root.setNativeProps(...args);
|
this.root.setNativeProps(...args);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,15 +7,17 @@ import {lineProps, pathProps, fillProps, strokeProps, numberProp} from '../lib/p
|
|||||||
|
|
||||||
class Line extends Shape {
|
class Line extends Shape {
|
||||||
static displayName = 'Line';
|
static displayName = 'Line';
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
...pathProps,
|
...pathProps,
|
||||||
...lineProps
|
...lineProps
|
||||||
};
|
};
|
||||||
|
|
||||||
static contextTypes = {
|
static defaultProps = {
|
||||||
...fillProps,
|
x1: 0,
|
||||||
...strokeProps,
|
y1: 0,
|
||||||
...lineProps
|
x2: 0,
|
||||||
|
y2: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
setNativeProps = (...args) => {
|
setNativeProps = (...args) => {
|
||||||
|
|||||||
@@ -10,23 +10,10 @@ class Path extends Shape {
|
|||||||
static displayName = 'Path';
|
static displayName = 'Path';
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
d: PropTypes.string,
|
d: PropTypes.string.isRequired,
|
||||||
...pathProps
|
...pathProps
|
||||||
};
|
};
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
...pathProps
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
_dimensions = null;
|
|
||||||
|
|
||||||
componentWillReceiveProps = nextProps => {
|
|
||||||
if (nextProps.d !== this.props.d) {
|
|
||||||
this._dimensions = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
setNativeProps = (...args) => {
|
setNativeProps = (...args) => {
|
||||||
this.root.setNativeProps(...args);
|
this.root.setNativeProps(...args);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
import React, {Component, PropTypes} from 'react';
|
import React, {Component, PropTypes} from 'react';
|
||||||
import Path from './Path';
|
import Path from './Path';
|
||||||
import {pathProps} from '../lib/props';
|
import {pathProps} from '../lib/props';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
class Polygon extends Component{
|
class Polygon extends Component{
|
||||||
static displayName = 'Polygon';
|
static displayName = 'Polygon';
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
...pathProps,
|
...pathProps,
|
||||||
points: PropTypes.oneOfType([PropTypes.string, PropTypes.array])
|
points: PropTypes.oneOfType([PropTypes.string, PropTypes.array]).isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
points: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
setNativeProps = (...args) => {
|
setNativeProps = (...args) => {
|
||||||
@@ -14,10 +19,15 @@ class Polygon extends Component{
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
let points = this.props.points;
|
||||||
|
if (_.isArray(points)) {
|
||||||
|
points = points.join(',');
|
||||||
|
}
|
||||||
|
|
||||||
return <Path
|
return <Path
|
||||||
ref={ele => this.root = ele}
|
ref={ele => this.root = ele}
|
||||||
{...this.props}
|
{...this.props}
|
||||||
d={`M${this.props.points.trim().replace(/\s+/g, 'L')}z`}
|
d={`M${points.trim().replace(/\s+/g, 'L')}z`}
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
import React, {Component, PropTypes} from 'react';
|
import React, {Component, PropTypes} from 'react';
|
||||||
import Path from './Path';
|
import Path from './Path';
|
||||||
import {pathProps} from '../lib/props';
|
import {pathProps} from '../lib/props';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
class Polyline extends Component{
|
class Polyline extends Component{
|
||||||
static displayName = 'Polyline';
|
static displayName = 'Polyline';
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
...pathProps,
|
...pathProps,
|
||||||
points: PropTypes.oneOfType([PropTypes.string, PropTypes.array])
|
points: PropTypes.oneOfType([PropTypes.string, PropTypes.array]).isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
points: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
setNativeProps = (...args) => {
|
setNativeProps = (...args) => {
|
||||||
@@ -14,10 +19,15 @@ class Polyline extends Component{
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
let points = this.props.points;
|
||||||
|
if (_.isArray(points)) {
|
||||||
|
points = points.join(',');
|
||||||
|
}
|
||||||
|
|
||||||
return <Path
|
return <Path
|
||||||
ref={ele => this.root = ele}
|
ref={ele => this.root = ele}
|
||||||
{...this.props}
|
{...this.props}
|
||||||
d={`M${this.props.points.trim().replace(/\s+/g, 'L')}`}
|
d={`M${points.trim().replace(/\s+/g, 'L')}`}
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,15 +8,19 @@ import Shape from './Shape';
|
|||||||
|
|
||||||
class Rect extends Shape {
|
class Rect extends Shape {
|
||||||
static displayName = 'Rect';
|
static displayName = 'Rect';
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
...pathProps,
|
...pathProps,
|
||||||
...rectProps
|
...rectProps
|
||||||
};
|
};
|
||||||
|
|
||||||
static contextTypes = {
|
static defaultProps = {
|
||||||
...fillProps,
|
x: 0,
|
||||||
...strokeProps,
|
y: 0,
|
||||||
...rectProps
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
rx: 0,
|
||||||
|
ry: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
setNativeProps = (...args) => {
|
setNativeProps = (...args) => {
|
||||||
@@ -37,8 +41,8 @@ class Rect 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()}
|
||||||
rx={props.rx ? props.rx.toString() : '0'}
|
rx={props.rx.toString()}
|
||||||
ry={props.ry ? props.ry.toString() : '0'}
|
ry={props.ry.toString()}
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,15 +30,6 @@ class Svg extends Component{
|
|||||||
id++;
|
id++;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
getChildren = () => {
|
|
||||||
return Children.map(this.props.children, child => {
|
|
||||||
return cloneElement(child, {
|
|
||||||
svgId: this.id
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
measureInWindow = (...args) => {
|
measureInWindow = (...args) => {
|
||||||
this.root.measureInWindow(...args);
|
this.root.measureInWindow(...args);
|
||||||
};
|
};
|
||||||
@@ -67,9 +58,7 @@ class Svg extends Component{
|
|||||||
preserveAspectRatio={props.preserveAspectRatio}
|
preserveAspectRatio={props.preserveAspectRatio}
|
||||||
width={props.width}
|
width={props.width}
|
||||||
height={props.height}
|
height={props.height}
|
||||||
>
|
>{props.children}</ViewBox> : props.children;
|
||||||
{this.getChildren()}
|
|
||||||
</ViewBox> : this.getChildren();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NativeSvgView
|
<NativeSvgView
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import Shape from './Shape';
|
|||||||
|
|
||||||
class Text extends Shape {
|
class Text extends Shape {
|
||||||
static displayName = 'Text';
|
static displayName = 'Text';
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
dx: numberProp,
|
dx: numberProp,
|
||||||
dy: numberProp,
|
dy: numberProp,
|
||||||
@@ -17,10 +18,9 @@ class Text extends Shape {
|
|||||||
...pathProps
|
...pathProps
|
||||||
};
|
};
|
||||||
|
|
||||||
static contextTypes = {
|
static defaultProps = {
|
||||||
...textProps,
|
dx: 0,
|
||||||
...fillProps,
|
dy: 0
|
||||||
...strokeProps
|
|
||||||
};
|
};
|
||||||
|
|
||||||
setNativeProps = (...args) => {
|
setNativeProps = (...args) => {
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import {PropTypes} from 'react';
|
import {PropTypes} from 'react';
|
||||||
import {pathProps} from '../lib/props';
|
import {pathProps} from '../lib/props';
|
||||||
import {UseAttributes} from '../lib/attributes';
|
import {UseAttributes, RenderableOnlyAttributes} from '../lib/attributes';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import patternReg from '../lib/extract/patternReg';
|
import patternReg from '../lib/extract/patternReg';
|
||||||
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
|
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
class Defs extends Shape {
|
class Defs extends Shape {
|
||||||
static displayName = 'Use';
|
static displayName = 'Use';
|
||||||
@@ -32,14 +33,35 @@ class Defs extends Shape {
|
|||||||
console.warn('Invalid `href` prop for `Use` element, expected a href like `"url(#id)"`, but got: "' + props.href + '"');
|
console.warn('Invalid `href` prop for `Use` element, expected a href like `"url(#id)"`, but got: "' + props.href + '"');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mergeList = [];
|
||||||
|
|
||||||
|
let extractedProps = this.extractProps(props, {
|
||||||
|
stroke: true,
|
||||||
|
fill: true,
|
||||||
|
responder: true,
|
||||||
|
transform: true
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(RenderableOnlyAttributes).forEach(name => {
|
||||||
|
|
||||||
|
if (!_.isNil(props[name])) {
|
||||||
|
// clipPath prop may provide `clipPathRef` as native prop
|
||||||
|
if (name === 'clipPath') {
|
||||||
|
if (extractedProps[name]) {
|
||||||
|
mergeList.push(name);
|
||||||
|
} else if (extractedProps.clipPathRef) {
|
||||||
|
mergeList.push('clipPathRef');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mergeList.push(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return <RNSVGUse
|
return <RNSVGUse
|
||||||
ref={ele => this.root = ele}
|
ref={ele => this.root = ele}
|
||||||
{...this.extractProps(props, {
|
{...extractedProps}
|
||||||
stroke: true,
|
mergeList={mergeList}
|
||||||
fill: true,
|
|
||||||
responder: true,
|
|
||||||
transform: true
|
|
||||||
})}
|
|
||||||
href={href}
|
href={href}
|
||||||
>{props.children}</RNSVGUse>;
|
>{props.children}</RNSVGUse>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,4 @@
|
|||||||
|
|
||||||
@interface RNSVGClipPath : RNSVGGroup
|
@interface RNSVGClipPath : RNSVGGroup
|
||||||
|
|
||||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -10,16 +10,16 @@
|
|||||||
|
|
||||||
@implementation RNSVGClipPath
|
@implementation RNSVGClipPath
|
||||||
|
|
||||||
- (void)saveDefination:(CGContextRef)context
|
|
||||||
{
|
|
||||||
[[self getSvgView] defineClipPath:[self getPath:context] clipPathRef:self.name];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||||
{
|
{
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)saveDefination:(CGContextRef)context
|
||||||
|
{
|
||||||
|
[[self getSvgView] defineClipPath:self clipPathRef:self.name];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)removeDefination
|
- (void)removeDefination
|
||||||
{
|
{
|
||||||
if (self.name) {
|
if (self.name) {
|
||||||
|
|||||||
@@ -64,10 +64,17 @@
|
|||||||
[super willRemoveSubview:subview];
|
[super willRemoveSubview:subview];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mergeProperties:(__kindof RNSVGNode *)target
|
- (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray<NSString *> *)mergeList
|
||||||
{
|
{
|
||||||
for (RNSVGNode *node in self.subviews) {
|
for (RNSVGNode *node in self.subviews) {
|
||||||
[node mergeProperties:target];
|
[node mergeProperties:target mergeList:mergeList];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)resetProperties
|
||||||
|
{
|
||||||
|
for (RNSVGNode *node in self.subviews) {
|
||||||
|
[node resetProperties];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,13 +19,13 @@
|
|||||||
/**
|
/**
|
||||||
* define <ClipPath></ClipPath> content as clipPath template.
|
* define <ClipPath></ClipPath> content as clipPath template.
|
||||||
*/
|
*/
|
||||||
- (void)defineClipPath:(CGPathRef)clipPath clipPathRef:(NSString *)clipPathRef;
|
- (void)defineClipPath:(__kindof RNSVGNode *)clipPath clipPathRef:(NSString *)clipPathRef;
|
||||||
|
|
||||||
- (void)removeClipPath:(NSString *)clipPathRef;
|
- (void)removeClipPath:(NSString *)clipPathRef;
|
||||||
|
|
||||||
- (CGPathRef)getDefinedClipPath:(NSString *)clipPathRef;
|
- (RNSVGNode *)getDefinedClipPath:(NSString *)clipPathRef;
|
||||||
|
|
||||||
- (void)defineTemplate:(RNSVGNode *)template templateRef:(NSString *)templateRef;
|
- (void)defineTemplate:(__kindof RNSVGNode *)template templateRef:(NSString *)templateRef;
|
||||||
|
|
||||||
- (void)removeTemplate:(NSString *)tempalteRef;
|
- (void)removeTemplate:(NSString *)tempalteRef;
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
@implementation RNSVGSvgView
|
@implementation RNSVGSvgView
|
||||||
{
|
{
|
||||||
NSMutableDictionary<NSString *, NSValue *> *clipPaths;
|
NSMutableDictionary<NSString *, RNSVGNode *> *clipPaths;
|
||||||
NSMutableDictionary<NSString *, RNSVGNode *> *templates;
|
NSMutableDictionary<NSString *, RNSVGNode *> *templates;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,12 +64,12 @@
|
|||||||
return self.responsible ? [super hitTest:point withEvent:event] : nil;
|
return self.responsible ? [super hitTest:point withEvent:event] : nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)defineClipPath:(CGPathRef)clipPath clipPathRef:(NSString *)clipPathRef
|
- (void)defineClipPath:(__kindof RNSVGNode *)clipPath clipPathRef:(NSString *)clipPathRef
|
||||||
{
|
{
|
||||||
if (!clipPaths) {
|
if (!clipPaths) {
|
||||||
clipPaths = [[NSMutableDictionary alloc] init];
|
clipPaths = [[NSMutableDictionary alloc] init];
|
||||||
}
|
}
|
||||||
[clipPaths setValue:[NSValue valueWithPointer:clipPath] forKey:clipPathRef];
|
[clipPaths setObject:clipPath forKey:clipPathRef];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)removeClipPath:(NSString *)clipPathRef
|
- (void)removeClipPath:(NSString *)clipPathRef
|
||||||
@@ -79,9 +79,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGPathRef)getDefinedClipPath:(NSString *)clipPathRef
|
- (RNSVGNode *)getDefinedClipPath:(NSString *)clipPathRef
|
||||||
{
|
{
|
||||||
return clipPaths ? [[clipPaths valueForKey:clipPathRef] pointerValue] : nil;
|
return clipPaths ? [clipPaths objectForKey:clipPathRef] : nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)defineTemplate:(RNSVGNode *)template templateRef:(NSString *)templateRef
|
- (void)defineTemplate:(RNSVGNode *)template templateRef:(NSString *)templateRef
|
||||||
|
|||||||
@@ -15,5 +15,7 @@
|
|||||||
@interface RNSVGUse : RNSVGRenderable
|
@interface RNSVGUse : RNSVGRenderable
|
||||||
|
|
||||||
@property (nonatomic, strong) NSString *href;
|
@property (nonatomic, strong) NSString *href;
|
||||||
|
@property (nonatomic, copy) NSArray<NSString *> *mergeList;
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -10,12 +10,22 @@
|
|||||||
|
|
||||||
@implementation RNSVGUse
|
@implementation RNSVGUse
|
||||||
|
|
||||||
|
- (void)setMergeList:(NSArray<NSString *> *)mergeList
|
||||||
|
{
|
||||||
|
if (mergeList == _mergeList) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_mergeList = mergeList;
|
||||||
|
[self invalidate];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)renderLayerTo:(CGContextRef)context
|
- (void)renderLayerTo:(CGContextRef)context
|
||||||
{
|
{
|
||||||
RNSVGNode* template = [[self getSvgView] getDefinedTemplate:self.href];
|
RNSVGNode* template = [[self getSvgView] getDefinedTemplate:self.href];
|
||||||
if (template) {
|
if (template) {
|
||||||
[template mergeProperties:self];
|
[template mergeProperties:self mergeList:self.mergeList];
|
||||||
[template renderTo:context];
|
[template renderTo:context];
|
||||||
|
[template resetProperties];
|
||||||
} else if (self.href) {
|
} else if (self.href) {
|
||||||
// TODO: calling yellow box here
|
// TODO: calling yellow box here
|
||||||
RCTLogWarn(@"`Use` element expected a pre-defined svg template as `href` prop, template named: %@ is not defined.", self.href);
|
RCTLogWarn(@"`Use` element expected a pre-defined svg template as `href` prop, template named: %@ is not defined.", self.href);
|
||||||
|
|||||||
@@ -36,16 +36,13 @@
|
|||||||
*/
|
*/
|
||||||
- (void)renderLayerTo:(CGContextRef)context;
|
- (void)renderLayerTo:(CGContextRef)context;
|
||||||
|
|
||||||
|
- (void)renderClip:(CGContextRef)context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clip node by clipPath or clipPathRef.
|
* clip node by clipPath or clipPathRef.
|
||||||
*/
|
*/
|
||||||
- (void)clip:(CGContextRef)context;
|
- (void)clip:(CGContextRef)context;
|
||||||
|
|
||||||
/**
|
|
||||||
* get clip path for current node.
|
|
||||||
*/
|
|
||||||
- (CGPathRef)getClipPath;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getPath will return the path inside node as a ClipPath.
|
* getPath will return the path inside node as a ClipPath.
|
||||||
*/
|
*/
|
||||||
@@ -70,8 +67,13 @@
|
|||||||
- (void)removeDefination;
|
- (void)removeDefination;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* merge owned properties into target element`s properties
|
* Just for template node to merge target node`s properties into owned properties
|
||||||
*/
|
*/
|
||||||
- (void)mergeProperties:(__kindof RNSVGNode *)target;
|
- (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray<NSString *> *)mergeList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just for template node to reset all owned properties once after rendered.
|
||||||
|
*/
|
||||||
|
- (void)resetProperties;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -11,6 +11,9 @@
|
|||||||
#import "RNSVGClipPath.h"
|
#import "RNSVGClipPath.h"
|
||||||
|
|
||||||
@implementation RNSVGNode
|
@implementation RNSVGNode
|
||||||
|
{
|
||||||
|
CGFloat originOpacity;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
|
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
|
||||||
{
|
{
|
||||||
@@ -76,13 +79,22 @@
|
|||||||
if (transparent) {
|
if (transparent) {
|
||||||
CGContextBeginTransparencyLayer(context, NULL);
|
CGContextBeginTransparencyLayer(context, NULL);
|
||||||
}
|
}
|
||||||
|
[self renderClip:context];
|
||||||
[self renderLayerTo:context];
|
[self renderLayerTo:context];
|
||||||
if (transparent) {
|
if (transparent) {
|
||||||
CGContextEndTransparencyLayer(context);
|
CGContextEndTransparencyLayer(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGContextRestoreGState(context);
|
CGContextRestoreGState(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)renderClip:(CGContextRef)context
|
||||||
|
{
|
||||||
|
if (self.clipPathRef) {
|
||||||
|
self.clipPath = [[[self getSvgView] getDefinedClipPath:self.clipPathRef] getPath:context];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)setClipPath:(CGPathRef)clipPath
|
- (void)setClipPath:(CGPathRef)clipPath
|
||||||
{
|
{
|
||||||
if (_clipPath == clipPath) {
|
if (_clipPath == clipPath) {
|
||||||
@@ -99,25 +111,12 @@
|
|||||||
return CGPathCreateMutable();
|
return CGPathCreateMutable();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGPathRef)getClipPath
|
|
||||||
{
|
|
||||||
CGPathRef clipPath = nil;
|
|
||||||
|
|
||||||
if (self.clipPath) {
|
|
||||||
clipPath = self.clipPath;
|
|
||||||
} else if (self.clipPathRef) {
|
|
||||||
clipPath = [[self getSvgView] getDefinedClipPath:self.clipPathRef];
|
|
||||||
}
|
|
||||||
|
|
||||||
return clipPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)clip:(CGContextRef)context
|
- (void)clip:(CGContextRef)context
|
||||||
{
|
{
|
||||||
CGPathRef clipPath = [self getClipPath];
|
CGPathRef clipPath = self.clipPath;
|
||||||
|
|
||||||
if (clipPath) {
|
if (clipPath) {
|
||||||
CGContextAddPath(context, [self getClipPath]);
|
CGContextAddPath(context, clipPath);
|
||||||
if (self.clipRule == kRNSVGCGFCRuleEvenodd) {
|
if (self.clipRule == kRNSVGCGFCRuleEvenodd) {
|
||||||
CGContextEOClip(context);
|
CGContextEOClip(context);
|
||||||
} else {
|
} else {
|
||||||
@@ -182,12 +181,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray<NSString *> *)mergeList
|
||||||
- (void)mergeProperties:(__kindof RNSVGNode *)target
|
|
||||||
{
|
{
|
||||||
|
originOpacity = self.opacity;
|
||||||
self.opacity = target.opacity * self.opacity;
|
self.opacity = target.opacity * self.opacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)resetProperties
|
||||||
|
{
|
||||||
|
self.opacity = originOpacity;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
CGPathRelease(_clipPath);
|
CGPathRelease(_clipPath);
|
||||||
|
|||||||
@@ -9,6 +9,10 @@
|
|||||||
#import "RNSVGRenderable.h"
|
#import "RNSVGRenderable.h"
|
||||||
|
|
||||||
@implementation RNSVGRenderable
|
@implementation RNSVGRenderable
|
||||||
|
{
|
||||||
|
NSMutableDictionary *originProperties;
|
||||||
|
NSArray *changedList;
|
||||||
|
}
|
||||||
|
|
||||||
- (id)init
|
- (id)init
|
||||||
{
|
{
|
||||||
@@ -93,6 +97,7 @@
|
|||||||
CGContextSaveGState(context);
|
CGContextSaveGState(context);
|
||||||
CGContextConcatCTM(context, self.transform);
|
CGContextConcatCTM(context, self.transform);
|
||||||
CGContextSetAlpha(context, self.opacity);
|
CGContextSetAlpha(context, self.opacity);
|
||||||
|
[self renderClip:context];
|
||||||
[self renderLayerTo:context];
|
[self renderLayerTo:context];
|
||||||
CGContextRestoreGState(context);
|
CGContextRestoreGState(context);
|
||||||
}
|
}
|
||||||
@@ -100,7 +105,7 @@
|
|||||||
// hitTest delagate
|
// hitTest delagate
|
||||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||||
{
|
{
|
||||||
CGPathRef clipPath = [self getClipPath];
|
CGPathRef clipPath = self.clipPath;
|
||||||
if (self.nodeArea && CGPathContainsPoint(self.nodeArea, nil, point, NO)) {
|
if (self.nodeArea && CGPathContainsPoint(self.nodeArea, nil, point, NO)) {
|
||||||
if (!clipPath) {
|
if (!clipPath) {
|
||||||
return self;
|
return self;
|
||||||
@@ -112,38 +117,33 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mergeProperties:(__kindof RNSVGNode *)target
|
- (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray<NSString *> *)mergeList
|
||||||
{
|
{
|
||||||
RNSVGRenderable* renderableTarget = target;
|
|
||||||
|
|
||||||
if (renderableTarget.fill) {
|
if (mergeList.count == 0) {
|
||||||
self.fill = renderableTarget.fill;
|
return;
|
||||||
}
|
}
|
||||||
if (renderableTarget.fillRule) {
|
|
||||||
self.fillRule = renderableTarget.fillRule;
|
originProperties = [[NSMutableDictionary alloc] init];
|
||||||
|
|
||||||
|
changedList = mergeList;
|
||||||
|
for (NSString *key in mergeList) {
|
||||||
|
[originProperties setValue:[self valueForKey:key] forKey:key];
|
||||||
|
[self setValue:[target valueForKey:key] forKey:key];
|
||||||
}
|
}
|
||||||
if (renderableTarget.stroke) {
|
|
||||||
self.stroke = renderableTarget.stroke;
|
[super mergeProperties:target mergeList:mergeList];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)resetProperties
|
||||||
|
{
|
||||||
|
if (changedList) {
|
||||||
|
for (NSString *key in changedList) {
|
||||||
|
[self setValue:[originProperties valueForKey:key] forKey:key];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (renderableTarget.strokeWidth) {
|
[super resetProperties];
|
||||||
self.strokeWidth = renderableTarget.strokeWidth;
|
changedList = nil;
|
||||||
}
|
|
||||||
if (renderableTarget.strokeLinecap) {
|
|
||||||
self.strokeLinecap = renderableTarget.strokeLinecap;
|
|
||||||
}
|
|
||||||
if (renderableTarget.strokeLinejoin) {
|
|
||||||
self.strokeLinejoin = renderableTarget.strokeLinejoin;
|
|
||||||
}
|
|
||||||
if (renderableTarget.strokeMiterlimit) {
|
|
||||||
self.strokeMiterlimit = renderableTarget.strokeMiterlimit;
|
|
||||||
}
|
|
||||||
if (renderableTarget.strokeDasharray.count != 0) {
|
|
||||||
self.strokeDasharray = renderableTarget.strokeDasharray;
|
|
||||||
}
|
|
||||||
if (renderableTarget.strokeDashoffset) {
|
|
||||||
self.strokeDashoffset = renderableTarget.strokeDashoffset;
|
|
||||||
}
|
|
||||||
[super mergeProperties:target];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)renderLayerTo:(CGContextRef)context
|
- (void)renderLayerTo:(CGContextRef)context
|
||||||
|
|||||||
@@ -20,5 +20,5 @@ RCT_EXPORT_MODULE()
|
|||||||
|
|
||||||
|
|
||||||
RCT_EXPORT_VIEW_PROPERTY(href, NSString)
|
RCT_EXPORT_VIEW_PROPERTY(href, NSString)
|
||||||
|
RCT_EXPORT_VIEW_PROPERTY(mergeList, NSArray<NSString *>)
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ function fontAndLinesDiffer(a, b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const NodeAttributes = {
|
const NodeAttributes = {
|
||||||
|
name: true,
|
||||||
transform: {
|
transform: {
|
||||||
diff: arrayDiffer
|
diff: arrayDiffer
|
||||||
},
|
},
|
||||||
@@ -50,7 +51,7 @@ const NodeAttributes = {
|
|||||||
responsible: true
|
responsible: true
|
||||||
};
|
};
|
||||||
|
|
||||||
const RenderableAttributes = merge(NodeAttributes, {
|
const RenderableOnlyAttributes = {
|
||||||
fill: {
|
fill: {
|
||||||
diff: arrayDiffer
|
diff: arrayDiffer
|
||||||
},
|
},
|
||||||
@@ -70,26 +71,31 @@ const RenderableAttributes = merge(NodeAttributes, {
|
|||||||
},
|
},
|
||||||
strokeDashoffset: true,
|
strokeDashoffset: true,
|
||||||
strokeMiterlimit: true
|
strokeMiterlimit: true
|
||||||
});
|
};
|
||||||
|
|
||||||
const GroupAttributes = merge(NodeAttributes, {
|
const RenderableAttributes = merge({}, NodeAttributes, RenderableOnlyAttributes);
|
||||||
|
|
||||||
|
const GroupAttributes = merge({
|
||||||
clipPath: {
|
clipPath: {
|
||||||
diff: arrayDiffer
|
diff: arrayDiffer
|
||||||
},
|
},
|
||||||
clipRule: true
|
clipRule: true
|
||||||
});
|
}, NodeAttributes);
|
||||||
|
|
||||||
const UseAttributes = merge(RenderableAttributes, {
|
const UseAttributes = merge({
|
||||||
|
mergeList: {
|
||||||
|
diff: arrayDiffer
|
||||||
|
},
|
||||||
href: true
|
href: true
|
||||||
});
|
}, RenderableAttributes);
|
||||||
|
|
||||||
const PathAttributes = merge(RenderableAttributes, {
|
const PathAttributes = merge({
|
||||||
d: {
|
d: {
|
||||||
diff: arrayDiffer
|
diff: arrayDiffer
|
||||||
}
|
}
|
||||||
});
|
}, RenderableAttributes);
|
||||||
|
|
||||||
const TextAttributes = merge(RenderableAttributes, {
|
const TextAttributes = merge({
|
||||||
alignment: true,
|
alignment: true,
|
||||||
frame: {
|
frame: {
|
||||||
diff: fontAndLinesDiffer
|
diff: fontAndLinesDiffer
|
||||||
@@ -97,48 +103,48 @@ const TextAttributes = merge(RenderableAttributes, {
|
|||||||
path: {
|
path: {
|
||||||
diff: arrayDiffer
|
diff: arrayDiffer
|
||||||
}
|
}
|
||||||
});
|
}, RenderableAttributes);
|
||||||
|
|
||||||
const ClipPathAttributes = merge(RenderableAttributes, {
|
const ClipPathAttributes = {
|
||||||
name: true
|
name: true
|
||||||
});
|
};
|
||||||
|
|
||||||
const CircleAttributes = merge(RenderableAttributes, {
|
const CircleAttributes = merge({
|
||||||
cx: true,
|
cx: true,
|
||||||
cy: true,
|
cy: true,
|
||||||
r: true
|
r: true
|
||||||
});
|
}, RenderableAttributes);
|
||||||
|
|
||||||
const EllipseAttributes = merge(RenderableAttributes, {
|
const EllipseAttributes = merge({
|
||||||
cx: true,
|
cx: true,
|
||||||
cy: true,
|
cy: true,
|
||||||
rx: true,
|
rx: true,
|
||||||
ry: true
|
ry: true
|
||||||
});
|
}, RenderableAttributes);
|
||||||
|
|
||||||
const ImageAttributes = merge(RenderableAttributes, {
|
const ImageAttributes = merge({
|
||||||
x: true,
|
x: true,
|
||||||
y: true,
|
y: true,
|
||||||
width: true,
|
width: true,
|
||||||
height: true,
|
height: true,
|
||||||
src: true
|
src: true
|
||||||
});
|
}, RenderableAttributes);
|
||||||
|
|
||||||
const LineAttributes = merge(RenderableAttributes, {
|
const LineAttributes = merge({
|
||||||
x1: true,
|
x1: true,
|
||||||
y1: true,
|
y1: true,
|
||||||
x2: true,
|
x2: true,
|
||||||
y2: true
|
y2: true
|
||||||
});
|
}, RenderableAttributes);
|
||||||
|
|
||||||
const RectAttributes = merge(RenderableAttributes, {
|
const RectAttributes = merge({
|
||||||
x: true,
|
x: true,
|
||||||
y: true,
|
y: true,
|
||||||
width: true,
|
width: true,
|
||||||
height: true,
|
height: true,
|
||||||
rx: true,
|
rx: true,
|
||||||
ry: true
|
ry: true
|
||||||
});
|
}, RenderableAttributes);
|
||||||
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
@@ -151,5 +157,6 @@ export {
|
|||||||
ImageAttributes,
|
ImageAttributes,
|
||||||
LineAttributes,
|
LineAttributes,
|
||||||
RectAttributes,
|
RectAttributes,
|
||||||
UseAttributes
|
UseAttributes,
|
||||||
|
RenderableOnlyAttributes
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,21 +1,11 @@
|
|||||||
import SerializablePath from 'react-native/Libraries/ART/ARTSerializablePath';
|
import SerializablePath from 'react-native/Libraries/ART/ARTSerializablePath';
|
||||||
import clipReg from './patternReg';
|
import clipReg from './patternReg';
|
||||||
|
|
||||||
let clipPatterns = {};
|
|
||||||
const clipRules = {
|
const clipRules = {
|
||||||
evenodd: 0,
|
evenodd: 0,
|
||||||
nonzero: 1
|
nonzero: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
function set(id, pattern) {
|
|
||||||
clipPatterns[id] = pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
function remove(id) {
|
|
||||||
delete clipPatterns[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default function (props) {
|
export default function (props) {
|
||||||
let {clipPath, clipRule} = props;
|
let {clipPath, clipRule} = props;
|
||||||
let clippingProps = {};
|
let clippingProps = {};
|
||||||
@@ -26,22 +16,11 @@ export default function (props) {
|
|||||||
let matched = clipPath.match(clipReg);
|
let matched = clipPath.match(clipReg);
|
||||||
|
|
||||||
if (matched) {
|
if (matched) {
|
||||||
let patternName = `${matched[1]}:${props.svgId}`;
|
clippingProps.clipPathRef = matched[1];
|
||||||
let pattern = clipPatterns[patternName];
|
|
||||||
if (pattern) {
|
|
||||||
clippingProps.clipPathRef = pattern;
|
|
||||||
} else {
|
|
||||||
clippingProps = null;
|
|
||||||
// TODO: warn
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
clippingProps.clipPath = new SerializablePath(clipPath).toJSON();
|
clippingProps.clipPath = new SerializablePath(clipPath).toJSON();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return clippingProps;
|
return clippingProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
|
||||||
set,
|
|
||||||
remove
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ function fillFilter(props) {
|
|||||||
if (fill === 'none') {
|
if (fill === 'none') {
|
||||||
return null;
|
return null;
|
||||||
} else if (fill) {
|
} else if (fill) {
|
||||||
return patterns(fill, fillOpacity, props.svgId);
|
return patterns(fill, fillOpacity);
|
||||||
} else if (props.fill === undefined) {
|
} else if (props.fill === undefined) {
|
||||||
return rgba('#000', isNaN(fillOpacity) ? 1 : fillOpacity).rgbaString();
|
return rgba('#000', isNaN(fillOpacity) ? 1 : fillOpacity).rgbaString();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ function strokeFilter(props) {
|
|||||||
|
|
||||||
// TODO: propTypes check
|
// TODO: propTypes check
|
||||||
return {
|
return {
|
||||||
stroke: patterns(stroke, +props.strokeOpacity, props.svgId),
|
stroke: patterns(stroke, +props.strokeOpacity),
|
||||||
strokeLinecap: caps[props.strokeLinecap] || 0,
|
strokeLinecap: caps[props.strokeLinecap] || 0,
|
||||||
strokeLinejoin: joins[props.strokeLinejoin] || 0,
|
strokeLinejoin: joins[props.strokeLinejoin] || 0,
|
||||||
strokeDasharray: strokeDasharray || null,
|
strokeDasharray: strokeDasharray || null,
|
||||||
|
|||||||
41
lib/props.js
41
lib/props.js
@@ -86,44 +86,34 @@ const pathProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const circleProps = {
|
const circleProps = {
|
||||||
cx: numberProp,
|
cx: numberProp.isRequired,
|
||||||
cy: numberProp,
|
cy: numberProp.isRequired,
|
||||||
r: numberProp
|
r: numberProp.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
const ellipseProps = {
|
const ellipseProps = {
|
||||||
cx: numberProp,
|
cx: numberProp.isRequired,
|
||||||
cy: numberProp,
|
cy: numberProp.isRequired,
|
||||||
rx: numberProp,
|
rx: numberProp.isRequired,
|
||||||
ry: numberProp
|
ry: numberProp.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
const lineProps = {
|
const lineProps = {
|
||||||
x1: numberProp,
|
x1: numberProp.isRequired,
|
||||||
x2: numberProp,
|
x2: numberProp.isRequired,
|
||||||
y1: numberProp,
|
y1: numberProp.isRequired,
|
||||||
y2: numberProp
|
y2: numberProp.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
const rectProps = {
|
const rectProps = {
|
||||||
x: numberProp,
|
x: numberProp.isRequired,
|
||||||
y: numberProp,
|
y: numberProp.isRequired,
|
||||||
width: numberProp,
|
width: numberProp.isRequired,
|
||||||
height: numberProp,
|
height: numberProp.isRequired,
|
||||||
rx: numberProp,
|
rx: numberProp,
|
||||||
ry: numberProp
|
ry: numberProp
|
||||||
};
|
};
|
||||||
|
|
||||||
const contextProps = {
|
|
||||||
...circleProps,
|
|
||||||
...ellipseProps,
|
|
||||||
...lineProps,
|
|
||||||
...rectProps,
|
|
||||||
...fillProps,
|
|
||||||
...strokeProps,
|
|
||||||
...textProps
|
|
||||||
};
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
numberProp,
|
numberProp,
|
||||||
fillProps,
|
fillProps,
|
||||||
@@ -135,7 +125,6 @@ export {
|
|||||||
ellipseProps,
|
ellipseProps,
|
||||||
lineProps,
|
lineProps,
|
||||||
rectProps,
|
rectProps,
|
||||||
contextProps,
|
|
||||||
pathProps,
|
pathProps,
|
||||||
responderProps,
|
responderProps,
|
||||||
responderPropsKeys,
|
responderPropsKeys,
|
||||||
|
|||||||
Reference in New Issue
Block a user