Skip to content

Shapes #89

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 16 commits into from
Oct 24, 2017
26 changes: 13 additions & 13 deletions ARKit.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
View,
Text,
NativeModules,
requireNativeComponent,
requireNativeComponent
} from 'react-native';

import generateId from './components/lib/generateId';
Expand All @@ -26,15 +26,15 @@ const TRACKING_REASONS = [
'NONE',
'INITIALIZING',
'EXCESSIVE_MOTION',
'INSUFFICIENT_FEATURES',
'INSUFFICIENT_FEATURES'
];
const TRACKING_STATES_COLOR = ['red', 'orange', 'green'];

class ARKit extends Component {
state = {
state: 0,
reason: 0,
floor: null,
floor: null
};
componentWillMount() {
ARKitManager.clearScene();
Expand All @@ -55,7 +55,7 @@ class ARKit extends Component {
<View
style={[
styles.stateIcon,
{ backgroundColor: TRACKING_STATES_COLOR[this.state.state] },
{ backgroundColor: TRACKING_STATES_COLOR[this.state.state] }
]}
/>
<Text style={styles.stateText}>
Expand Down Expand Up @@ -84,21 +84,21 @@ class ARKit extends Component {
_onTrackingState = ({
state = this.state.state,
reason = this.state.reason,
floor,
floor
}) => {
if (this.props.onTrackingState) {
this.props.onTrackingState({
state: TRACKING_STATES[state] || state,
reason: TRACKING_REASONS[reason] || reason,
floor,
floor
});
}

if (this.props.debug) {
this.setState({
state,
reason,
floor: floor ? floor.toFixed(2) : this.state.floor,
floor: floor ? floor.toFixed(2) : this.state.floor
});
}
};
Expand Down Expand Up @@ -138,19 +138,19 @@ const styles = StyleSheet.create({
borderRadius: 10,
padding: 4,
backgroundColor: 'black',
flexDirection: 'row',
flexDirection: 'row'
},
stateIcon: {
width: 12,
height: 12,
borderRadius: 6,
marginRight: 4,
marginRight: 4
},
stateText: {
color: 'white',
fontSize: 10,
height: 12,
},
height: 12
}
});

// copy all ARKitManager properties to ARKit
Expand All @@ -160,7 +160,7 @@ Object.keys(ARKitManager).forEach(key => {

const addDefaultsToSnapShotFunc = funcName => ({
target = 'cameraRoll',
format = 'png',
format = 'png'
}) => ARKitManager[funcName]({ target, format });

ARKit.snapshot = addDefaultsToSnapShotFunc('snapshot');
Expand All @@ -182,7 +182,7 @@ ARKit.propTypes = {
onTrackingState: PropTypes.func,
onTapOnPlaneUsingExtent: PropTypes.func,
onTapOnPlaneNoExtent: PropTypes.func,
onEvent: PropTypes.func,
onEvent: PropTypes.func
};

const RCTARKit = requireNativeComponent('RCTARKit', ARKit);
Expand Down
46 changes: 42 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@ There is a Slack group that anyone can join for help / support / general questio

`$ react-native link react-native-arkit`

! Currently automatic installation does not work as PocketSVG is missing. Follow the manual installation

### Manual installation


#### iOS

1. In XCode, in the project navigator, right click `Libraries` ➜ `Add Files to [your project's name]`
2. Go to `node_modules` ➜ `react-native-arkit` and add `RCTARKit.xcodeproj`
3. In XCode, in the project navigator, select your project. Add `libRCTARKit.a` to your project's `Build Phases` ➜ `Link Binary With Libraries`
4. Run your project (`Cmd+R`)<
2. Go to `node_modules` ➜ add `react-native-arkit/RCTARKit.xcodeproj` and `_PocketSVG/_PocketSVG.xcodeproj`
3. In XCode, in the project navigator, select your project. Add `libRCTARKit.a` `and PocketSVG.framework` to your project's `Build Phases` ➜ `Link Binary With Libraries`
4. In Tab `General` ➜ `Embedded Binaries` ➜ `+` ➜ Add `PocketSVG.framework ios`
5. Run your project (`Cmd+R`)<


## Usage
Expand Down Expand Up @@ -100,11 +103,32 @@ export default class ReactNativeARKit extends Component {
/>
<ARKit.Model
position={{ x: -0.2, y: 0, z: 0, frame: 'local' }}
scale={0.01},
model={{
file: 'art.scnassets/ship.scn', // make sure you have the model file in the ios project
scale: 0.01,
}}
/>
<ARKit.Shape
position={{ x: -1, y: 0, z: 0 }}
eulerAngles={{
x: Math.PI,
}}
scale={0.01}
shape={{
// specify shape by svg! See https://github.com/HippoAR/react-native-arkit/pull/89 for details
pathSvg: `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<path d="M50,30c9-22 42-24 48,0c5,40-40,40-48,65c-8-25-54-25-48-65c 6-24 39-22 48,0 z" fill="#F00" stroke="#000"/>
</svg>`,
pathFlatness: 0.1,
// it's also possible to specify a chamfer profile:
chamferRadius: 5,
chamferProfilePathSvg: `
<path d="M.6 94.4c.7-7 0-13 6-18.5 1.6-1.4 5.3 1 6-.8l9.6 2.3C25 70.8 20.2 63 21 56c0-1.3 2.3-1 3.5-.7 7.6 1.4 7 15.6 14.7 13.2 1-.2 1.7-1 2-2 2-5-11.3-28.8-3-30.3 2.3-.4 5.7 1.8 6.7 0l8.4 6.5c.3-.4-8-17.3-2.4-21.6 7-5.4 14 5.3 17.7 7.8 1 .8 3 2 3.8 1 6.3-10-6-8.5-3.2-19 2-8.2 18.2-2.3 20.3-3 2.4-.6 1.7-5.6 4.2-6.4"/>
`,
extrusion: 10,
}}
/>
</ARKit>
</View>
);
Expand Down Expand Up @@ -273,6 +297,20 @@ SceneKit only supports `.scn` and `.dae` formats.
| `eulerAngles` | `{ x, y, z }` |
| `model` | `{ file, node, scale, alpha }` |

#### `<ARKit.Shape />`

Creates a extruded shape by an svg path.
See https://github.com/HippoAR/react-native-arkit/pull/89 for details

##### Props

| Prop | Type |
|---|---|
| `position` | `{ x, y, z }` |
| `eulerAngles` | `{ x, y, z }` |
| `shape` | `{ pathSvg, extrusion, pathFlatness, chamferRadius, chamferProfilePathSvg, chamferProfilePathFlatness }` |



## Contributing

Expand Down
18 changes: 18 additions & 0 deletions components/ARShape.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import PropTypes from 'prop-types';

import { chamferMode } from './lib/propTypes';
import createArComponent from './lib/createArComponent';

const ARShape = createArComponent('addShape', {
shape: PropTypes.shape({
extrusion: PropTypes.number,
pathSvg: PropTypes.string,
pathFlatness: PropTypes.number,
chamferMode,
chamferRadius: PropTypes.number,
chamferProfilePathSvg: PropTypes.string,
chamferProfilePathFlatness: PropTypes.string
})
});

module.exports = ARShape;
16 changes: 8 additions & 8 deletions components/ARSprite.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { Component } from 'react';
import withAnimationFrame from 'react-animation-frame';
import withAnimationFrame from '@panter/react-animation-frame';

import { NativeModules, Animated } from 'react-native';

Expand All @@ -13,7 +13,7 @@ const ARSprite = withAnimationFrame(
super(props);
this.state = {
zIndex: new Animated.Value(),
pos2D: new Animated.ValueXY(), // inits to zero
pos2D: new Animated.ValueXY() // inits to zero
};
}
onAnimationFrame() {
Expand All @@ -22,9 +22,9 @@ const ARSprite = withAnimationFrame(
{
x: this.state.pos2D.x,
y: this.state.pos2D.y,
z: this.state.zIndex,
},
]),
z: this.state.zIndex
}
])
);
}

Expand All @@ -34,18 +34,18 @@ const ARSprite = withAnimationFrame(
style={{
position: 'absolute',
transform: this.state.pos2D.getTranslateTransform(),
...this.props.style,
...this.props.style
}}
>
{this.props.children}
</Animated.View>
);
}
},
}
);

ARSprite.propTypes = {
position,
position
};

module.exports = ARSprite;
19 changes: 10 additions & 9 deletions components/lib/createArComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
orientation,
position,
rotation,
transition,
transition
} from './propTypes';
import { processColorInMaterial } from './parseColor';
import generateId from './generateId';
Expand All @@ -25,26 +25,27 @@ const NODE_PROPS = [
'position',
'eulerAngles',
'rotation',
'scale',
'orientation',
'transition',
'transition'
];
const KEYS_THAT_NEED_REMOUNT = ['material', 'shape', 'model'];

const nodeProps = (id, props) => ({
id,
...pick(props, NODE_PROPS),
...pick(props, NODE_PROPS)
});

export default (mountConfig, propTypes = {}) => {
const getShapeAndMaterialProps = props =>
typeof mountConfig === 'string'
? {
shape: props.shape,
material: processColorInMaterial(props.material),
material: processColorInMaterial(props.material)
}
: {
...pick(props, mountConfig.pick),
material: processColorInMaterial(props.material),
material: processColorInMaterial(props.material)
};

const mountFunc =
Expand All @@ -56,7 +57,7 @@ export default (mountConfig, propTypes = {}) => {
mountFunc(
getShapeAndMaterialProps(props),
nodeProps(id, props),
props.frame,
props.frame
);
};

Expand All @@ -71,7 +72,7 @@ export default (mountConfig, propTypes = {}) => {
componentWillUpdate(props) {
const changedKeys = filter(
keys(this.props),
key => !isDeepEqual(props[key], this.props[key]),
key => !isDeepEqual(props[key], this.props[key])
);

if (isEmpty(changedKeys)) {
Expand All @@ -87,7 +88,7 @@ export default (mountConfig, propTypes = {}) => {
// always include transition
ARGeosManager.update(
this.identifier,
pick(props, ['transition', ...changedKeys]),
pick(props, ['transition', ...changedKeys])
);
}
}
Expand All @@ -108,7 +109,7 @@ export default (mountConfig, propTypes = {}) => {
rotation,
orientation,
material,
...propTypes,
...propTypes
};

return ARComponent;
Expand Down
17 changes: 9 additions & 8 deletions components/lib/propTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,49 +8,50 @@ const ARKitManager = NativeModules.ARKitManager;
export const position = PropTypes.shape({
x: PropTypes.number,
y: PropTypes.number,
z: PropTypes.number,
z: PropTypes.number
});
export const transition = PropTypes.shape({
duration: PropTypes.number,
duration: PropTypes.number
});
export const eulerAngles = PropTypes.shape({
x: PropTypes.number,
y: PropTypes.number,
z: PropTypes.number,
z: PropTypes.number
});

export const rotation = PropTypes.shape({
x: PropTypes.number,
y: PropTypes.number,
z: PropTypes.number,
w: PropTypes.number,
w: PropTypes.number
});

export const orientation = PropTypes.shape({
x: PropTypes.number,
y: PropTypes.number,
z: PropTypes.number,
w: PropTypes.number,
w: PropTypes.number
});

export const shaders = PropTypes.shape({
[ARKitManager.ShaderModifierEntryPoint.Geometry]: PropTypes.string,
[ARKitManager.ShaderModifierEntryPoint.Surface]: PropTypes.string,
[ARKitManager.ShaderModifierEntryPoint.LightingModel]: PropTypes.string,
[ARKitManager.ShaderModifierEntryPoint.Fragment]: PropTypes.string,
[ARKitManager.ShaderModifierEntryPoint.Fragment]: PropTypes.string
});

export const lightingModel = PropTypes.oneOf(
values(ARKitManager.LightingModel),
values(ARKitManager.LightingModel)
);

export const blendMode = PropTypes.oneOf(values(ARKitManager.BlendMode));
export const chamferMode = PropTypes.oneOf(values(ARKitManager.ChamferMode));

export const material = PropTypes.shape({
color: PropTypes.string,
metalness: PropTypes.number,
roughness: PropTypes.number,
blendMode,
lightingModel,
shaders,
shaders
});
Loading