From 4f2dc3dbc4d0b709c5083f4e0ac8fad406c554dc Mon Sep 17 00:00:00 2001 From: Martin Bielik Date: Wed, 22 Feb 2017 16:09:15 +0100 Subject: [PATCH] fade in, fade out backdrop --- src/Backdrop.js | 47 ++++++++++++++++++++++++++++++------ src/MenuContext.js | 6 +++-- src/constants.js | 3 +++ src/renderers/ContextMenu.js | 5 ++-- src/renderers/SlideInMenu.js | 5 ++-- 5 files changed, 52 insertions(+), 14 deletions(-) create mode 100644 src/constants.js diff --git a/src/Backdrop.js b/src/Backdrop.js index 52872f1..a029f15 100644 --- a/src/Backdrop.js +++ b/src/Backdrop.js @@ -1,18 +1,49 @@ -import React from 'react'; -import { View, StyleSheet, TouchableWithoutFeedback } from 'react-native'; +import React, { Component } from 'react'; +import { View, StyleSheet, TouchableWithoutFeedback, Animated } from 'react-native'; +import { OPEN_ANIM_DURATION, CLOSE_ANIM_DURATION } from './constants'; -const Backdrop = props => ( - - - -); +class Backdrop extends Component { + + constructor(...args) { + super(...args); + this.fadeAnim = new Animated.Value(0.001); + } + + componentDidMount() { + Animated.timing(this.fadeAnim, { + duration: OPEN_ANIM_DURATION, + toValue: 1, + }).start(); + } + + close() { + return new Promise(resolve => { + Animated.timing(this.fadeAnim, { + duration: CLOSE_ANIM_DURATION, + toValue: 0, + }).start(resolve); + }); + } + + render() { + const { onPress, style } = this.props; + return ( + + + + + + ); + } + +} Backdrop.propTypes = { onPress: React.PropTypes.func.isRequired, }; const styles = StyleSheet.create({ - backdrop: { + fullscreen: { opacity: 0, position: 'absolute', top: 0, diff --git a/src/MenuContext.js b/src/MenuContext.js index 4c7e700..89810db 100644 --- a/src/MenuContext.js +++ b/src/MenuContext.js @@ -50,9 +50,11 @@ export default class MenuContext extends Component { closeMenu() { debug('close menu'); - const closePromise = (this.refs.menuOptions + const hideMenu = (this.refs.menuOptions && this.refs.menuOptions.close && this.refs.menuOptions.close()) || Promise.resolve(); + const hideBackdrop = this.refs.backdrop && this.refs.backdrop.close(); + const closePromise = Promise.all([hideMenu, hideBackdrop]); return closePromise.then(() => { this._menuRegistry.getAll().forEach(menu => { if (menu.instance._getOpened()) { @@ -129,7 +131,7 @@ export default class MenuContext extends Component { { this.props.children } {shouldRenderMenu && - this._onBackdropPress()} style={customStyles.backdrop} /> + this._onBackdropPress()} style={customStyles.backdrop} ref='backdrop' /> } {shouldRenderMenu && this._makeOptions(this.state.openedMenu) diff --git a/src/constants.js b/src/constants.js new file mode 100644 index 0000000..6b87abf --- /dev/null +++ b/src/constants.js @@ -0,0 +1,3 @@ +// common durations of animation +export const OPEN_ANIM_DURATION = 225; +export const CLOSE_ANIM_DURATION = 195; diff --git a/src/renderers/ContextMenu.js b/src/renderers/ContextMenu.js index 0fefea0..f371ef2 100644 --- a/src/renderers/ContextMenu.js +++ b/src/renderers/ContextMenu.js @@ -1,5 +1,6 @@ import React from 'react'; import { Animated, StyleSheet } from 'react-native'; +import { OPEN_ANIM_DURATION, CLOSE_ANIM_DURATION } from '../constants'; const axisPosition = (oDim, wDim, tPos, tDim) => { // if options are bigger than window dimension, then render at 0 @@ -48,7 +49,7 @@ export default class ContextMenu extends React.Component { componentDidMount() { Animated.timing(this.state.scaleAnim, { - duration: 225, + duration: OPEN_ANIM_DURATION, toValue: 1 }).start(); } @@ -56,7 +57,7 @@ export default class ContextMenu extends React.Component { close() { return new Promise(resolve => { Animated.timing(this.state.scaleAnim, { - duration: 195, + duration: CLOSE_ANIM_DURATION, toValue: 0 }).start(resolve); }); diff --git a/src/renderers/SlideInMenu.js b/src/renderers/SlideInMenu.js index 3349ec4..2ed0117 100644 --- a/src/renderers/SlideInMenu.js +++ b/src/renderers/SlideInMenu.js @@ -1,5 +1,6 @@ import React from 'react'; import { Animated, StyleSheet } from 'react-native'; +import { OPEN_ANIM_DURATION, CLOSE_ANIM_DURATION } from '../constants'; export const computePosition = ({ windowLayout, optionsLayout }) => { const { height: wHeight } = windowLayout; @@ -20,7 +21,7 @@ export default class SlideInMenu extends React.Component { componentDidMount() { Animated.timing(this.state.slide, { - duration: 225, + duration: OPEN_ANIM_DURATION, toValue: 1 }).start(); } @@ -28,7 +29,7 @@ export default class SlideInMenu extends React.Component { close() { return new Promise(resolve => { Animated.timing(this.state.slide, { - duration: 195, + duration: CLOSE_ANIM_DURATION, toValue: 0 }).start(resolve); });