mirror of
https://github.com/zoriya/react-native-svg.git
synced 2025-12-23 23:55:27 +00:00
refactor Use and Defs element with native code support(iOS)
This commit is contained in:
@@ -14,24 +14,9 @@ import * as Symbol from './examples/Symbol';
|
|||||||
import * as Gradients from './examples/Gradients';
|
import * as Gradients from './examples/Gradients';
|
||||||
import * as Clipping from './examples/Clipping';
|
import * as Clipping from './examples/Clipping';
|
||||||
import * as Image from './examples/Image';
|
import * as Image from './examples/Image';
|
||||||
|
import * as Definations from './examples/Definations';
|
||||||
import * as TouchEvents from './examples/TouchEvents';
|
import * as TouchEvents from './examples/TouchEvents';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Svg,
|
Definations
|
||||||
Rect,
|
|
||||||
Circle,
|
|
||||||
Ellipse,
|
|
||||||
Line,
|
|
||||||
Polygon,
|
|
||||||
Polyline,
|
|
||||||
Path,
|
|
||||||
Text,
|
|
||||||
Stroking,
|
|
||||||
G,
|
|
||||||
Use,
|
|
||||||
Symbol,
|
|
||||||
Gradients,
|
|
||||||
Clipping,
|
|
||||||
Image,
|
|
||||||
TouchEvents
|
|
||||||
};
|
};
|
||||||
|
|||||||
51
Example/examples/Definations.js
Normal file
51
Example/examples/Definations.js
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import React, {
|
||||||
|
Component
|
||||||
|
} from 'react';
|
||||||
|
|
||||||
|
import Svg, {
|
||||||
|
Defs,
|
||||||
|
G,
|
||||||
|
Path,
|
||||||
|
Use,
|
||||||
|
Rect
|
||||||
|
} from 'react-native-svg';
|
||||||
|
|
||||||
|
class DefsExample extends Component{
|
||||||
|
static title = 'basic Defs usage';
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <Svg
|
||||||
|
height="100"
|
||||||
|
width="100"
|
||||||
|
>
|
||||||
|
<Defs>
|
||||||
|
<G id="path" x="5" y="2">
|
||||||
|
<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>
|
||||||
|
</Defs>
|
||||||
|
<Use href="url(#path)" x="0" fill="blue" />
|
||||||
|
<Use href="url(#path)" x="10" fill="#3a8" />
|
||||||
|
</Svg>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const icon = <Svg
|
||||||
|
height="20"
|
||||||
|
width="20"
|
||||||
|
>
|
||||||
|
<Defs>
|
||||||
|
<G id="path">
|
||||||
|
<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>
|
||||||
|
</Defs>
|
||||||
|
<Use href="url(#path)" x="10" fill="#3a8" />
|
||||||
|
</Svg>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const samples = [DefsExample];
|
||||||
|
|
||||||
|
export {
|
||||||
|
icon,
|
||||||
|
samples
|
||||||
|
};
|
||||||
@@ -111,7 +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 = ['Svg', 'Stroking', 'Path', 'Line', 'Rect', 'Polygon', 'Polyline', 'Circle', 'Ellipse', 'G', 'Text', 'Use', 'Symbol', 'Gradients', 'Clipping', 'Image', 'TouchEvents'];
|
||||||
|
const names = ['Definations'];
|
||||||
|
|
||||||
class SvgExample extends Component {
|
class SvgExample extends Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|||||||
@@ -15,9 +15,7 @@ class Circle extends Shape {
|
|||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
...fillProps,
|
...fillProps,
|
||||||
...strokeProps,
|
...strokeProps,
|
||||||
...circleProps,
|
...circleProps
|
||||||
isInGroup: PropTypes.bool,
|
|
||||||
svgId: numberProp
|
|
||||||
};
|
};
|
||||||
|
|
||||||
setNativeProps = (...args) => {
|
setNativeProps = (...args) => {
|
||||||
|
|||||||
105
elements/Defs.js
105
elements/Defs.js
@@ -1,102 +1,19 @@
|
|||||||
import React, {Children, Component, cloneElement, PropTypes} from 'react';
|
import React, {
|
||||||
import {NativeGroup} from './G';
|
Component,
|
||||||
let map = {};
|
} from 'react'
|
||||||
|
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
|
||||||
|
|
||||||
import LinearGradient from './LinearGradient';
|
class Defs extends Component {
|
||||||
import RadialGradient from './RadialGradient';
|
|
||||||
import ClipPath from './ClipPath';
|
|
||||||
let onlyChild = Children.only;
|
|
||||||
|
|
||||||
class DefsItem extends Component{
|
|
||||||
static displayName = 'DefsItem';
|
|
||||||
static propType = {
|
|
||||||
visible: PropTypes.bool
|
|
||||||
};
|
|
||||||
|
|
||||||
static defaultProps = {
|
|
||||||
visible: false
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super(...arguments);
|
|
||||||
this.id = this.props.id + ':' + this.props.svgId;
|
|
||||||
map[this.id] = cloneElement(onlyChild(this.props.children), {
|
|
||||||
id: null
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillReceiveProps = nextProps => {
|
|
||||||
let id = nextProps.id + ':' + nextProps.svgId;
|
|
||||||
if (id !== this.id) {
|
|
||||||
delete map[this.id];
|
|
||||||
}
|
|
||||||
map[id] = cloneElement(onlyChild(nextProps.children), {
|
|
||||||
id: null
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
componentWillUnmount = () => {
|
|
||||||
delete map[this.id];
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return this.props.visible ? onlyChild(this.props.children) : <NativeGroup />;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let idReg = /^#(.+)/;
|
|
||||||
class DefsUse extends Component{
|
|
||||||
static displayName = 'DefsUse';
|
|
||||||
static propType = {
|
|
||||||
href: PropTypes.string
|
|
||||||
};
|
|
||||||
render() {
|
|
||||||
let href = this.props.href;
|
|
||||||
if (href) {
|
|
||||||
let matched = href.match(idReg);
|
|
||||||
if (matched) {
|
|
||||||
let template = map[matched[1] + ':' + this.props.svgId];
|
|
||||||
if (template) {
|
|
||||||
return cloneElement(template, {
|
|
||||||
...this.props,
|
|
||||||
href: null
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.warn(`Invalid href: '${href}' for Use element.\n Please check if '${href}' if defined`);
|
|
||||||
return <NativeGroup />;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: defination scope, global or local?
|
|
||||||
class Defs extends Component{
|
|
||||||
static displayName = 'Defs';
|
static displayName = 'Defs';
|
||||||
static Item = DefsItem;
|
|
||||||
static Use = DefsUse;
|
|
||||||
|
|
||||||
getChildren = () => {
|
|
||||||
return Children.map(this.props.children, child => {
|
|
||||||
let {type} = child;
|
|
||||||
|
|
||||||
if (type === LinearGradient || type === RadialGradient || type === ClipPath) {
|
|
||||||
return cloneElement(child, {
|
|
||||||
svgId: this.props.svgId
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (child.props.id) {
|
|
||||||
return <DefsItem
|
|
||||||
{...child.props}
|
|
||||||
svgId={this.props.svgId}
|
|
||||||
>{child}</DefsItem>;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <NativeGroup>{this.getChildren()}</NativeGroup>;
|
return <RNSVGDefination>{this.props.children}</RNSVGDefination>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RNSVGDefination = createReactNativeComponentClass({
|
||||||
|
validAttributes: {},
|
||||||
|
uiViewClassName: 'RNSVGDefination'
|
||||||
|
});
|
||||||
|
|
||||||
export default Defs;
|
export default Defs;
|
||||||
|
|||||||
@@ -15,9 +15,7 @@ class Ellipse extends Shape{
|
|||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
...fillProps,
|
...fillProps,
|
||||||
...strokeProps,
|
...strokeProps,
|
||||||
...ellipseProps,
|
...ellipseProps
|
||||||
isInGroup: PropTypes.bool,
|
|
||||||
svgId: numberProp
|
|
||||||
};
|
};
|
||||||
|
|
||||||
setNativeProps = (...args) => {
|
setNativeProps = (...args) => {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import React, {Component, PropTypes} from 'react';
|
import React, {Component, PropTypes} from 'react';
|
||||||
import Defs from './Defs';
|
|
||||||
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 {numberProp, contextProps} from '../lib/props';
|
||||||
@@ -10,13 +9,10 @@ class G extends Component{
|
|||||||
static displayName = 'G';
|
static displayName = 'G';
|
||||||
|
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
svgId: numberProp,
|
|
||||||
...contextProps
|
...contextProps
|
||||||
};
|
};
|
||||||
|
|
||||||
static childContextTypes = {
|
static childContextTypes = {
|
||||||
svgId: numberProp,
|
|
||||||
isInGroup: PropTypes.bool,
|
|
||||||
...contextProps
|
...contextProps
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -26,44 +22,24 @@ class G extends Component{
|
|||||||
props[key] = this.props[key];
|
props[key] = this.props[key];
|
||||||
}
|
}
|
||||||
return props;
|
return props;
|
||||||
}, {
|
}, {});
|
||||||
svgId: this.props.svgId || this.context.svgId,
|
|
||||||
isInGroup: true
|
|
||||||
});
|
|
||||||
return _.defaults({}, this.context, context);
|
return _.defaults({}, this.context, context);
|
||||||
};
|
};
|
||||||
|
|
||||||
setNativeProps = (...args) => {
|
setNativeProps = (...args) => {
|
||||||
this.getNativeElement().setNativeProps(...args);
|
this.root.setNativeProps(...args);
|
||||||
};
|
|
||||||
|
|
||||||
getNativeElement = () => {
|
|
||||||
return this.refs.root || this.root;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.props.id) {
|
|
||||||
return <Defs.Item
|
|
||||||
id={this.props.id}
|
|
||||||
svgId={this.props.svgId}
|
|
||||||
visible={true}
|
|
||||||
>
|
|
||||||
<G
|
|
||||||
{...this.props}
|
|
||||||
ref={ele => this.root = ele.refs.root}
|
|
||||||
id={null}
|
|
||||||
/>
|
|
||||||
</Defs.Item>;
|
|
||||||
} else {
|
|
||||||
return <RNSVGGroup
|
return <RNSVGGroup
|
||||||
{...extractProps(this.props, {transform: true})}
|
{...extractProps(this.props, {transform: true})}
|
||||||
ref="root"
|
ref={ele => this.root = ele}
|
||||||
asClipPath={this.props.asClipPath}
|
asClipPath={this.props.asClipPath}
|
||||||
>
|
>
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</RNSVGGroup>;
|
</RNSVGGroup>;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const RNSVGGroup = createReactNativeComponentClass({
|
const RNSVGGroup = createReactNativeComponentClass({
|
||||||
|
|||||||
@@ -15,9 +15,7 @@ class Line extends Shape {
|
|||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
...fillProps,
|
...fillProps,
|
||||||
...strokeProps,
|
...strokeProps,
|
||||||
...lineProps,
|
...lineProps
|
||||||
isInGroup: PropTypes.bool,
|
|
||||||
svgId: numberProp
|
|
||||||
};
|
};
|
||||||
|
|
||||||
setNativeProps = (...args) => {
|
setNativeProps = (...args) => {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import React, {PropTypes} from 'react';
|
import React, {PropTypes} from 'react';
|
||||||
import Defs from './Defs';
|
|
||||||
import SerializablePath from '../lib/SerializablePath';
|
import SerializablePath from '../lib/SerializablePath';
|
||||||
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
|
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
|
||||||
import {PathAttributes} from '../lib/attributes';
|
import {PathAttributes} from '../lib/attributes';
|
||||||
@@ -16,9 +15,7 @@ class Path extends Shape {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
...pathProps,
|
...pathProps
|
||||||
isInGroup: PropTypes.bool,
|
|
||||||
svgId: numberProp
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -31,34 +28,16 @@ class Path extends Shape {
|
|||||||
};
|
};
|
||||||
|
|
||||||
setNativeProps = (...args) => {
|
setNativeProps = (...args) => {
|
||||||
this.getNativeElement().setNativeProps(...args);
|
this.root.setNativeProps(...args);
|
||||||
};
|
|
||||||
|
|
||||||
getNativeElement = () => {
|
|
||||||
return this.refs.root || this.root;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let props = mergeContext(this.props, this.context);
|
let props = mergeContext(this.props, this.context);
|
||||||
|
|
||||||
if (props.id) {
|
|
||||||
return <Defs.Item
|
|
||||||
id={props.id}
|
|
||||||
svgId={props.svgId}
|
|
||||||
visible={true}
|
|
||||||
>
|
|
||||||
<Path
|
|
||||||
ref={ele => this.root = ele.refs.root}
|
|
||||||
{...props}
|
|
||||||
id={null}
|
|
||||||
/>
|
|
||||||
</Defs.Item>;
|
|
||||||
}
|
|
||||||
|
|
||||||
let d = new SerializablePath(props.d).toJSON();
|
let d = new SerializablePath(props.d).toJSON();
|
||||||
return (
|
return (
|
||||||
<RNSVGPath
|
<RNSVGPath
|
||||||
ref="root"
|
ref={ele => this.root = ele}
|
||||||
{...this.extractProps(props)}
|
{...this.extractProps(props)}
|
||||||
d={d}
|
d={d}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -16,9 +16,7 @@ class Rect extends Shape {
|
|||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
...fillProps,
|
...fillProps,
|
||||||
...strokeProps,
|
...strokeProps,
|
||||||
...rectProps,
|
...rectProps
|
||||||
isInGroup: PropTypes.bool,
|
|
||||||
svgId: numberProp
|
|
||||||
};
|
};
|
||||||
|
|
||||||
setNativeProps = (...args) => {
|
setNativeProps = (...args) => {
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ class Shape extends Component {
|
|||||||
this.state = this.touchableGetInitialState();
|
this.state = this.touchableGetInitialState();
|
||||||
}
|
}
|
||||||
|
|
||||||
extractProps = (props) => {
|
extractProps = (props, options = {stroke: true, fill: true, responder: true}) => {
|
||||||
let extractedProps = extractProps(props);
|
let extractedProps = extractProps(props, options);
|
||||||
if (extractedProps.touchable && !extractedProps.disabled) {
|
if (extractedProps.touchable && !extractedProps.disabled) {
|
||||||
_.assign(extractedProps, {
|
_.assign(extractedProps, {
|
||||||
onStartShouldSetResponder: this.touchableHandleStartShouldSetResponder,
|
onStartShouldSetResponder: this.touchableHandleStartShouldSetResponder,
|
||||||
|
|||||||
@@ -20,17 +20,11 @@ class Text extends Shape {
|
|||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
...textProps,
|
...textProps,
|
||||||
...fillProps,
|
...fillProps,
|
||||||
...strokeProps,
|
...strokeProps
|
||||||
isInGroup: PropTypes.bool,
|
|
||||||
svgId: numberProp
|
|
||||||
};
|
};
|
||||||
|
|
||||||
setNativeProps = (...args) => {
|
setNativeProps = (...args) => {
|
||||||
this.getNativeElement().setNativeProps(...args);
|
this.root.setNativeProps(...args);
|
||||||
};
|
|
||||||
|
|
||||||
getNativeElement = () => {
|
|
||||||
return this.refs.root || this.root;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -45,21 +39,9 @@ class Text extends Shape {
|
|||||||
y = props.dy ? +props.y + (+props.dy) : +props.y;
|
y = props.dy ? +props.y + (+props.dy) : +props.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.id) {
|
|
||||||
return <Defs.Item
|
|
||||||
ref={ele => this.root = ele.refs.root}
|
|
||||||
id={this.props.id}
|
|
||||||
svgId={this.props.svgId}
|
|
||||||
visible={true}
|
|
||||||
text={true}
|
|
||||||
>
|
|
||||||
<Text {...this.props} id={null} />
|
|
||||||
</Defs.Item>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RNSVGText
|
<RNSVGText
|
||||||
ref="root"
|
ref={ele => this.root = ele}
|
||||||
{...extractProps({...props, x, y})}
|
{...extractProps({...props, x, y})}
|
||||||
{...extractText(props)}
|
{...extractText(props)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,14 +1,54 @@
|
|||||||
import React, {Component, PropTypes} from 'react';
|
import {PropTypes} from 'react';
|
||||||
import Defs from './Defs';
|
import {pathProps} from '../lib/props';
|
||||||
class Use extends Component{
|
import {UseAttributes} from '../lib/attributes';
|
||||||
|
import Shape from './Shape';
|
||||||
|
import React from 'react';
|
||||||
|
import patternReg from '../lib/extract/patternReg';
|
||||||
|
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
|
||||||
|
|
||||||
|
class Defs extends Shape {
|
||||||
static displayName = 'Use';
|
static displayName = 'Use';
|
||||||
static propType = {
|
|
||||||
href: PropTypes.string
|
static propTypes = {
|
||||||
|
href: PropTypes.string.isRequired,
|
||||||
|
...pathProps
|
||||||
|
};
|
||||||
|
|
||||||
|
setNativeProps = (...args) => {
|
||||||
|
this.root.setNativeProps(...args);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <Defs.Use {...this.props} />;
|
let {props} = this;
|
||||||
|
// 尝试匹配 "url(#pattern)"
|
||||||
|
let matched = props.href.match(patternReg);
|
||||||
|
let href;
|
||||||
|
|
||||||
|
if (matched) {
|
||||||
|
href = matched[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!href) {
|
||||||
|
console.warn('Invalid `href` prop for `Use` element, expected a href like `"url(#id)"`, but got: "' + props.href + '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
return <RNSVGUse
|
||||||
|
ref={ele => this.root = ele}
|
||||||
|
{...this.extractProps(props, {
|
||||||
|
stroke: true,
|
||||||
|
fill: true,
|
||||||
|
responder: true,
|
||||||
|
transform: true
|
||||||
|
})}
|
||||||
|
href={href}
|
||||||
|
>{props.children}</RNSVGUse>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Use;
|
const RNSVGUse = createReactNativeComponentClass({
|
||||||
|
validAttributes: UseAttributes,
|
||||||
|
uiViewClassName: 'RNSVGUse'
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Defs;
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#import "RNSVGSvgView.h"
|
#import "RNSVGSvgView.h"
|
||||||
|
|
||||||
@interface RNSVGClipPath : RNSVGGroup
|
@interface RNSVGClipPath : RNSVGGroup
|
||||||
@property (nonatomic, strong) NSString *name;
|
|
||||||
|
|
||||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
|
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
|
||||||
|
|
||||||
|
|||||||
@@ -10,16 +10,23 @@
|
|||||||
|
|
||||||
@implementation RNSVGClipPath
|
@implementation RNSVGClipPath
|
||||||
|
|
||||||
- (void)renderLayerTo:(CGContextRef)context
|
- (void)saveDefination:(CGContextRef)context
|
||||||
{
|
{
|
||||||
[[self getSvgView] defineClipPath:[self getPath:context] clipPathRef:self.name];
|
[[self getSvgView] defineClipPath:[self getPath:context] clipPathRef:self.name];
|
||||||
}
|
}
|
||||||
|
|
||||||
// hitTest delagate
|
|
||||||
|
|
||||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||||
{
|
{
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)removeDefination
|
||||||
|
{
|
||||||
|
if (self.name) {
|
||||||
|
[[self getSvgView] removeClipPath: self.name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
21
ios/Elements/RNSVGDefination.h
Normal file
21
ios/Elements/RNSVGDefination.h
Normal 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"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RNSVG defination are implemented as abstract UIViews for all elements inside Defs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@interface RNSVGDefination : RNSVGNode
|
||||||
|
|
||||||
|
- (void)renderTo:(CGContextRef)context;
|
||||||
|
|
||||||
|
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
|
||||||
|
|
||||||
|
@end
|
||||||
27
ios/Elements/RNSVGDefination.m
Normal file
27
ios/Elements/RNSVGDefination.m
Normal 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 "RNSVGDefination.h"
|
||||||
|
|
||||||
|
@class RNSVGNode;
|
||||||
|
|
||||||
|
@implementation RNSVGDefination
|
||||||
|
|
||||||
|
- (void)renderTo:(CGContextRef)context
|
||||||
|
{
|
||||||
|
for (RNSVGNode *node in self.subviews) {
|
||||||
|
[node saveDefination: context];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||||
|
{
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import "RNSVGGroup.h"
|
#import "RNSVGGroup.h"
|
||||||
|
#import <objc/runtime.h>
|
||||||
|
|
||||||
@implementation RNSVGGroup
|
@implementation RNSVGGroup
|
||||||
|
|
||||||
@@ -35,17 +36,39 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// hitTest delagate
|
// hitTest delagate
|
||||||
|
|
||||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||||
{
|
{
|
||||||
for (RNSVGNode *node in [self.subviews reverseObjectEnumerator]) {
|
for (RNSVGNode *node in [self.subviews reverseObjectEnumerator]) {
|
||||||
UIView *view = [node hitTest: point withEvent:event];
|
UIView *view = [node hitTest: point withEvent:event];
|
||||||
if (view != NULL) {
|
if (view) {
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)saveDefination:(CGContextRef)context
|
||||||
|
{
|
||||||
|
if (self.name) {
|
||||||
|
RNSVGSvgView* svg = [self getSvgView];
|
||||||
|
[svg defineTemplate:self templateRef:self.name];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (RNSVGNode *node in self.subviews) {
|
||||||
|
[node saveDefination:context];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)willRemoveSubview:(UIView *)subview
|
||||||
|
{
|
||||||
|
[super willRemoveSubview:subview];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mergeProperties:(__kindof RNSVGNode *)target
|
||||||
|
{
|
||||||
|
for (RNSVGNode *node in self.subviews) {
|
||||||
|
[node mergeProperties:target];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#import "RNSVGContainer.h"
|
#import "RNSVGContainer.h"
|
||||||
|
|
||||||
|
@class RNSVGNode;
|
||||||
|
|
||||||
@interface RNSVGSvgView : UIView <RNSVGContainer>
|
@interface RNSVGSvgView : UIView <RNSVGContainer>
|
||||||
|
|
||||||
@property (nonatomic, assign) BOOL responsible;
|
@property (nonatomic, assign) BOOL responsible;
|
||||||
@@ -17,10 +19,16 @@
|
|||||||
/**
|
/**
|
||||||
* define <ClipPath></ClipPath> content as clipPath template.
|
* define <ClipPath></ClipPath> content as clipPath template.
|
||||||
*/
|
*/
|
||||||
- (void)defineClipPath:(CGPathRef)clipPath clipPathRef:(NSString *)clipPathId;
|
- (void)defineClipPath:(CGPathRef)clipPath clipPathRef:(NSString *)clipPathRef;
|
||||||
|
|
||||||
- (void)removeClipPath:(NSString *)clipPathRef;
|
- (void)removeClipPath:(NSString *)clipPathRef;
|
||||||
|
|
||||||
- (CGPathRef)getDefinedClipPath:(NSString *)clipPathRef;
|
- (CGPathRef)getDefinedClipPath:(NSString *)clipPathRef;
|
||||||
|
|
||||||
|
- (void)defineTemplate:(RNSVGNode *)template templateRef:(NSString *)templateRef;
|
||||||
|
|
||||||
|
- (void)removeTemplate:(NSString *)tempalteRef;
|
||||||
|
|
||||||
|
- (RNSVGNode *)getDefinedTemplate:(NSString *)tempalteRef;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
|
|
||||||
@implementation RNSVGSvgView
|
@implementation RNSVGSvgView
|
||||||
{
|
{
|
||||||
NSMutableDictionary *clipPaths;
|
NSMutableDictionary<NSString *, NSValue *> *clipPaths;
|
||||||
|
NSMutableDictionary<NSString *, RNSVGNode *> *templates;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
|
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
|
||||||
@@ -44,6 +45,7 @@
|
|||||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||||
|
|
||||||
for (RNSVGNode *node in self.subviews) {
|
for (RNSVGNode *node in self.subviews) {
|
||||||
|
[node saveDefination:context];
|
||||||
[node renderTo:context];
|
[node renderTo:context];
|
||||||
|
|
||||||
if (node.responsible && !self.responsible) {
|
if (node.responsible && !self.responsible) {
|
||||||
@@ -64,7 +66,7 @@
|
|||||||
|
|
||||||
- (void)defineClipPath:(CGPathRef)clipPath clipPathRef:(NSString *)clipPathRef
|
- (void)defineClipPath:(CGPathRef)clipPath clipPathRef:(NSString *)clipPathRef
|
||||||
{
|
{
|
||||||
if (clipPaths == NULL) {
|
if (!clipPaths) {
|
||||||
clipPaths = [[NSMutableDictionary alloc] init];
|
clipPaths = [[NSMutableDictionary alloc] init];
|
||||||
}
|
}
|
||||||
[clipPaths setValue:[NSValue valueWithPointer:clipPath] forKey:clipPathRef];
|
[clipPaths setValue:[NSValue valueWithPointer:clipPath] forKey:clipPathRef];
|
||||||
@@ -72,14 +74,34 @@
|
|||||||
|
|
||||||
- (void)removeClipPath:(NSString *)clipPathRef
|
- (void)removeClipPath:(NSString *)clipPathRef
|
||||||
{
|
{
|
||||||
if (clipPaths != NULL) {
|
if (clipPaths) {
|
||||||
[clipPaths removeObjectForKey:clipPathRef];
|
[clipPaths removeObjectForKey:clipPathRef];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGPathRef)getDefinedClipPath:(NSString *)clipPathRef
|
- (CGPathRef)getDefinedClipPath:(NSString *)clipPathRef
|
||||||
{
|
{
|
||||||
return [[clipPaths valueForKey:clipPathRef] pointerValue];
|
return clipPaths ? [[clipPaths valueForKey:clipPathRef] pointerValue] : nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)defineTemplate:(RNSVGNode *)template templateRef:(NSString *)templateRef
|
||||||
|
{
|
||||||
|
if (!templates) {
|
||||||
|
templates = [[NSMutableDictionary alloc] init];
|
||||||
|
}
|
||||||
|
[templates setObject:template forKey:templateRef];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)removeTemplate:(NSString *)tempalteRef
|
||||||
|
{
|
||||||
|
if (templates) {
|
||||||
|
[templates removeObjectForKey:tempalteRef];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (RNSVGNode *)getDefinedTemplate:(NSString *)tempalteRef
|
||||||
|
{
|
||||||
|
return templates ? [templates objectForKey:tempalteRef] : nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
19
ios/Elements/RNSVGUse.h
Normal file
19
ios/Elements/RNSVGUse.h
Normal 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 "RNSVGRenderable.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RNSVG defination are implemented as abstract UIViews for all elements inside Defs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@interface RNSVGUse : RNSVGRenderable
|
||||||
|
|
||||||
|
@property (nonatomic, strong) NSString *href;
|
||||||
|
|
||||||
|
@end
|
||||||
26
ios/Elements/RNSVGUse.m
Normal file
26
ios/Elements/RNSVGUse.m
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Horcrux.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
#import "RNSVGUse.h"
|
||||||
|
#import "RCTLog.h"
|
||||||
|
|
||||||
|
@implementation RNSVGUse
|
||||||
|
|
||||||
|
- (void)renderLayerTo:(CGContextRef)context
|
||||||
|
{
|
||||||
|
RNSVGNode* template = [[self getSvgView] getDefinedTemplate:self.href];
|
||||||
|
if (template) {
|
||||||
|
[template mergeProperties:self];
|
||||||
|
[template renderTo:context];
|
||||||
|
} else if (self.href) {
|
||||||
|
// TODO: calling yellow box here
|
||||||
|
RCTLogWarn(@"`Use` element expected a pre-defined svg template as `href` prop, template named: %@ is not defined.", self.href);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@@ -13,6 +13,10 @@
|
|||||||
0CF68B0D1AF0549300FF9E5C /* RNSVGPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF01AF0549300FF9E5C /* RNSVGPattern.m */; };
|
0CF68B0D1AF0549300FF9E5C /* RNSVGPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF01AF0549300FF9E5C /* RNSVGPattern.m */; };
|
||||||
0CF68B0E1AF0549300FF9E5C /* RNSVGRadialGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF21AF0549300FF9E5C /* RNSVGRadialGradient.m */; };
|
0CF68B0E1AF0549300FF9E5C /* RNSVGRadialGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF21AF0549300FF9E5C /* RNSVGRadialGradient.m */; };
|
||||||
0CF68B0F1AF0549300FF9E5C /* RNSVGSolidColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF41AF0549300FF9E5C /* RNSVGSolidColor.m */; };
|
0CF68B0F1AF0549300FF9E5C /* RNSVGSolidColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF41AF0549300FF9E5C /* RNSVGSolidColor.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 */; };
|
||||||
|
1023B4961D3DF57D0051496D /* RNSVGUseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1023B4951D3DF57D0051496D /* RNSVGUseManager.m */; };
|
||||||
1039D2891CE71EB7001E90A8 /* RNSVGGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2821CE71EB7001E90A8 /* RNSVGGroup.m */; };
|
1039D2891CE71EB7001E90A8 /* RNSVGGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2821CE71EB7001E90A8 /* RNSVGGroup.m */; };
|
||||||
1039D28A1CE71EB7001E90A8 /* RNSVGImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2841CE71EB7001E90A8 /* RNSVGImage.m */; };
|
1039D28A1CE71EB7001E90A8 /* RNSVGImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2841CE71EB7001E90A8 /* RNSVGImage.m */; };
|
||||||
1039D28B1CE71EB7001E90A8 /* RNSVGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2861CE71EB7001E90A8 /* RNSVGPath.m */; };
|
1039D28B1CE71EB7001E90A8 /* RNSVGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2861CE71EB7001E90A8 /* RNSVGPath.m */; };
|
||||||
@@ -68,6 +72,14 @@
|
|||||||
0CF68AF21AF0549300FF9E5C /* RNSVGRadialGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGRadialGradient.m; 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>"; };
|
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>"; };
|
0CF68AF41AF0549300FF9E5C /* RNSVGSolidColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGSolidColor.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>"; };
|
||||||
|
1023B48F1D3DF4C40051496D /* RNSVGDefination.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGDefination.m; path = Elements/RNSVGDefination.m; sourceTree = "<group>"; };
|
||||||
|
1023B4911D3DF5060051496D /* RNSVGUse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGUse.h; path = Elements/RNSVGUse.h; sourceTree = "<group>"; };
|
||||||
|
1023B4921D3DF5060051496D /* RNSVGUse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGUse.m; path = Elements/RNSVGUse.m; sourceTree = "<group>"; };
|
||||||
|
1023B4941D3DF57D0051496D /* RNSVGUseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGUseManager.h; sourceTree = "<group>"; };
|
||||||
|
1023B4951D3DF57D0051496D /* RNSVGUseManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGUseManager.m; sourceTree = "<group>"; };
|
||||||
1039D2811CE71EB7001E90A8 /* RNSVGGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGGroup.h; path = Elements/RNSVGGroup.h; sourceTree = "<group>"; };
|
1039D2811CE71EB7001E90A8 /* RNSVGGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGGroup.h; path = Elements/RNSVGGroup.h; sourceTree = "<group>"; };
|
||||||
1039D2821CE71EB7001E90A8 /* RNSVGGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGGroup.m; path = Elements/RNSVGGroup.m; sourceTree = "<group>"; };
|
1039D2821CE71EB7001E90A8 /* RNSVGGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGGroup.m; path = Elements/RNSVGGroup.m; sourceTree = "<group>"; };
|
||||||
1039D2831CE71EB7001E90A8 /* RNSVGImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGImage.h; path = Elements/RNSVGImage.h; sourceTree = "<group>"; };
|
1039D2831CE71EB7001E90A8 /* RNSVGImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGImage.h; path = Elements/RNSVGImage.h; sourceTree = "<group>"; };
|
||||||
@@ -185,6 +197,10 @@
|
|||||||
0CF68AF81AF0549300FF9E5C /* ViewManagers */ = {
|
0CF68AF81AF0549300FF9E5C /* ViewManagers */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
1023B4941D3DF57D0051496D /* RNSVGUseManager.h */,
|
||||||
|
1023B4951D3DF57D0051496D /* RNSVGUseManager.m */,
|
||||||
|
1023B48B1D3DDCCE0051496D /* RNSVGDefinationManager.h */,
|
||||||
|
1023B48C1D3DDCCE0051496D /* RNSVGDefinationManager.m */,
|
||||||
10ED4A9C1CF0656A0078BC02 /* RNSVGClipPathManager.h */,
|
10ED4A9C1CF0656A0078BC02 /* RNSVGClipPathManager.h */,
|
||||||
10ED4A9D1CF0656A0078BC02 /* RNSVGClipPathManager.m */,
|
10ED4A9D1CF0656A0078BC02 /* RNSVGClipPathManager.m */,
|
||||||
10BA0D1C1CE74E3100887C2B /* RNSVGCircleManager.h */,
|
10BA0D1C1CE74E3100887C2B /* RNSVGCircleManager.h */,
|
||||||
@@ -245,6 +261,10 @@
|
|||||||
1039D2801CE71DCF001E90A8 /* Elements */ = {
|
1039D2801CE71DCF001E90A8 /* Elements */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
1023B4911D3DF5060051496D /* RNSVGUse.h */,
|
||||||
|
1023B4921D3DF5060051496D /* RNSVGUse.m */,
|
||||||
|
1023B48E1D3DF4C40051496D /* RNSVGDefination.h */,
|
||||||
|
1023B48F1D3DF4C40051496D /* RNSVGDefination.m */,
|
||||||
10ED4A991CF065260078BC02 /* RNSVGClipPath.h */,
|
10ED4A991CF065260078BC02 /* RNSVGClipPath.h */,
|
||||||
10ED4A9A1CF065260078BC02 /* RNSVGClipPath.m */,
|
10ED4A9A1CF065260078BC02 /* RNSVGClipPath.m */,
|
||||||
1039D2811CE71EB7001E90A8 /* RNSVGGroup.h */,
|
1039D2811CE71EB7001E90A8 /* RNSVGGroup.h */,
|
||||||
@@ -336,6 +356,7 @@
|
|||||||
10BA0D491CE74E3D00887C2B /* RNSVGEllipse.m in Sources */,
|
10BA0D491CE74E3D00887C2B /* RNSVGEllipse.m in Sources */,
|
||||||
1039D28B1CE71EB7001E90A8 /* RNSVGPath.m in Sources */,
|
1039D28B1CE71EB7001E90A8 /* RNSVGPath.m in Sources */,
|
||||||
0CF68B0D1AF0549300FF9E5C /* RNSVGPattern.m in Sources */,
|
0CF68B0D1AF0549300FF9E5C /* RNSVGPattern.m in Sources */,
|
||||||
|
1023B4931D3DF5060051496D /* RNSVGUse.m in Sources */,
|
||||||
0CF68B0E1AF0549300FF9E5C /* RNSVGRadialGradient.m in Sources */,
|
0CF68B0E1AF0549300FF9E5C /* RNSVGRadialGradient.m in Sources */,
|
||||||
1039D2951CE71EC2001E90A8 /* RNSVGText.m in Sources */,
|
1039D2951CE71EC2001E90A8 /* RNSVGText.m in Sources */,
|
||||||
10BA0D3B1CE74E3100887C2B /* RNSVGRectManager.m in Sources */,
|
10BA0D3B1CE74E3100887C2B /* RNSVGRectManager.m in Sources */,
|
||||||
@@ -352,6 +373,7 @@
|
|||||||
0CF68B0C1AF0549300FF9E5C /* RNSVGLinearGradient.m in Sources */,
|
0CF68B0C1AF0549300FF9E5C /* RNSVGLinearGradient.m in Sources */,
|
||||||
10BA0D371CE74E3100887C2B /* RNSVGImageManager.m in Sources */,
|
10BA0D371CE74E3100887C2B /* RNSVGImageManager.m in Sources */,
|
||||||
10BA0D391CE74E3100887C2B /* RNSVGNodeManager.m in Sources */,
|
10BA0D391CE74E3100887C2B /* RNSVGNodeManager.m in Sources */,
|
||||||
|
1023B4901D3DF4C40051496D /* RNSVGDefination.m in Sources */,
|
||||||
10BA0D381CE74E3100887C2B /* RNSVGLineManager.m in Sources */,
|
10BA0D381CE74E3100887C2B /* RNSVGLineManager.m in Sources */,
|
||||||
10BA0D481CE74E3D00887C2B /* RNSVGCircle.m in Sources */,
|
10BA0D481CE74E3D00887C2B /* RNSVGCircle.m in Sources */,
|
||||||
10BA0D351CE74E3100887C2B /* RNSVGEllipseManager.m in Sources */,
|
10BA0D351CE74E3100887C2B /* RNSVGEllipseManager.m in Sources */,
|
||||||
@@ -360,6 +382,8 @@
|
|||||||
10BA0D361CE74E3100887C2B /* RNSVGGroupManager.m in Sources */,
|
10BA0D361CE74E3100887C2B /* RNSVGGroupManager.m in Sources */,
|
||||||
10BA0D4A1CE74E3D00887C2B /* RNSVGLine.m in Sources */,
|
10BA0D4A1CE74E3D00887C2B /* RNSVGLine.m in Sources */,
|
||||||
1039D28C1CE71EB7001E90A8 /* RNSVGSvgView.m in Sources */,
|
1039D28C1CE71EB7001E90A8 /* RNSVGSvgView.m in Sources */,
|
||||||
|
1023B4961D3DF57D0051496D /* RNSVGUseManager.m in Sources */,
|
||||||
|
1023B48D1D3DDCCE0051496D /* RNSVGDefinationManager.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,21 +11,22 @@
|
|||||||
#import "RNSVGSvgView.h"
|
#import "RNSVGSvgView.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RNSVG nodes are implemented as empty UIViews but this is just an implementation detail to fit
|
* RNSVG nodes are implemented as base UIViews. They should be implementation for all basic
|
||||||
* into the existing view management. They should also be shadow views and painted on a background
|
*interfaces for all non-defination nodes.
|
||||||
* thread.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@interface RNSVGNode : UIView
|
@interface RNSVGNode : UIView
|
||||||
|
|
||||||
@property (nonatomic, assign) CGRect rect;
|
@property (nonatomic, strong) NSString *name;
|
||||||
@property (nonatomic, assign) CGFloat opacity;
|
@property (nonatomic, assign) CGFloat opacity;
|
||||||
@property (nonatomic, assign) RNSVGCGFCRule clipRule;
|
@property (nonatomic, assign) RNSVGCGFCRule clipRule;
|
||||||
@property (nonatomic, assign) CGPathRef clipPath; // convert clipPath="M0,0 L0,10 L10,10z" into path
|
@property (nonatomic, assign) CGPathRef clipPath; // convert clipPath="M0,0 L0,10 L10,10z" into path
|
||||||
@property (nonatomic, strong) NSString *clipPathRef; // use clipPath="url(#clip)" as ClipPath
|
@property (nonatomic, strong) NSString *clipPathRef; // use clipPath="url(#clip)" as ClipPath
|
||||||
@property (nonatomic, assign) BOOL responsible;
|
@property (nonatomic, assign) BOOL responsible;
|
||||||
|
|
||||||
|
|
||||||
- (void)invalidate;
|
- (void)invalidate;
|
||||||
|
|
||||||
- (void)renderTo:(CGContextRef)context;
|
- (void)renderTo:(CGContextRef)context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,20 +37,41 @@
|
|||||||
- (void)renderLayerTo:(CGContextRef)context;
|
- (void)renderLayerTo:(CGContextRef)context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clip node by clipPath or clipPathId.
|
* clip node by clipPath or clipPathRef.
|
||||||
*/
|
*/
|
||||||
- (void)clip:(CGContextRef)context;
|
- (void)clip:(CGContextRef)context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get clip path for current node.
|
||||||
|
*/
|
||||||
- (CGPathRef)getClipPath;
|
- (CGPathRef)getClipPath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getPath will return the path inside node as a ClipPath.
|
* getPath will return the path inside node as a ClipPath.
|
||||||
*/
|
*/
|
||||||
- (CGPathRef)getPath: (CGContextRef) context;
|
- (CGPathRef)getPath:(CGContextRef) context;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* run hitTest
|
||||||
|
*/
|
||||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
|
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
|
||||||
|
|
||||||
- (RNSVGSvgView *)getSvgView;
|
- (RNSVGSvgView *)getSvgView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* save element`s defination into svg element.
|
||||||
|
*/
|
||||||
|
- (void)saveDefination:(CGContextRef)context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove element`s defination from svg element.
|
||||||
|
*/
|
||||||
|
- (void)removeDefination;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* merge owned properties into target element`s properties
|
||||||
|
*/
|
||||||
|
- (void)mergeProperties:(__kindof RNSVGNode *)target;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -30,6 +30,17 @@
|
|||||||
// Do nothing, as subviews are inserted by insertReactSubview:
|
// Do nothing, as subviews are inserted by insertReactSubview:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)invalidate
|
||||||
|
{
|
||||||
|
id<RNSVGContainer> container = (id<RNSVGContainer>)self.superview;
|
||||||
|
[container invalidate];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)reactSetInheritedBackgroundColor:(UIColor *)inheritedBackgroundColor
|
||||||
|
{
|
||||||
|
self.backgroundColor = inheritedBackgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)setOpacity:(CGFloat)opacity
|
- (void)setOpacity:(CGFloat)opacity
|
||||||
{
|
{
|
||||||
if (opacity == _opacity) {
|
if (opacity == _opacity) {
|
||||||
@@ -52,12 +63,6 @@
|
|||||||
super.transform = transform;
|
super.transform = transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)invalidate
|
|
||||||
{
|
|
||||||
id<RNSVGContainer> container = (id<RNSVGContainer>)self.superview;
|
|
||||||
[container invalidate];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)renderTo:(CGContextRef)context
|
- (void)renderTo:(CGContextRef)context
|
||||||
{
|
{
|
||||||
float opacity = self.opacity;
|
float opacity = self.opacity;
|
||||||
@@ -111,7 +116,7 @@
|
|||||||
{
|
{
|
||||||
CGPathRef clipPath = [self getClipPath];
|
CGPathRef clipPath = [self getClipPath];
|
||||||
|
|
||||||
if (clipPath != NULL) {
|
if (clipPath) {
|
||||||
CGContextAddPath(context, [self getClipPath]);
|
CGContextAddPath(context, [self getClipPath]);
|
||||||
if (self.clipRule == kRNSVGCGFCRuleEvenodd) {
|
if (self.clipRule == kRNSVGCGFCRuleEvenodd) {
|
||||||
CGContextEOClip(context);
|
CGContextEOClip(context);
|
||||||
@@ -121,33 +126,68 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)reactSetInheritedBackgroundColor:(UIColor *)inheritedBackgroundColor
|
|
||||||
{
|
|
||||||
self.backgroundColor = inheritedBackgroundColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)renderLayerTo:(CGContextRef)context
|
- (void)renderLayerTo:(CGContextRef)context
|
||||||
{
|
{
|
||||||
// abstract
|
// abstract
|
||||||
}
|
}
|
||||||
|
|
||||||
- (RNSVGSvgView *)getSvgView
|
|
||||||
{
|
|
||||||
UIView *parent = self.superview;
|
|
||||||
while ([parent class] != [RNSVGSvgView class]) {
|
|
||||||
parent = parent.superview;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (RNSVGSvgView *)parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
|
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
|
||||||
{
|
{
|
||||||
// abstract
|
// abstract
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (RNSVGSvgView *)getSvgView
|
||||||
|
{
|
||||||
|
UIView *parent = self.superview;
|
||||||
|
while (parent && [parent class] != [RNSVGSvgView class]) {
|
||||||
|
parent = parent.superview;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (RNSVGSvgView *)parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)willRemoveFromSuperView
|
||||||
|
{
|
||||||
|
if (self.subviews) {
|
||||||
|
for (RNSVGNode *node in self.subviews) {
|
||||||
|
[node willRemoveFromSuperView];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[self removeDefination];
|
||||||
|
[super removeFromSuperview];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reverse removeFromSuperview calling order.
|
||||||
|
* calling it from subviews to superview.
|
||||||
|
*/
|
||||||
|
- (void)removeFromSuperview
|
||||||
|
{
|
||||||
|
[self willRemoveFromSuperView];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)saveDefination:(CGContextRef)context
|
||||||
|
{
|
||||||
|
if (self.name) {
|
||||||
|
RNSVGSvgView* svg = [self getSvgView];
|
||||||
|
[svg defineTemplate:self templateRef:self.name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)removeDefination
|
||||||
|
{
|
||||||
|
if (self.name) {
|
||||||
|
[[self getSvgView] removeTemplate:self.name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)mergeProperties:(__kindof RNSVGNode *)target
|
||||||
|
{
|
||||||
|
self.opacity = target.opacity * self.opacity;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
CGPathRelease(_clipPath);
|
CGPathRelease(_clipPath);
|
||||||
|
|||||||
@@ -101,8 +101,8 @@
|
|||||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||||
{
|
{
|
||||||
CGPathRef clipPath = [self getClipPath];
|
CGPathRef clipPath = [self getClipPath];
|
||||||
if (self.nodeArea != NULL && CGPathContainsPoint(self.nodeArea, nil, point, NO)) {
|
if (self.nodeArea && CGPathContainsPoint(self.nodeArea, nil, point, NO)) {
|
||||||
if (clipPath == NULL) {
|
if (!clipPath) {
|
||||||
return self;
|
return self;
|
||||||
} else {
|
} else {
|
||||||
return CGPathContainsPoint(clipPath, nil, point, NO) ? self : nil;
|
return CGPathContainsPoint(clipPath, nil, point, NO) ? self : nil;
|
||||||
@@ -112,6 +112,40 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)mergeProperties:(__kindof RNSVGNode *)target
|
||||||
|
{
|
||||||
|
RNSVGRenderable* renderableTarget = target;
|
||||||
|
|
||||||
|
if (renderableTarget.fill) {
|
||||||
|
self.fill = renderableTarget.fill;
|
||||||
|
}
|
||||||
|
if (renderableTarget.fillRule) {
|
||||||
|
self.fillRule = renderableTarget.fillRule;
|
||||||
|
}
|
||||||
|
if (renderableTarget.stroke) {
|
||||||
|
self.stroke = renderableTarget.stroke;
|
||||||
|
}
|
||||||
|
if (renderableTarget.strokeWidth) {
|
||||||
|
self.strokeWidth = renderableTarget.strokeWidth;
|
||||||
|
}
|
||||||
|
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
|
||||||
{
|
{
|
||||||
// abstract
|
// abstract
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ static void RNSVGFreeTextFrame(RNSVGTextFrame frame)
|
|||||||
}
|
}
|
||||||
// We should consider snapping this shift to device pixels to improve rendering quality
|
// We should consider snapping this shift to device pixels to improve rendering quality
|
||||||
// when a line has subpixel width.
|
// when a line has subpixel width.
|
||||||
CGAffineTransform offset = CGAffineTransformMakeTranslation(-shift, frame.baseLine + frame.lineHeight * i + (self.path == NULL ? 0 : -frame.lineHeight));
|
CGAffineTransform offset = CGAffineTransformMakeTranslation(-shift, frame.baseLine + frame.lineHeight * i + (self.path ? -frame.lineHeight : 0));
|
||||||
CGPathAddPath(path, &offset, [self setLinePath:frame.lines[i]]);
|
CGPathAddPath(path, &offset, [self setLinePath:frame.lines[i]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,11 +115,11 @@ static void RNSVGFreeTextFrame(RNSVGTextFrame frame)
|
|||||||
for(CFIndex j = 0; j < runGlyphCount; ++j, ++glyphIndex) {
|
for(CFIndex j = 0; j < runGlyphCount; ++j, ++glyphIndex) {
|
||||||
CGPathRef letter = [cache pathForGlyph:glyphs[j] fromFont:runFont];
|
CGPathRef letter = [cache pathForGlyph:glyphs[j] fromFont:runFont];
|
||||||
CGPoint point = positions[j];
|
CGPoint point = positions[j];
|
||||||
if (letter != NULL) {
|
if (letter) {
|
||||||
CGAffineTransform transform;
|
CGAffineTransform transform;
|
||||||
|
|
||||||
// draw glyphs along path
|
// draw glyphs along path
|
||||||
if (self.path != NULL) {
|
if (self.path) {
|
||||||
CGPoint slope;
|
CGPoint slope;
|
||||||
CGRect bounding = CGPathGetBoundingBox(letter);
|
CGRect bounding = CGPathGetBoundingBox(letter);
|
||||||
UIBezierPath* path = [UIBezierPath bezierPathWithCGPath:self.path];
|
UIBezierPath* path = [UIBezierPath bezierPathWithCGPath:self.path];
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
-(id)init
|
-(id)init
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if(self != nil)
|
if(self)
|
||||||
{
|
{
|
||||||
cache = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
|
cache = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
{
|
{
|
||||||
// First we lookup the font to get to its glyph dictionary
|
// First we lookup the font to get to its glyph dictionary
|
||||||
CFMutableDictionaryRef glyphDict = (CFMutableDictionaryRef)CFDictionaryGetValue(cache, font);
|
CFMutableDictionaryRef glyphDict = (CFMutableDictionaryRef)CFDictionaryGetValue(cache, font);
|
||||||
if(glyphDict == NULL)
|
if(!glyphDict)
|
||||||
{
|
{
|
||||||
// And if this font hasn't been seen before, we'll create and set the dictionary for it
|
// And if this font hasn't been seen before, we'll create and set the dictionary for it
|
||||||
glyphDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
|
glyphDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
|
||||||
@@ -38,11 +38,11 @@
|
|||||||
}
|
}
|
||||||
// Next we try to get a path for the given glyph from the glyph dictionary
|
// Next we try to get a path for the given glyph from the glyph dictionary
|
||||||
CGPathRef path = (CGPathRef)CFDictionaryGetValue(glyphDict, (const void *)(uintptr_t)glyph);
|
CGPathRef path = (CGPathRef)CFDictionaryGetValue(glyphDict, (const void *)(uintptr_t)glyph);
|
||||||
if(path == NULL)
|
if(!path)
|
||||||
{
|
{
|
||||||
// If the path hasn't been seen before, then we'll create the path from the font & glyph and cache it.
|
// If the path hasn't been seen before, then we'll create the path from the font & glyph and cache it.
|
||||||
path = CTFontCreatePathForGlyph(font, glyph, NULL);
|
path = CTFontCreatePathForGlyph(font, glyph, NULL);
|
||||||
if(path == NULL)
|
if(!path)
|
||||||
{
|
{
|
||||||
// If a glyph does not have a path, then we need a placeholder to set in the dictionary
|
// If a glyph does not have a path, then we need a placeholder to set in the dictionary
|
||||||
path = (CGPathRef)kCFNull;
|
path = (CGPathRef)kCFNull;
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
|
|
||||||
- (BOOL) isPercentage:(NSString *) string
|
- (BOOL) isPercentage:(NSString *) string
|
||||||
{
|
{
|
||||||
return [percentageRegularExpression firstMatchInString:string options:0 range:NSMakeRange(0, [string length])] != NULL;
|
return [percentageRegularExpression firstMatchInString:string options:0 range:NSMakeRange(0, [string length])] != nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
15
ios/ViewManagers/RNSVGDefinationManager.h
Normal file
15
ios/ViewManagers/RNSVGDefinationManager.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* 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 "RCTViewManager.h"
|
||||||
|
|
||||||
|
@interface RNSVGDefinationManager : RCTViewManager
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#import "RNSVGNode.h"
|
||||||
31
ios/ViewManagers/RNSVGDefinationManager.m
Normal file
31
ios/ViewManagers/RNSVGDefinationManager.m
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* 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 "RNSVGDefination.h"
|
||||||
|
#import "RNSVGDefinationManager.h"
|
||||||
|
|
||||||
|
@implementation RNSVGDefinationManager
|
||||||
|
|
||||||
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
|
- (RNSVGDefination *)node
|
||||||
|
{
|
||||||
|
return [RNSVGDefination new];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIView *)view
|
||||||
|
{
|
||||||
|
return [self node];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (RCTShadowView *)shadowView
|
||||||
|
{
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -29,8 +29,9 @@ RCT_EXPORT_MODULE()
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_VIEW_PROPERTY(name, NSString)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(opacity, CGFloat)
|
RCT_EXPORT_VIEW_PROPERTY(opacity, CGFloat)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(trans, CGAffineTransform)
|
RCT_EXPORT_VIEW_PROPERTY(transform, CGAffineTransform)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(clipPathRef, NSString)
|
RCT_EXPORT_VIEW_PROPERTY(clipPathRef, NSString)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(responsible, BOOL)
|
RCT_EXPORT_VIEW_PROPERTY(responsible, BOOL)
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,6 @@
|
|||||||
|
|
||||||
#import "RNSVGRenderableManager.h"
|
#import "RNSVGRenderableManager.h"
|
||||||
|
|
||||||
@interface RNSVGShapeManager : RNSVGRenderableManager
|
@interface RNSVGUseManager : RNSVGRenderableManager
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -6,20 +6,19 @@
|
|||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "RNSVGShapeManager.h"
|
#import "RNSVGUseManager.h"
|
||||||
|
#import "RNSVGUse.h"
|
||||||
|
|
||||||
#import "RNSVGShape.h"
|
@implementation RNSVGUseManager
|
||||||
#import "RCTConvert+RNSVG.h"
|
|
||||||
|
|
||||||
@implementation RNSVGShapeManager
|
|
||||||
|
|
||||||
RCT_EXPORT_MODULE()
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
- (RNSVGRenderable *)node
|
- (RNSVGNode *)node
|
||||||
{
|
{
|
||||||
return [RNSVGShape new];
|
return [RNSVGUse new];
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_EXPORT_VIEW_PROPERTY(shape, NSDictionary)
|
|
||||||
|
RCT_EXPORT_VIEW_PROPERTY(href, NSString)
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -3,7 +3,7 @@ import _ from 'lodash';
|
|||||||
const merge = _.assign;
|
const merge = _.assign;
|
||||||
|
|
||||||
function arrayDiffer(a, b) {
|
function arrayDiffer(a, b) {
|
||||||
if (a == null || b == null) {
|
if (_.isNil(a) || _.isNil(b) ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (a.length !== b.length) {
|
if (a.length !== b.length) {
|
||||||
@@ -79,6 +79,10 @@ const GroupAttributes = merge(NodeAttributes, {
|
|||||||
clipRule: true
|
clipRule: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const UseAttributes = merge(RenderableAttributes, {
|
||||||
|
href: true
|
||||||
|
});
|
||||||
|
|
||||||
const PathAttributes = merge(RenderableAttributes, {
|
const PathAttributes = merge(RenderableAttributes, {
|
||||||
d: {
|
d: {
|
||||||
diff: arrayDiffer
|
diff: arrayDiffer
|
||||||
@@ -146,5 +150,6 @@ export {
|
|||||||
EllipseAttributes,
|
EllipseAttributes,
|
||||||
ImageAttributes,
|
ImageAttributes,
|
||||||
LineAttributes,
|
LineAttributes,
|
||||||
RectAttributes
|
RectAttributes,
|
||||||
|
UseAttributes
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,16 +6,14 @@ import extractResponder from './extractResponder';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
export default function(props, options = {stroke: true, transform: true, fill: true, responder: true}) {
|
export default function(props, options = {stroke: true, transform: true, fill: true, responder: true}) {
|
||||||
if (props.visible === false) {
|
|
||||||
return {
|
|
||||||
opacity: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let extractedProps = {
|
let extractedProps = {
|
||||||
opacity: +props.opacity || 1
|
opacity: +props.opacity || 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (props.id) {
|
||||||
|
extractedProps.name = props.id;
|
||||||
|
}
|
||||||
|
|
||||||
if (props.clipPath) {
|
if (props.clipPath) {
|
||||||
_.assign(extractedProps, extractClipping(props));
|
_.assign(extractedProps, extractClipping(props));
|
||||||
}
|
}
|
||||||
@@ -30,6 +28,10 @@ export default function(props, options = {stroke: true, transform: true, fill: t
|
|||||||
|
|
||||||
if (options.transform) {
|
if (options.transform) {
|
||||||
extractedProps.transform = extractTransform(props);
|
extractedProps.transform = extractTransform(props);
|
||||||
|
} else if (props.transform) {
|
||||||
|
// todo: add support for transform prop like this:
|
||||||
|
// {scale: 1.5, translate: '10 10'}
|
||||||
|
extractedProps.transform = props.transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.responder) {
|
if (options.responder) {
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ const clipProps = {
|
|||||||
clipPath: PropTypes.string
|
clipPath: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const definationProps = {
|
||||||
|
name: PropTypes.string
|
||||||
|
};
|
||||||
|
|
||||||
const strokeProps = {
|
const strokeProps = {
|
||||||
stroke: PropTypes.string,
|
stroke: PropTypes.string,
|
||||||
strokeWidth: numberProp,
|
strokeWidth: numberProp,
|
||||||
@@ -77,7 +81,8 @@ const pathProps = {
|
|||||||
...clipProps,
|
...clipProps,
|
||||||
...transformProps,
|
...transformProps,
|
||||||
...responderProps,
|
...responderProps,
|
||||||
...touchableProps
|
...touchableProps,
|
||||||
|
...definationProps
|
||||||
};
|
};
|
||||||
|
|
||||||
const circleProps = {
|
const circleProps = {
|
||||||
|
|||||||
Reference in New Issue
Block a user