add touchable support for shape elements

This commit is contained in:
Horcrux
2016-06-09 23:30:10 +08:00
parent 16b4f741f5
commit 7307715712
12 changed files with 123 additions and 67 deletions
+1 -2
View File
@@ -568,8 +568,7 @@ npm install
1. add native method for elements
2. more Text features support
3. Pattern element
4. implement touchable elements
5. implement Animated elements
4. implement Animated elements
#### Thanks:
-18
View File
@@ -4,11 +4,9 @@ import createNativeComponent from '../lib/createNativeComponent';
import mergeContext from '../lib/mergeContext';
import {circleProps, pathProps, fillProps, strokeProps, numberProp} from '../lib/props';
class Circle extends Component{
static displayName = 'Circle';
static propTypes = {
...pathProps,
...circleProps
};
static contextTypes = {
@@ -19,28 +17,12 @@ class Circle extends Component{
svgId: numberProp
};
//constructor() {
// super(...arguments);
// _.forEach(SvgTouchableMixin, (method, key) => {
// this[key] = method.bind(this);
// });
//
// this.state = this.touchableGetInitialState();
//};
render() {
let props = mergeContext(this.props, this.context);
return <RNSVGCircle
{...extractProps(props)}
cx={props.cx.toString()}
cy={props.cy.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
View File
@@ -1,11 +1,11 @@
import React, {PropTypes, Component} from 'react';
import extractProps from '../lib/extract/extractProps';
import React, {PropTypes} from 'react';
import createNativeComponent from '../lib/createNativeComponent';
import mergeContext from '../lib/mergeContext';
import Shape from './Shape';
import {ellipseProps, pathProps, fillProps, strokeProps, numberProp} from '../lib/props';
class Ellipse extends Component{
class Ellipse extends Shape{
static displayName = 'Ellipse';
static propTypes = {
...pathProps,
@@ -23,7 +23,7 @@ class Ellipse extends Component{
render() {
let props = mergeContext(this.props, this.context);
return <RNSVGEllipse
{...extractProps(props)}
{...this.extractProps(props)}
cx={props.cx.toString()}
cy={props.cy.toString()}
rx={props.rx.toString()}
+4 -4
View File
@@ -1,11 +1,11 @@
import React, {Component, PropTypes} from 'react';
import extractProps from '../lib/extract/extractProps';
import React, {PropTypes} from 'react';
import createNativeComponent from '../lib/createNativeComponent';
import {numberProp} from '../lib/props';
import Shape from './Shape';
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
class Image extends Component{
class Image extends Shape {
static displayName = 'Image';
static propTypes = {
x: numberProp,
@@ -20,7 +20,7 @@ class Image extends Component{
render() {
let {props} = this;
return <RNSVGImage
{...extractProps(props, {transform: true, responder: true})}
{...this.extractProps(props, {transform: true, responder: true})}
x={props.x.toString()}
y={props.y.toString()}
width={props.width.toString()}
+4 -4
View File
@@ -1,10 +1,10 @@
import React, {PropTypes, Component} from 'react';
import extractProps from '../lib/extract/extractProps';
import React, {PropTypes} from 'react';
import createNativeComponent from '../lib/createNativeComponent';
import mergeContext from '../lib/mergeContext';
import Shape from './Shape';
import {lineProps, pathProps, fillProps, strokeProps, numberProp} from '../lib/props';
class Line extends Component{
class Line extends Shape {
static displayName = 'Line';
static propTypes = {
...pathProps,
@@ -22,7 +22,7 @@ class Line extends Component{
render() {
let props = mergeContext(this.props, this.context);
return <RNSVGLine
{...extractProps(props)}
{...this.extractProps(props)}
x1={props.x1.toString()}
y1={props.y1.toString()}
x2={props.x2.toString()}
+6 -13
View File
@@ -1,12 +1,12 @@
import React, {Component, PropTypes} from 'react';
import _ from 'lodash';
import React, {PropTypes} from 'react';
import Defs from './Defs';
import extractProps from '../lib/extract/extractProps';
import SerializablePath from '../lib/SerializablePath';
import createNativeComponent from '../lib/createNativeComponent';
import mergeContext from '../lib/mergeContext';
import Shape from './Shape';
import {pathProps, numberProp} from '../lib/props';
class Path extends Component{
class Path extends Shape {
static displayName = 'Path';
static propTypes = {
@@ -30,13 +30,7 @@ class Path extends Component{
};
render() {
let {props} = this;
if (this.context.isInGroup) {
props = _.defaults(this.context, props, {
isInGroup: null
});
}
let props = mergeContext(this.props, this.context);
if (props.id) {
return <Defs.Item
@@ -49,10 +43,9 @@ class Path extends Component{
}
let d = new SerializablePath(props.d).toJSON();
return (
<RNSVGPath
{...extractProps(props)}
{...this.extractProps(props)}
d={d}
/>
);
+4 -4
View File
@@ -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 extractProps from '../lib/extract/extractProps';
import createNativeComponent from '../lib/createNativeComponent';
import mergeContext from '../lib/mergeContext';
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 propTypes = {
...pathProps,
@@ -24,7 +24,7 @@ class Rect extends Component{
let props = mergeContext(this.props, this.context);
return <RNSVGRect
{...extractProps({
{...this.extractProps({
...props,
x: null,
y: null
+32
View File
@@ -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
View File
@@ -1,13 +1,13 @@
import React, {Component, PropTypes} from 'react';
import React, {PropTypes} from 'react';
import createNativeComponent from '../lib/createNativeComponent';
import Defs from './Defs';
import _ from 'lodash';
import extractProps from '../lib/extract/extractProps';
import extractText from '../lib/extract/extractText';
import mergeContext from '../lib/mergeContext';
import {numberProp, textProps, fillProps, strokeProps, pathProps} from '../lib/props';
import Shape from './Shape';
class Text extends Component{
class Text extends Shape {
static displayName = 'Text';
static propTypes = {
dx: numberProp,
@@ -27,13 +27,7 @@ class Text extends Component{
};
render() {
let {props} = this;
if (this.context.isInGroup) {
props = _.defaults(this.context, props, {
isInGroup: null
});
}
let props = mergeContext(this.props, this.context);
let x = 0;
if (props.x) {
+50
View File
@@ -3,6 +3,56 @@ const PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
export default {
...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) {
this.props.onPress && this.props.onPress(e);
},
+12 -5
View File
@@ -1,19 +1,26 @@
import {responderProps} from '../props';
import {responderProps, touchableProps} from '../props';
import _ from 'lodash';
export default function (props) {
let responsible;
let touchable;
return _.reduce(props, (prev, value, key) => {
if (value && responderProps[key]) {
if (value && (responderProps[key] || touchableProps[key])) {
prev[key] = value;
if (!touchable) {
if (!responsible) {
responsible = true;
prev.responsible = true;
}
if (!touchable && touchableProps[key]) {
touchable = true;
prev.touchable = true;
}
}
return prev;
}, {});
}, {
responsible: false,
touchable: false
});
}
+1 -2
View File
@@ -3,7 +3,6 @@ import {PanResponder} from 'react-native';
const numberProp = PropTypes.oneOfType([PropTypes.string, PropTypes.number]);
const touchableProps = {
disabled: PropTypes.bool,
onPress: PropTypes.func,
@@ -18,7 +17,7 @@ const touchableProps = {
const touchablePropsKeys = Object.keys(touchableProps);
const responderPropsKeys = [
...Object.keys(PanResponder.create({onStartShouldSetPanResponder: () => {}}).panHandlers),
...Object.keys(PanResponder.create({}).panHandlers),
'pointerEvents'
];