Skip to content

Commit

Permalink
[fixed] changing dropUp during a transition will cancel and restart t…
Browse files Browse the repository at this point in the history
…he correct animation
  • Loading branch information
jquense committed Dec 8, 2015
1 parent b84234a commit 3f7a001
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 30 deletions.
43 changes: 29 additions & 14 deletions dev/dev.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,24 +60,29 @@ var App = React.createClass({
console.log('rendered: ', +(new Date) - this.start)
this.start = null
}

if (this._changeDropUp) {
this._changeDropUp = false
this.setState({ dropUp: !this.state.dropUp })
}
},

render(){
var self = this;

function change(field, data) {
var obj = {}

if(field === 'selectValues' && Array.isArray(data))
data = data.map( d => d.id)

if(field === 'open') console.log(field, data)

obj[field] = data.hasOwnProperty('id') ? data.id : data

self.setState(obj)
//console.log('example: set field: ' + field, data)
}
// function change(field, data) {
// var obj = {}
//
// if(field === 'selectValues' && Array.isArray(data))
// data = data.map( d => d.id)
//
// if(field === 'open') console.log(field, data)
//
// obj[field] = data.hasOwnProperty('id') ? data.id : data
//
// self.setState(obj)
// //console.log('example: set field: ' + field, data)
// }

return (
<div style={{ fontSize: 14 }}>
Expand All @@ -91,11 +96,21 @@ var App = React.createClass({
>
add
</button>
<DateTimePicker format='YYYY-MM-DD' value={new Date()} time={false}/>
<DropdownList
dropUp={this.state.dropUp}
open={this.state.open}
onToggle={this.onToggle}
data={this.state.data}
/>
</section>
</div>
</div>
)
},

onToggle(open){
open && (this._changeDropUp = true)
this.setState({ open })
}


Expand Down
45 changes: 29 additions & 16 deletions src/Popup.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import compat from './util/compat';

var transform = config.animate.transform

const CLOSING = 0
, OPENING = 1
, NONE = 2;

function properties(prop, value){
var TRANSLATION_MAP = config.animate.TRANSLATION_MAP

Expand Down Expand Up @@ -75,7 +79,14 @@ module.exports = React.createClass({
componentDidUpdate(pvProps){
var closing = pvProps.open && !this.props.open
, opening = !pvProps.open && this.props.open
, open = this.props.open;
, open = this.props.open;

if (pvProps.dropUp !== this.props.dropUp && this.transitionState !== NONE) {
this._transition && this._transition.cancel()
this.reset()
opening = this.transitionState === OPENING
closing = this.transitionState === CLOSING
}

if (opening) this.open()
else if (closing) this.close()
Expand Down Expand Up @@ -110,7 +121,7 @@ module.exports = React.createClass({
)
},

reset(){
reset() {
var container = compat.findDOMNode(this)
, content = compat.findDOMNode(this.refs.content)
, style = { display: 'block', overflow: 'hidden'}
Expand Down Expand Up @@ -140,7 +151,7 @@ module.exports = React.createClass({
, el = compat.findDOMNode(this.refs.content);

this.ORGINAL_POSITION = css(el, 'position')
this._isOpening = true
this.transitionState = OPENING;

if (this._initialPosition) {
this._initialPosition = false
Expand All @@ -154,51 +165,53 @@ module.exports = React.createClass({
anim.className += ' rw-popup-animating'
el.style.position = 'absolute'

config.animate(el
this._transition = config.animate(el
, { top: 0 }
, self.props.duration
, 'ease'
, function(){
if ( !self._isOpening ) return
, () => {
if (this.transitionState !== OPENING) return

this.transitionState = NONE;
anim.className = anim.className.replace(/ ?rw-popup-animating/g, '')

el.style.position = self.ORGINAL_POSITION
anim.style.overflow = 'visible'
self.ORGINAL_POSITION = null
this.ORGINAL_POSITION = null

self.props.onOpen()
this.props.onOpen()
})
},

close(dur) {
var self = this
, el = compat.findDOMNode(this.refs.content)
var el = compat.findDOMNode(this.refs.content)
, anim = compat.findDOMNode(this);

this.ORGINAL_POSITION = css(el, 'position')

this._isOpening = false
this.transitionState = CLOSING;

this.height()
this.props.onClosing()

anim.style.overflow = 'hidden'
anim.className += ' rw-popup-animating'
el.style.position = 'absolute'

config.animate(el
this._transition = config.animate(el
, { top: this.props.dropUp ? '100%' : '-100%' }
, dur === undefined ? this.props.duration : dur
, 'ease'
, function() {
if ( self._isOpening ) return
, () => {
if (this.transitionState !== CLOSING) return

this.transitionState = NONE;
el.style.position = self.ORGINAL_POSITION
anim.className = anim.className.replace(/ ?rw-popup-animating/g, '')

anim.style.display = 'none'
self.ORGINAL_POSITION = null
self.props.onClose()
this.ORGINAL_POSITION = null
this.props.onClose()
})
}

Expand Down
9 changes: 9 additions & 0 deletions src/util/dom/animate.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ export default function animate(node, properties, duration, easing, callback){
if (duration <= 0)
setTimeout(done.bind(null, fakeEvent), 0)

return {
cancel() {
if (fired) return
fired = true
off(event.target, transitionProps.end, done)
css(node, reset)
}
}

function done(event) {
if (event.target !== event.currentTarget) return

Expand Down

0 comments on commit 3f7a001

Please sign in to comment.