UNPKG

react-mdc-web

Version:

React web components for Material Design

133 lines (116 loc) 4.49 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTransformPropertyName = getTransformPropertyName; exports.clamp = clamp; exports.bezierProgress = bezierProgress; /** * Copyright 2016 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var storedTransformPropertyName_ = void 0; // Returns the name of the correct transform property to use on the current browser. function getTransformPropertyName(globalObj) { var forceRefresh = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; if (storedTransformPropertyName_ === undefined || forceRefresh) { var el = globalObj.document.createElement('div'); var transformPropertyName = 'transform' in el.style ? 'transform' : 'webkitTransform'; storedTransformPropertyName_ = transformPropertyName; } return storedTransformPropertyName_; } // Clamps a value between the minimum and the maximum, returning the clamped value. function clamp(value) { var min = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var max = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; return Math.min(max, Math.max(min, value)); } // Returns the easing value to apply at time t, for a given cubic bezier curve. // Control points P0 and P3 are assumed to be (0,0) and (1,1), respectively. // Paramters are as follows: // - time: The current time in the animation, scaled between 0 and 1. // - x1: The x value of control point P1. // - y1: The y value of control point P1. // - x2: The x value of control point P2. // - y2: The y value of control point P2. function bezierProgress(time, x1, y1, x2, y2) { return getBezierCoordinate_(solvePositionFromXValue_(time, x1, x2), y1, y2); } // Compute a single coordinate at a position point between 0 and 1. // c1 and c2 are the matching coordinate on control points P1 and P2, respectively. // Control points P0 and P3 are assumed to be (0,0) and (1,1), respectively. // Adapted from https://github.com/google/closure-library/blob/master/closure/goog/math/bezier.js. function getBezierCoordinate_(t, c1, c2) { // Special case start and end. if (t === 0 || t === 1) { return t; } // Step one - from 4 points to 3 var ic0 = t * c1; var ic1 = c1 + t * (c2 - c1); var ic2 = c2 + t * (1 - c2); // Step two - from 3 points to 2 ic0 += t * (ic1 - ic0); ic1 += t * (ic2 - ic1); // Final step - last point return ic0 + t * (ic1 - ic0); } // Project a point onto the Bezier curve, from a given X. Calculates the position t along the curve. // Adapted from https://github.com/google/closure-library/blob/master/closure/goog/math/bezier.js. function solvePositionFromXValue_(xVal, x1, x2) { var EPSILON = 1e-6; var MAX_ITERATIONS = 8; if (xVal <= 0) { return 0; } else if (xVal >= 1) { return 1; } // Initial estimate of t using linear interpolation. var t = xVal; // Try gradient descent to solve for t. If it works, it is very fast. var tMin = 0; var tMax = 1; var value = 0; for (var i = 0; i < MAX_ITERATIONS; i++) { value = getBezierCoordinate_(t, x1, x2); var derivative = (getBezierCoordinate_(t + EPSILON, x1, x2) - value) / EPSILON; if (Math.abs(value - xVal) < EPSILON) { return t; } else if (Math.abs(derivative) < EPSILON) { break; } else { if (value < xVal) { tMin = t; } else { tMax = t; } t -= (value - xVal) / derivative; } } // If the gradient descent got stuck in a local minimum, e.g. because // the derivative was close to 0, use a Dichotomy refinement instead. // We limit the number of interations to 8. for (var _i = 0; Math.abs(value - xVal) > EPSILON && _i < MAX_ITERATIONS; _i++) { if (value < xVal) { tMin = t; t = (t + tMax) / 2; } else { tMax = t; t = (t + tMin) / 2; } value = getBezierCoordinate_(t, x1, x2); } return t; }