Skip to content

Instantly share code, notes, and snippets.

@OlavHN
Last active August 29, 2015 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OlavHN/987bc0469bc501621b4f to your computer and use it in GitHub Desktop.
Save OlavHN/987bc0469bc501621b4f to your computer and use it in GitHub Desktop.
Drag to animation
'use strict';
module.exports = {
dragStart: function(state, onEnd) {
// We'll run the entire drag loop in this scope!
var component = this;
function getInput(evt) {
var evtObj = 'ontouchstart' in window ? evt.changedTouches[0] : evt;
return {x: evtObj.clientX, y: evtObj.clientY};
}
function dragMove(evt) {
evt.preventDefault();
// Update internal stuff
var input = getInput(evt);
var pos = {
x: input.x - state.offset.x,
y: input.y - state.offset.y
};
var dPos = {
x: pos.x - state.position.x,
y: pos.y - state.position.y
};
state.position = pos;
var dTime = Date.now() - state.time;
state.time = Date.now();
state.velocity = {
x: 0.8 * 1000 * dPos.x / (1 + dTime) + 0.2 * state.velocity.x,
y: 0.8 * 1000 * dPos.y / (1 + dTime) + 0.2 * state.velocity.y
};
// Update state
var stateObj = {};
stateObj[state.name] = {
position: state.position,
velocity: state.velocity
};
component.setState(stateObj);
}
function dragEnd(evt) {
evt.preventDefault();
document.removeEventListener('touchmove', dragMove);
document.removeEventListener('touchend', dragEnd);
document.removeEventListener('mousemove', dragMove);
document.removeEventListener('mouseup', dragEnd);
if (typeof onEnd === 'function')
onEnd();
}
return function(evt) {
evt.preventDefault();
var name = state.name ? state.name : state;
var input = getInput(evt);
var position;
if (component.state[name])
position = component.state[name].position;
else {
var rect = component.getDOMNode().getBoundingClientRect();
position = {x: rect.left, y: rect.top};
}
var offset = {
x: input.x - position.x,
y: input.y - position.y
};
// Hijack the reference as it's perfectly scoped!
state = {
name: state.name ? state.name : state,
offset: offset,
position: position,
velocity: {x: 0, y: 0},
time: Date.now()
};
// Update state
var stateObj = {};
stateObj[state.name] = {
position: state.position,
velocity: state.velocity
};
component.setState(stateObj);
document.addEventListener('touchmove', dragMove);
document.addEventListener('touchend', dragEnd);
document.addEventListener('mousemove', dragMove);
document.addEventListener('mouseup', dragEnd);
};
}
};
'use strict';
var React = require('react');
var RCSS = require('rcss');
var tweenState = require('react-tween-state');
var DragMixin = require('./mixins/drag-mixin');
var headerStyle = RCSS.registerClass({
position: 'relative',
width: '100%',
background: 'rgba(0, 0, 0, 0.5)',
boxSizing: 'border-box'
});
var headerBorderStyle = RCSS.registerClass({
position: 'absolute',
bottom: 0
});
var Header = React.createClass({
mixins: [
tweenState.Mixin,
DragMixin
],
render: function() {
if (!this.props.device)
return null;
// Get current tweened value
var height = this.props.height;
var y = this.state.headerTween ? this.getTweeningValue(function(state) { return state.headerTween.position; }, 'y') : - height * 2 + 30;
var inlineStyle = {
WebkitTransform: 'translate3d(0, ' + y + 'px, 0)',
transform: 'translate3d(0, ' + y + 'px, 0)',
height: height * 2,
paddingTop: height
};
var dragHandler = this.dragStart('headerTween', this.endDrag)
return (
<div onMouseDown={dragHandler} onTouchStart={dragHandler} className={headerStyle.className} style={inlineStyle}>
<div className={headerBorderStyle.className}>
GONZO
</div>
</div>
);
},
endDrag: function() {
var endPos = this.state.headerTween.position.y + 0.5 * this.state.headerTween.velocity.y;
var height = this.props.height;
// Animate either back up or all the way down
this.tweenState(function(state) { return state.headerTween.position}, 'y', {
initialVelocity: this.state.headerTween.velocity.y,
tension: 40,
friction: 5,
endValue: endPos > -height * 1.5 ? -height : -height * 2 + 30
});
}
});
module.exports = Header;
react-tween-state changes for rebound-js:
https://github.com/OlavHN/react-tween-state/commit/a4c2a09c1895c9ac1e73b74281d1bc491b30ec27
Example: http://olavhn.github.io/react-tween-state/
@OlavHN
Copy link
Author

OlavHN commented Dec 15, 2014

https://gist.github.com/OlavHN/987bc0469bc501621b4f#file-header-jsx-L41

I realize that is really stupid .. It'll execute the entire function on each render .. Must be moved to a new part or have the function return cached results ..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment