Skip to content

Commit

Permalink
Reproduce tween-state functionalities with state-stream
Browse files Browse the repository at this point in the history
  • Loading branch information
chenglou committed Jan 9, 2015
1 parent 963f5d6 commit 994b449
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 83 deletions.
78 changes: 0 additions & 78 deletions App2.jsx

This file was deleted.

109 changes: 109 additions & 0 deletions App2/App2.jsx
@@ -0,0 +1,109 @@
/*global -React */
var React = require('react');
var M = require('mori');
var stateStream = require('../stateStream');
var easingTypes = require('../easingTypes');
var tweenMixin = require('./tweenMixin');

var ease = easingTypes.easeInOutQuad;

var App2 = React.createClass({
mixins: [stateStream.Mixin, tweenMixin],
getInitialStateStream: function() {
return M.repeat(1, M.js_to_clj({
blockX: [0, 0],
goingLeft: false,
contrib: [],
}));
},

handleClick: function() {
var duration = 1000;
var frameCount = stateStream.toFrameCount(duration);
var initState = this.state;
var start = initState.goingLeft ? 400 : 0;
var dest = initState.goingLeft ? 0 : 400;

var newStream = M.map(function(stateI) {
return M.assoc(stateI, 'goingLeft', !initState.goingLeft);
}, this.stream);

newStream = this.mapState(newStream, duration, function(stateI, ms) {
return M.assoc_in(
stateI,
['blockX', 0],
ease(ms, start, dest, duration)
);
});

newStream = this.mapState(newStream, duration, function(stateI, ms) {
return M.assoc_in(
stateI,
['blockX', 1],
ease(ms, initState.blockX[1], dest, duration)
);
});

newStream = this.mapChunk(newStream, duration, function(stateI, ms) {
var contrib = ease(ms, start, dest, duration) - dest;

return M.assoc(stateI,
'contrib',
M.conj(M.get(stateI, 'contrib'), contrib)
);
});

this.setStateStream(newStream);
},

render: function() {
var s1 = {
border: '1px solid gray',
borderRadius: '10px',
display: 'inline-block',
padding: 20,
position: 'absolute',
top: 10,
WebkitTransform: 'translate3d(' + this.state.blockX[0] + 'px,0,0)',
transform: 'translate3d(' + this.state.blockX[0] + 'px,0,0)',
};
var s2 = {
border: '1px solid gray',
borderRadius: '10px',
display: 'inline-block',
padding: 20,
position: 'absolute',
top: 60,
WebkitTransform: 'translate3d(' + this.state.blockX[1] + 'px,0,0)',
transform: 'translate3d(' + this.state.blockX[1] + 'px,0,0)',
};

var val = this.state.contrib.reduce(function(a, x) {
return a + x;
}, this.state.goingLeft ? 400 : 0);

// var val = this.getAdditiveValue(['']);

var s3 = {
border: '1px solid gray',
borderRadius: '10px',
display: 'inline-block',
padding: 20,
position: 'absolute',
top: 110,
WebkitTransform: 'translate3d(' + val + 'px,0,0)',
transform: 'translate3d(' + val + 'px,0,0)',
};

return (
<div style={{height: 180}}>
<button onClick={this.handleClick}>Click</button>
<div style={s1}></div>
<div style={s2}></div>
<div style={s3}></div>
</div>
);
}
});

module.exports = App2;
14 changes: 14 additions & 0 deletions App2/tweenMixin copy.js
@@ -0,0 +1,14 @@
// react-tween-state provides additive animation as a default, just like iOS.
// there's really nothing (tween-state/state-stream)-specific about additive
// animation: it's just math. http://iosoteric.com/additive-animations-animatewithduration-in-ios-8/

// tween-state users who stumbled upon this lib

// the mixin adds a
var additiveMixin = {
getTweeningValue: function(path) {

}
};

module.exports = additiveMixin;
42 changes: 42 additions & 0 deletions App2/tweenMixin.js
@@ -0,0 +1,42 @@
var stateStream = require('../stateStream');
var M = require('mori');

var tweenMixin = {
// TODO: prolly doesn't have to be a mixin
// TODO: better name
mapState: function(stream, duration, cb) {
var frameCount = stateStream.toFrameCount(duration);
var newStream = stateStream.extendTo(frameCount + 1, stream);

var chunk = M.map(
cb,
M.take(frameCount, newStream),
M.map(stateStream.toMs, M.range())
);

var restChunk = M.map(
cb,
M.drop(frameCount, newStream),
M.map(stateStream.toMs, M.repeat(frameCount))
);

return M.concat(chunk, restChunk);
},

mapChunk: function(stream, duration, cb) {
var frameCount = stateStream.toFrameCount(duration);
var newStream = stateStream.extendTo(frameCount, stream);

var chunk = M.map(
cb,
M.take(frameCount, newStream),
M.map(stateStream.toMs, M.range())
);

var restChunk = M.drop(frameCount, stream);

return M.concat(chunk, restChunk);
}
};

module.exports = tweenMixin;
4 changes: 2 additions & 2 deletions App4/App4.jsx
Expand Up @@ -12,7 +12,7 @@ function toObj(children) {
});
}

var ease = easingTypes.easeInOutQuad;
var ease = easingTypes.linear;

var Container = React.createClass({
mixins: [stateStream.Mixin],
Expand Down Expand Up @@ -64,7 +64,7 @@ var Container = React.createClass({
children[key] = nextChildrenMap[key] || this.state.children[key];
}, this);

var duration = 2700;
var duration = 700;
var frameCount = stateStream.toFrameCount(duration);
var initState = this.state;
var newStream = stateStream.extendTo(frameCount + 1, this.stream);
Expand Down
1 change: 1 addition & 0 deletions index.html
Expand Up @@ -8,6 +8,7 @@
<div id="content1"></div>
<div id="content2"></div>
<div id="content3"></div>
<div id="content4"></div>

<script src="out.js"></script>
</body>
Expand Down
8 changes: 5 additions & 3 deletions index.jsx
@@ -1,9 +1,11 @@
/*global -React */
var React = require('react');
var App1 = require('./App1.jsx');
var App2 = require('./App2.jsx');
var App2 = require('./App2/App2.jsx');
var App3 = require('./App3.jsx');
var App4 = require('./App4/App4.jsx');

React.render(<App1 />, document.getElementById('content1'));
// React.render(<App1 />, document.getElementById('content1'));
React.render(<App2 />, document.getElementById('content2'));
React.render(<App3 />, document.getElementById('content3'));
// React.render(<App3 />, document.getElementById('content3'));
// React.render(<App4 />, document.getElementById('content4'));

0 comments on commit 994b449

Please sign in to comment.