Skip to content
This repository was archived by the owner on Sep 28, 2023. It is now read-only.

Commit 084ae5d

Browse files
committed
Added options.transitionFriction and options.transitionTension
1 parent 23dc6ac commit 084ae5d

File tree

4 files changed

+70
-27
lines changed

4 files changed

+70
-27
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[![Build Status][travis-image]][travis-url]
44
[![NPM version][npm-image]][npm-url]
55

6-
A React view manager similar to [UINavigationController][ios-controller]
6+
React view manager similar to [UINavigationController][ios-controller]
77

88
## Instalation
99

@@ -128,6 +128,14 @@ navigationController.pushView(<MyView />, {
128128
});
129129
```
130130

131+
##### `options.transitonTension` `{number}` `default=10`
132+
133+
Specify the spring tension to be used for built-in animations
134+
135+
##### `options.transitonFriction` `{number}` `default=6`
136+
137+
Specify the spring friction to be used for built-in animations
138+
131139
##### `options.onComplete` `{function}`
132140

133141
Called once the transition has completed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "react-navigation-controller",
3-
"version": "1.0.1",
4-
"description": "A React view manager similar to UINavigationController",
3+
"version": "1.0.2",
4+
"description": "React view manager similar to UINavigationController",
55
"keywords": [
66
"react",
77
"react-component"

spec/navigation-controller.spec.jsx

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -296,12 +296,15 @@ describe('NavigationController', () => {
296296
});
297297
});
298298
it('sets the completion callback', () => {
299-
controller.__transitionViews(null, () => {});
299+
controller.__transitionViews({});
300300
expect(controller.__transitionViewsComplete).to.be.a('function');
301301
});
302302
it('sets and calls the completion callback', (done) => {
303303
const transitionCallbackSpy = sinon.spy();
304-
controller.__transitionViews(Transition.type.NONE, transitionCallbackSpy);
304+
controller.__transitionViews({
305+
transition: Transition.type.NONE,
306+
onComplete: transitionCallbackSpy
307+
});
305308
const transitionCompleteSpy = sinon.spy(controller, '__transitionViewsComplete');
306309
requestAnimationFrame(() => {
307310
expect(transitionCompleteSpy.calledOnce).to.be.true;
@@ -312,7 +315,9 @@ describe('NavigationController', () => {
312315
it('manually runs a "none" transition', (done) => {
313316
const transformSpy = sinon.spy(controller, '__transformViews');
314317
const animateCompleteSpy = sinon.spy(controller, '__animateViewsComplete');
315-
controller.__transitionViews(Transition.type.NONE);
318+
controller.__transitionViews({
319+
transition: Transition.type.NONE
320+
});
316321
const transitionCompleteSpy = sinon.spy(controller, '__transitionViewsComplete');
317322
requestAnimationFrame(() => {
318323
expect(transformSpy.calledOnce).to.be.true;
@@ -325,26 +330,32 @@ describe('NavigationController', () => {
325330
const animateSpy = sinon.spy(controller, '__animateViews');
326331
const transformSpy = sinon.spy(controller, '__transformViews');
327332
const animateCompleteSpy = sinon.spy(controller, '__animateViewsComplete');
328-
controller.__transitionViews(Transition.type.PUSH_LEFT, function() {
329-
expect(animateSpy.callCount).to.be.above(1);
330-
expect(transformSpy.callCount).to.be.above(1);
331-
expect(animateCompleteSpy.calledOnce).to.be.true;
332-
done();
333+
controller.__transitionViews({
334+
transition: Transition.type.PUSH_LEFT,
335+
onComplete() {
336+
expect(animateSpy.callCount).to.be.above(1);
337+
expect(transformSpy.callCount).to.be.above(1);
338+
expect(animateCompleteSpy.calledOnce).to.be.true;
339+
done();
340+
}
333341
});
334342
controller.__isTransitioning = true;
335343
});
336344
it('runs a custom transtion', (done) => {
337345
let _prevElement,_nextElement;
338-
controller.__transitionViews((prevElement, nextElement, done) => {
339-
_prevElement = prevElement;
340-
_nextElement = nextElement;
341-
prevElement.style[transformPrefix] = 'translate3d(10px, 20px, 0px)';
342-
nextElement.style[transformPrefix] = 'translate3d(30px, 40px, 0px)';
343-
setTimeout(done, 500);
344-
}, () => {
345-
expect(_prevElement.style[transformPrefix]).to.equal(`translate3d(10px, 20px, 0px)`);
346-
expect(_nextElement.style[transformPrefix]).to.equal(`translate3d(30px, 40px, 0px)`);
347-
done();
346+
controller.__transitionViews({
347+
transition(prevElement, nextElement, done) {
348+
_prevElement = prevElement;
349+
_nextElement = nextElement;
350+
prevElement.style[transformPrefix] = 'translate3d(10px, 20px, 0px)';
351+
nextElement.style[transformPrefix] = 'translate3d(30px, 40px, 0px)';
352+
setTimeout(done, 500);
353+
},
354+
onComplete() {
355+
expect(_prevElement.style[transformPrefix]).to.equal(`translate3d(10px, 20px, 0px)`);
356+
expect(_nextElement.style[transformPrefix]).to.equal(`translate3d(30px, 40px, 0px)`);
357+
done();
358+
}
348359
});
349360
});
350361
});

src/navigation-controller.jsx

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
const React = require('react');
22

33
const rebound = require('rebound');
4+
const {
5+
SpringSystem,
6+
SpringConfig,
7+
OrigamiValueConverter
8+
} = rebound;
49
const {
510
mapValueInRange
611
} = rebound.MathUtil;
@@ -89,7 +94,7 @@ class NavigationController extends React.Component {
8994
this.__isTransitioning = false;
9095
this.__viewStates = [];
9196
this.__viewIndexes = [0,1];
92-
this.__springSystem = new rebound.SpringSystem();
97+
this.__springSystem = new SpringSystem();
9398
this.__spring = this.__springSystem.createSpring(
9499
this.props.transitionTension,
95100
this.props.transitionFriction
@@ -229,7 +234,20 @@ class NavigationController extends React.Component {
229234
* @param {string} transition
230235
* @param {function} [onComplete] - Called once the transition is complete
231236
*/
232-
__transitionViews(transition, onComplete) {
237+
__transitionViews(options) {
238+
options = typeof options === 'object' ? options : {};
239+
const defaults = {
240+
transitionTension: this.props.transitionTension,
241+
transitionFriction: this.props.transitionFriction
242+
};
243+
options = assign({}, defaults, options);
244+
const {
245+
transition,
246+
transitionTension,
247+
transitionFriction,
248+
onComplete
249+
} = options;
250+
// Create a function that will be called once the
233251
this.__transitionViewsComplete = () => {
234252
delete this.__transitionViewsComplete;
235253
if (typeof onComplete === 'function') {
@@ -250,6 +268,12 @@ class NavigationController extends React.Component {
250268
}
251269
// Otherwise use the springs
252270
else {
271+
this.__spring.setSpringConfig(
272+
new SpringConfig(
273+
OrigamiValueConverter.tensionFromOrigamiValue(transitionTension),
274+
OrigamiValueConverter.frictionFromOrigamiValue(transitionFriction)
275+
)
276+
);
253277
this.__spring.setEndValue(1);
254278
}
255279
}
@@ -295,7 +319,7 @@ class NavigationController extends React.Component {
295319
options = assign({}, defaults, options, { view });
296320
checkOptions('pushView', options);
297321
if (this.__isTransitioning) return;
298-
const {transition,onComplete} = options;
322+
const {transition} = options;
299323
const [prev,next] = this.__viewIndexes;
300324
let views = this.state.views.slice();
301325
// Alternate mounted views order
@@ -319,7 +343,7 @@ class NavigationController extends React.Component {
319343
this.__viewStates.push(prevView.state);
320344
}
321345
// Transition
322-
this.__transitionViews(transition, onComplete);
346+
this.__transitionViews(options);
323347
});
324348
this.__isTransitioning = true;
325349
}
@@ -342,7 +366,7 @@ class NavigationController extends React.Component {
342366
throw new Error('popView() can only be called with two or more views in the stack')
343367
};
344368
if (this.__isTransitioning) return;
345-
const {transition,onComplete} = options;
369+
const {transition} = options;
346370
const [prev,next] = this.__viewIndexes;
347371
const views = dropRight(this.state.views);
348372
// Alternate mounted views order
@@ -368,7 +392,7 @@ class NavigationController extends React.Component {
368392
}
369393
}
370394
// Transition
371-
this.__transitionViews(transition, onComplete);
395+
this.__transitionViews(options);
372396
});
373397
this.__isTransitioning = true;
374398
}

0 commit comments

Comments
 (0)