Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F101420880
TouchRipple.js
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Mon, Feb 10, 07:09
Size
10 KB
Mime Type
text/x-java
Expires
Wed, Feb 12, 07:09 (2 d)
Engine
blob
Format
Raw Data
Handle
24156176
Attached To
rOACCT Open Access Compliance Check Tool (OACCT)
TouchRipple.js
View Options
import _extends from "@babel/runtime/helpers/esm/extends";
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import _taggedTemplateLiteral from "@babel/runtime/helpers/esm/taggedTemplateLiteral";
var _templateObject, _templateObject2, _templateObject3, _templateObject4;
import * as React from 'react';
import PropTypes from 'prop-types';
import { TransitionGroup } from 'react-transition-group';
import clsx from 'clsx';
import { keyframes } from '@mui/system';
import styled from '../styles/styled';
import useThemeProps from '../styles/useThemeProps';
import Ripple from './Ripple';
import touchRippleClasses from './touchRippleClasses';
import { jsx as _jsx } from "react/jsx-runtime";
var DURATION = 550;
export var DELAY_RIPPLE = 80;
var enterKeyframe = keyframes(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n 0% {\n transform: scale(0);\n opacity: 0.1;\n }\n\n 100% {\n transform: scale(1);\n opacity: 0.3;\n }\n"])));
var exitKeyframe = keyframes(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n 0% {\n opacity: 1;\n }\n\n 100% {\n opacity: 0;\n }\n"])));
var pulsateKeyframe = keyframes(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n 0% {\n transform: scale(1);\n }\n\n 50% {\n transform: scale(0.92);\n }\n\n 100% {\n transform: scale(1);\n }\n"])));
export var TouchRippleRoot = styled('span', {
name: 'MuiTouchRipple',
slot: 'Root'
})({
overflow: 'hidden',
pointerEvents: 'none',
position: 'absolute',
zIndex: 0,
top: 0,
right: 0,
bottom: 0,
left: 0,
borderRadius: 'inherit'
});
// This `styled()` function invokes keyframes. `styled-components` only supports keyframes
// in string templates. Do not convert these styles in JS object as it will break.
export var TouchRippleRipple = styled(Ripple, {
name: 'MuiTouchRipple',
slot: 'Ripple'
})(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n opacity: 0;\n position: absolute;\n\n &.", " {\n opacity: 0.3;\n transform: scale(1);\n animation-name: ", ";\n animation-duration: ", "ms;\n animation-timing-function: ", ";\n }\n\n &.", " {\n animation-duration: ", "ms;\n }\n\n & .", " {\n opacity: 1;\n display: block;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n background-color: currentColor;\n }\n\n & .", " {\n opacity: 0;\n animation-name: ", ";\n animation-duration: ", "ms;\n animation-timing-function: ", ";\n }\n\n & .", " {\n position: absolute;\n /* @noflip */\n left: 0px;\n top: 0;\n animation-name: ", ";\n animation-duration: 2500ms;\n animation-timing-function: ", ";\n animation-iteration-count: infinite;\n animation-delay: 200ms;\n }\n"])), touchRippleClasses.rippleVisible, enterKeyframe, DURATION, function (_ref) {
var theme = _ref.theme;
return theme.transitions.easing.easeInOut;
}, touchRippleClasses.ripplePulsate, function (_ref2) {
var theme = _ref2.theme;
return theme.transitions.duration.shorter;
}, touchRippleClasses.child, touchRippleClasses.childLeaving, exitKeyframe, DURATION, function (_ref3) {
var theme = _ref3.theme;
return theme.transitions.easing.easeInOut;
}, touchRippleClasses.childPulsate, pulsateKeyframe, function (_ref4) {
var theme = _ref4.theme;
return theme.transitions.easing.easeInOut;
});
/**
* @ignore - internal component.
*
* TODO v5: Make private
*/
var TouchRipple = /*#__PURE__*/React.forwardRef(function TouchRipple(inProps, ref) {
var props = useThemeProps({
props: inProps,
name: 'MuiTouchRipple'
});
var _props$center = props.center,
centerProp = _props$center === void 0 ? false : _props$center,
_props$classes = props.classes,
classes = _props$classes === void 0 ? {} : _props$classes,
className = props.className,
other = _objectWithoutProperties(props, ["center", "classes", "className"]);
var _React$useState = React.useState([]),
ripples = _React$useState[0],
setRipples = _React$useState[1];
var nextKey = React.useRef(0);
var rippleCallback = React.useRef(null);
React.useEffect(function () {
if (rippleCallback.current) {
rippleCallback.current();
rippleCallback.current = null;
}
}, [ripples]);
// Used to filter out mouse emulated events on mobile.
var ignoringMouseDown = React.useRef(false);
// We use a timer in order to only show the ripples for touch "click" like events.
// We don't want to display the ripple for touch scroll events.
var startTimer = React.useRef(null);
// This is the hook called once the previous timeout is ready.
var startTimerCommit = React.useRef(null);
var container = React.useRef(null);
React.useEffect(function () {
return function () {
clearTimeout(startTimer.current);
};
}, []);
var startCommit = React.useCallback(function (params) {
var pulsate = params.pulsate,
rippleX = params.rippleX,
rippleY = params.rippleY,
rippleSize = params.rippleSize,
cb = params.cb;
setRipples(function (oldRipples) {
return [].concat(_toConsumableArray(oldRipples), [/*#__PURE__*/_jsx(TouchRippleRipple, {
classes: {
ripple: clsx(classes.ripple, touchRippleClasses.ripple),
rippleVisible: clsx(classes.rippleVisible, touchRippleClasses.rippleVisible),
ripplePulsate: clsx(classes.ripplePulsate, touchRippleClasses.ripplePulsate),
child: clsx(classes.child, touchRippleClasses.child),
childLeaving: clsx(classes.childLeaving, touchRippleClasses.childLeaving),
childPulsate: clsx(classes.childPulsate, touchRippleClasses.childPulsate)
},
timeout: DURATION,
pulsate: pulsate,
rippleX: rippleX,
rippleY: rippleY,
rippleSize: rippleSize
}, nextKey.current)]);
});
nextKey.current += 1;
rippleCallback.current = cb;
}, [classes]);
var start = React.useCallback(function () {
var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var cb = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {};
var _options$pulsate = options.pulsate,
pulsate = _options$pulsate === void 0 ? false : _options$pulsate,
_options$center = options.center,
center = _options$center === void 0 ? centerProp || options.pulsate : _options$center,
_options$fakeElement = options.fakeElement,
fakeElement = _options$fakeElement === void 0 ? false : _options$fakeElement;
if ((event == null ? void 0 : event.type) === 'mousedown' && ignoringMouseDown.current) {
ignoringMouseDown.current = false;
return;
}
if ((event == null ? void 0 : event.type) === 'touchstart') {
ignoringMouseDown.current = true;
}
var element = fakeElement ? null : container.current;
var rect = element ? element.getBoundingClientRect() : {
width: 0,
height: 0,
left: 0,
top: 0
};
// Get the size of the ripple
var rippleX;
var rippleY;
var rippleSize;
if (center || event === undefined || event.clientX === 0 && event.clientY === 0 || !event.clientX && !event.touches) {
rippleX = Math.round(rect.width / 2);
rippleY = Math.round(rect.height / 2);
} else {
var _ref5 = event.touches && event.touches.length > 0 ? event.touches[0] : event,
clientX = _ref5.clientX,
clientY = _ref5.clientY;
rippleX = Math.round(clientX - rect.left);
rippleY = Math.round(clientY - rect.top);
}
if (center) {
rippleSize = Math.sqrt((2 * Math.pow(rect.width, 2) + Math.pow(rect.height, 2)) / 3);
// For some reason the animation is broken on Mobile Chrome if the size is even.
if (rippleSize % 2 === 0) {
rippleSize += 1;
}
} else {
var sizeX = Math.max(Math.abs((element ? element.clientWidth : 0) - rippleX), rippleX) * 2 + 2;
var sizeY = Math.max(Math.abs((element ? element.clientHeight : 0) - rippleY), rippleY) * 2 + 2;
rippleSize = Math.sqrt(Math.pow(sizeX, 2) + Math.pow(sizeY, 2));
}
// Touche devices
if (event != null && event.touches) {
// check that this isn't another touchstart due to multitouch
// otherwise we will only clear a single timer when unmounting while two
// are running
if (startTimerCommit.current === null) {
// Prepare the ripple effect.
startTimerCommit.current = function () {
startCommit({
pulsate: pulsate,
rippleX: rippleX,
rippleY: rippleY,
rippleSize: rippleSize,
cb: cb
});
};
// Delay the execution of the ripple effect.
startTimer.current = setTimeout(function () {
if (startTimerCommit.current) {
startTimerCommit.current();
startTimerCommit.current = null;
}
}, DELAY_RIPPLE); // We have to make a tradeoff with this value.
}
} else {
startCommit({
pulsate: pulsate,
rippleX: rippleX,
rippleY: rippleY,
rippleSize: rippleSize,
cb: cb
});
}
}, [centerProp, startCommit]);
var pulsate = React.useCallback(function () {
start({}, {
pulsate: true
});
}, [start]);
var stop = React.useCallback(function (event, cb) {
clearTimeout(startTimer.current);
// The touch interaction occurs too quickly.
// We still want to show ripple effect.
if ((event == null ? void 0 : event.type) === 'touchend' && startTimerCommit.current) {
startTimerCommit.current();
startTimerCommit.current = null;
startTimer.current = setTimeout(function () {
stop(event, cb);
});
return;
}
startTimerCommit.current = null;
setRipples(function (oldRipples) {
if (oldRipples.length > 0) {
return oldRipples.slice(1);
}
return oldRipples;
});
rippleCallback.current = cb;
}, []);
React.useImperativeHandle(ref, function () {
return {
pulsate: pulsate,
start: start,
stop: stop
};
}, [pulsate, start, stop]);
return /*#__PURE__*/_jsx(TouchRippleRoot, _extends({
className: clsx(touchRippleClasses.root, classes.root, className),
ref: container
}, other, {
children: /*#__PURE__*/_jsx(TransitionGroup, {
component: null,
exit: true,
children: ripples
})
}));
});
process.env.NODE_ENV !== "production" ? TouchRipple.propTypes = {
/**
* If `true`, the ripple starts at the center of the component
* rather than at the point of interaction.
*/
center: PropTypes.bool,
/**
* Override or extend the styles applied to the component.
* See [CSS API](#css) below for more details.
*/
classes: PropTypes.object,
/**
* @ignore
*/
className: PropTypes.string
} : void 0;
export default TouchRipple;
Event Timeline
Log In to Comment