mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-08 09:10:44 +00:00
add touchable support for shape elements
This commit is contained in:
@@ -568,8 +568,7 @@ npm install
|
|||||||
1. add native method for elements
|
1. add native method for elements
|
||||||
2. more Text features support
|
2. more Text features support
|
||||||
3. Pattern element
|
3. Pattern element
|
||||||
4. implement touchable elements
|
4. implement Animated elements
|
||||||
5. implement Animated elements
|
|
||||||
|
|
||||||
#### Thanks:
|
#### Thanks:
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,9 @@ import createNativeComponent from '../lib/createNativeComponent';
|
|||||||
import mergeContext from '../lib/mergeContext';
|
import mergeContext from '../lib/mergeContext';
|
||||||
import {circleProps, pathProps, fillProps, strokeProps, numberProp} from '../lib/props';
|
import {circleProps, pathProps, fillProps, strokeProps, numberProp} from '../lib/props';
|
||||||
|
|
||||||
class Circle extends Component{
|
|
||||||
static displayName = 'Circle';
|
static displayName = 'Circle';
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
...pathProps,
|
...pathProps,
|
||||||
...circleProps
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
@@ -19,28 +17,12 @@ class Circle extends Component{
|
|||||||
svgId: numberProp
|
svgId: numberProp
|
||||||
};
|
};
|
||||||
|
|
||||||
//constructor() {
|
|
||||||
// super(...arguments);
|
|
||||||
// _.forEach(SvgTouchableMixin, (method, key) => {
|
|
||||||
// this[key] = method.bind(this);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// this.state = this.touchableGetInitialState();
|
|
||||||
//};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let props = mergeContext(this.props, this.context);
|
let props = mergeContext(this.props, this.context);
|
||||||
return <RNSVGCircle
|
return <RNSVGCircle
|
||||||
{...extractProps(props)}
|
|
||||||
cx={props.cx.toString()}
|
cx={props.cx.toString()}
|
||||||
cy={props.cy.toString()}
|
cy={props.cy.toString()}
|
||||||
r={props.r.toString()}
|
r={props.r.toString()}
|
||||||
//onStartShouldSetResponder={this.touchableHandleStartShouldSetResponder}
|
|
||||||
//onResponderTerminationRequest={this.touchableHandleResponderTerminationRequest}
|
|
||||||
//onResponderGrant={this.touchableHandleResponderGrant}
|
|
||||||
//onResponderMove={this.touchableHandleResponderMove}
|
|
||||||
//onResponderRelease={this.touchableHandleResponderRelease}
|
|
||||||
//onResponderTerminate={this.touchableHandleResponderTerminate}
|
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -1,11 +1,11 @@
|
|||||||
import React, {PropTypes, Component} from 'react';
|
import React, {PropTypes} from 'react';
|
||||||
import extractProps from '../lib/extract/extractProps';
|
|
||||||
import createNativeComponent from '../lib/createNativeComponent';
|
import createNativeComponent from '../lib/createNativeComponent';
|
||||||
import mergeContext from '../lib/mergeContext';
|
import mergeContext from '../lib/mergeContext';
|
||||||
|
import Shape from './Shape';
|
||||||
import {ellipseProps, pathProps, fillProps, strokeProps, numberProp} from '../lib/props';
|
import {ellipseProps, pathProps, fillProps, strokeProps, numberProp} from '../lib/props';
|
||||||
|
|
||||||
|
|
||||||
class Ellipse extends Component{
|
class Ellipse extends Shape{
|
||||||
static displayName = 'Ellipse';
|
static displayName = 'Ellipse';
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
...pathProps,
|
...pathProps,
|
||||||
@@ -23,7 +23,7 @@ class Ellipse extends Component{
|
|||||||
render() {
|
render() {
|
||||||
let props = mergeContext(this.props, this.context);
|
let props = mergeContext(this.props, this.context);
|
||||||
return <RNSVGEllipse
|
return <RNSVGEllipse
|
||||||
{...extractProps(props)}
|
{...this.extractProps(props)}
|
||||||
cx={props.cx.toString()}
|
cx={props.cx.toString()}
|
||||||
cy={props.cy.toString()}
|
cy={props.cy.toString()}
|
||||||
rx={props.rx.toString()}
|
rx={props.rx.toString()}
|
||||||
|
|||||||
+4
-4
@@ -1,11 +1,11 @@
|
|||||||
import React, {Component, PropTypes} from 'react';
|
import React, {PropTypes} from 'react';
|
||||||
import extractProps from '../lib/extract/extractProps';
|
|
||||||
import createNativeComponent from '../lib/createNativeComponent';
|
import createNativeComponent from '../lib/createNativeComponent';
|
||||||
import {numberProp} from '../lib/props';
|
import {numberProp} from '../lib/props';
|
||||||
|
import Shape from './Shape';
|
||||||
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
|
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
|
||||||
|
|
||||||
|
|
||||||
class Image extends Component{
|
class Image extends Shape {
|
||||||
static displayName = 'Image';
|
static displayName = 'Image';
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
x: numberProp,
|
x: numberProp,
|
||||||
@@ -20,7 +20,7 @@ class Image extends Component{
|
|||||||
render() {
|
render() {
|
||||||
let {props} = this;
|
let {props} = this;
|
||||||
return <RNSVGImage
|
return <RNSVGImage
|
||||||
{...extractProps(props, {transform: true, responder: true})}
|
{...this.extractProps(props, {transform: true, responder: true})}
|
||||||
x={props.x.toString()}
|
x={props.x.toString()}
|
||||||
y={props.y.toString()}
|
y={props.y.toString()}
|
||||||
width={props.width.toString()}
|
width={props.width.toString()}
|
||||||
|
|||||||
+4
-4
@@ -1,10 +1,10 @@
|
|||||||
import React, {PropTypes, Component} from 'react';
|
import React, {PropTypes} from 'react';
|
||||||
import extractProps from '../lib/extract/extractProps';
|
|
||||||
import createNativeComponent from '../lib/createNativeComponent';
|
import createNativeComponent from '../lib/createNativeComponent';
|
||||||
import mergeContext from '../lib/mergeContext';
|
import mergeContext from '../lib/mergeContext';
|
||||||
|
import Shape from './Shape';
|
||||||
import {lineProps, pathProps, fillProps, strokeProps, numberProp} from '../lib/props';
|
import {lineProps, pathProps, fillProps, strokeProps, numberProp} from '../lib/props';
|
||||||
|
|
||||||
class Line extends Component{
|
class Line extends Shape {
|
||||||
static displayName = 'Line';
|
static displayName = 'Line';
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
...pathProps,
|
...pathProps,
|
||||||
@@ -22,7 +22,7 @@ class Line extends Component{
|
|||||||
render() {
|
render() {
|
||||||
let props = mergeContext(this.props, this.context);
|
let props = mergeContext(this.props, this.context);
|
||||||
return <RNSVGLine
|
return <RNSVGLine
|
||||||
{...extractProps(props)}
|
{...this.extractProps(props)}
|
||||||
x1={props.x1.toString()}
|
x1={props.x1.toString()}
|
||||||
y1={props.y1.toString()}
|
y1={props.y1.toString()}
|
||||||
x2={props.x2.toString()}
|
x2={props.x2.toString()}
|
||||||
|
|||||||
+6
-13
@@ -1,12 +1,12 @@
|
|||||||
import React, {Component, PropTypes} from 'react';
|
import React, {PropTypes} from 'react';
|
||||||
import _ from 'lodash';
|
|
||||||
import Defs from './Defs';
|
import Defs from './Defs';
|
||||||
import extractProps from '../lib/extract/extractProps';
|
|
||||||
import SerializablePath from '../lib/SerializablePath';
|
import SerializablePath from '../lib/SerializablePath';
|
||||||
import createNativeComponent from '../lib/createNativeComponent';
|
import createNativeComponent from '../lib/createNativeComponent';
|
||||||
|
import mergeContext from '../lib/mergeContext';
|
||||||
|
import Shape from './Shape';
|
||||||
import {pathProps, numberProp} from '../lib/props';
|
import {pathProps, numberProp} from '../lib/props';
|
||||||
|
|
||||||
class Path extends Component{
|
class Path extends Shape {
|
||||||
static displayName = 'Path';
|
static displayName = 'Path';
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@@ -30,13 +30,7 @@ class Path extends Component{
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let {props} = this;
|
let props = mergeContext(this.props, this.context);
|
||||||
|
|
||||||
if (this.context.isInGroup) {
|
|
||||||
props = _.defaults(this.context, props, {
|
|
||||||
isInGroup: null
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (props.id) {
|
if (props.id) {
|
||||||
return <Defs.Item
|
return <Defs.Item
|
||||||
@@ -49,10 +43,9 @@ class Path extends Component{
|
|||||||
}
|
}
|
||||||
|
|
||||||
let d = new SerializablePath(props.d).toJSON();
|
let d = new SerializablePath(props.d).toJSON();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RNSVGPath
|
<RNSVGPath
|
||||||
{...extractProps(props)}
|
{...this.extractProps(props)}
|
||||||
d={d}
|
d={d}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
+4
-4
@@ -1,11 +1,11 @@
|
|||||||
import React, {PropTypes, Component} from 'react';
|
import React, {PropTypes} from 'react';
|
||||||
import './Path'; // must import Path first, don`t know why. without this will throw an `Super expression must either be null or a function, not undefined`
|
import './Path'; // must import Path first, don`t know why. without this will throw an `Super expression must either be null or a function, not undefined`
|
||||||
import extractProps from '../lib/extract/extractProps';
|
|
||||||
import createNativeComponent from '../lib/createNativeComponent';
|
import createNativeComponent from '../lib/createNativeComponent';
|
||||||
import mergeContext from '../lib/mergeContext';
|
import mergeContext from '../lib/mergeContext';
|
||||||
import {rectProps, pathProps, fillProps, strokeProps, numberProp} from '../lib/props';
|
import {rectProps, pathProps, fillProps, strokeProps, numberProp} from '../lib/props';
|
||||||
|
import Shape from './Shape';
|
||||||
|
|
||||||
class Rect extends Component{
|
class Rect extends Shape {
|
||||||
static displayName = 'Rect';
|
static displayName = 'Rect';
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
...pathProps,
|
...pathProps,
|
||||||
@@ -24,7 +24,7 @@ class Rect extends Component{
|
|||||||
let props = mergeContext(this.props, this.context);
|
let props = mergeContext(this.props, this.context);
|
||||||
|
|
||||||
return <RNSVGRect
|
return <RNSVGRect
|
||||||
{...extractProps({
|
{...this.extractProps({
|
||||||
...props,
|
...props,
|
||||||
x: null,
|
x: null,
|
||||||
y: null
|
y: null
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import {Component} from 'react';
|
||||||
|
import extractProps from '../lib/extract/extractProps';
|
||||||
|
import SvgTouchableMixin from '../lib/SvgTouchableMixin';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
class Shape extends Component {
|
||||||
|
constructor() {
|
||||||
|
super(...arguments);
|
||||||
|
_.forEach(SvgTouchableMixin, (method, key) => {
|
||||||
|
this[key] = method.bind(this);
|
||||||
|
});
|
||||||
|
this.state = this.touchableGetInitialState();
|
||||||
|
}
|
||||||
|
|
||||||
|
extractProps = (props) => {
|
||||||
|
let extractedProps = extractProps(props);
|
||||||
|
if (extractedProps.touchable && !extractedProps.disabled) {
|
||||||
|
_.assign(extractedProps, {
|
||||||
|
onStartShouldSetResponder: this.touchableHandleStartShouldSetResponder,
|
||||||
|
onResponderTerminationRequest: this.touchableHandleResponderTerminationRequest,
|
||||||
|
onResponderGrant: this.touchableHandleResponderGrant,
|
||||||
|
onResponderMove: this.touchableHandleResponderMove,
|
||||||
|
onResponderRelease: this.touchableHandleResponderRelease,
|
||||||
|
onResponderTerminate: this.touchableHandleResponderTerminate
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return extractedProps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Shape;
|
||||||
+5
-11
@@ -1,13 +1,13 @@
|
|||||||
import React, {Component, PropTypes} from 'react';
|
import React, {PropTypes} from 'react';
|
||||||
import createNativeComponent from '../lib/createNativeComponent';
|
import createNativeComponent from '../lib/createNativeComponent';
|
||||||
import Defs from './Defs';
|
import Defs from './Defs';
|
||||||
import _ from 'lodash';
|
|
||||||
import extractProps from '../lib/extract/extractProps';
|
import extractProps from '../lib/extract/extractProps';
|
||||||
import extractText from '../lib/extract/extractText';
|
import extractText from '../lib/extract/extractText';
|
||||||
|
import mergeContext from '../lib/mergeContext';
|
||||||
import {numberProp, textProps, fillProps, strokeProps, pathProps} from '../lib/props';
|
import {numberProp, textProps, fillProps, strokeProps, pathProps} from '../lib/props';
|
||||||
|
import Shape from './Shape';
|
||||||
|
|
||||||
|
class Text extends Shape {
|
||||||
class Text extends Component{
|
|
||||||
static displayName = 'Text';
|
static displayName = 'Text';
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
dx: numberProp,
|
dx: numberProp,
|
||||||
@@ -27,13 +27,7 @@ class Text extends Component{
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let {props} = this;
|
let props = mergeContext(this.props, this.context);
|
||||||
|
|
||||||
if (this.context.isInGroup) {
|
|
||||||
props = _.defaults(this.context, props, {
|
|
||||||
isInGroup: null
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let x = 0;
|
let x = 0;
|
||||||
if (props.x) {
|
if (props.x) {
|
||||||
|
|||||||
@@ -3,6 +3,56 @@ const PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
...Touchable.Mixin,
|
...Touchable.Mixin,
|
||||||
|
|
||||||
|
touchableHandleStartShouldSetResponder: function (e) {
|
||||||
|
|
||||||
|
if (this.props.onStartShouldSetResponder) {
|
||||||
|
return this.props.onStartShouldSetResponder(e);
|
||||||
|
} else {
|
||||||
|
return Touchable.Mixin.touchableHandleStartShouldSetResponder.call(this, e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableHandleResponderTerminationRequest: function (e) {
|
||||||
|
if (this.props.onResponderTerminationRequest) {
|
||||||
|
return this.props.onResponderTerminationRequest(e);
|
||||||
|
} else {
|
||||||
|
return Touchable.Mixin.touchableHandleResponderTerminationRequest.call(this, e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableHandleResponderGrant: function (e) {
|
||||||
|
if (this.props.onResponderGrant) {
|
||||||
|
return this.props.onResponderGrant(e);
|
||||||
|
} else {
|
||||||
|
return Touchable.Mixin.touchableHandleResponderGrant.call(this, e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableHandleResponderMove: function (e) {
|
||||||
|
if (this.props.onResponderMove) {
|
||||||
|
return this.props.onResponderMove(e);
|
||||||
|
} else {
|
||||||
|
return Touchable.Mixin.touchableHandleResponderMove.call(this, e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableHandleResponderRelease: function (e) {
|
||||||
|
if (this.props.onResponderRelease) {
|
||||||
|
return this.props.onResponderRelease(e);
|
||||||
|
} else {
|
||||||
|
return Touchable.Mixin.touchableHandleResponderRelease.call(this, e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableHandleResponderTerminate: function (e) {
|
||||||
|
if (this.props.onResponderTerminate) {
|
||||||
|
return this.props.onResponderTerminate(e);
|
||||||
|
} else {
|
||||||
|
return Touchable.Mixin.touchableHandleResponderTerminate.call(this, e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
touchableHandlePress: function(e) {
|
touchableHandlePress: function(e) {
|
||||||
this.props.onPress && this.props.onPress(e);
|
this.props.onPress && this.props.onPress(e);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,19 +1,26 @@
|
|||||||
import {responderProps} from '../props';
|
import {responderProps, touchableProps} from '../props';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
export default function (props) {
|
export default function (props) {
|
||||||
|
let responsible;
|
||||||
let touchable;
|
let touchable;
|
||||||
|
|
||||||
return _.reduce(props, (prev, value, key) => {
|
return _.reduce(props, (prev, value, key) => {
|
||||||
if (value && responderProps[key]) {
|
if (value && (responderProps[key] || touchableProps[key])) {
|
||||||
prev[key] = value;
|
prev[key] = value;
|
||||||
|
if (!responsible) {
|
||||||
if (!touchable) {
|
responsible = true;
|
||||||
|
prev.responsible = true;
|
||||||
|
}
|
||||||
|
if (!touchable && touchableProps[key]) {
|
||||||
touchable = true;
|
touchable = true;
|
||||||
prev.touchable = true;
|
prev.touchable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return prev;
|
return prev;
|
||||||
}, {});
|
}, {
|
||||||
|
responsible: false,
|
||||||
|
touchable: false
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -3,7 +3,6 @@ import {PanResponder} from 'react-native';
|
|||||||
|
|
||||||
const numberProp = PropTypes.oneOfType([PropTypes.string, PropTypes.number]);
|
const numberProp = PropTypes.oneOfType([PropTypes.string, PropTypes.number]);
|
||||||
|
|
||||||
|
|
||||||
const touchableProps = {
|
const touchableProps = {
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
onPress: PropTypes.func,
|
onPress: PropTypes.func,
|
||||||
@@ -18,7 +17,7 @@ const touchableProps = {
|
|||||||
const touchablePropsKeys = Object.keys(touchableProps);
|
const touchablePropsKeys = Object.keys(touchableProps);
|
||||||
|
|
||||||
const responderPropsKeys = [
|
const responderPropsKeys = [
|
||||||
...Object.keys(PanResponder.create({onStartShouldSetPanResponder: () => {}}).panHandlers),
|
...Object.keys(PanResponder.create({}).panHandlers),
|
||||||
'pointerEvents'
|
'pointerEvents'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user