mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 04:14:21 +08:00
collide updates
This commit is contained in:
@ -1,9 +1,11 @@
|
||||
/* Forked from Velocity.js, MIT License. Julian Shapiro http://twitter.com/shapiro */
|
||||
/* Forked from VelocityJS: https://github.com/julianshapiro/velocity | MIT License. Julian Shapiro http://twitter.com/shapiro */
|
||||
|
||||
import * as util from 'ionic/util/util'
|
||||
import {Collide} from './collide'
|
||||
import {CSS} from './css'
|
||||
import {getEasing} from './easing'
|
||||
import {calculateUnitRatios} from './calculate-unit-ratios'
|
||||
|
||||
|
||||
const data = Collide.data;
|
||||
|
||||
@ -587,128 +589,6 @@ export function animationProcess(action, elements, elementsIndex, options, prope
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
parsePropertyValue(), Unit Ratio Calculation
|
||||
***************************/
|
||||
|
||||
/* When queried, the browser returns (most) CSS property values in pixels. Therefore, if an endValue with a unit type of
|
||||
%, em, or rem is animated toward, startValue must be converted from pixels into the same unit type as endValue in order
|
||||
for value manipulation logic (increment/decrement) to proceed. Further, if the startValue was forcefed or transferred
|
||||
from a previous call, startValue may also not be in pixels. Unit conversion logic therefore consists of two steps:
|
||||
1) Calculating the ratio of %/em/rem/vh/vw relative to pixels
|
||||
2) Converting startValue into the same unit of measurement as endValue based on these ratios. */
|
||||
/* Unit conversion ratios are calculated by inserting a sibling node next to the target node, copying over its position property,
|
||||
setting values with the target unit type then comparing the returned pixel value. */
|
||||
/* Note: Even if only one of these unit types is being animated, all unit ratios are calculated at once since the overhead
|
||||
of batching the SETs and GETs together upfront outweights the potential overhead
|
||||
of layout thrashing caused by re-querying for uncalculated ratios for subsequently-processed properties. */
|
||||
/* Todo: Shift this logic into the calls' first tick instance so that it's synced with RAF. */
|
||||
function calculateUnitRatios() {
|
||||
|
||||
/**************************************************************
|
||||
parsePropertyValue(), calculateUnitRatios(), Same Ratio Checks
|
||||
**************************************************************/
|
||||
|
||||
/* The properties below are used to determine whether the element differs sufficiently from this call's
|
||||
previously iterated element to also differ in its unit conversion ratios. If the properties match up with those
|
||||
of the prior element, the prior element's conversion ratios are used. Like most optimizations in Collide,
|
||||
this is done to minimize DOM querying. */
|
||||
var sameRatioIndicators = {
|
||||
myParent: element.parentNode || document.body, /* GET */
|
||||
position: CSS.getPropertyValue(element, 'position'), /* GET */
|
||||
fontSize: CSS.getPropertyValue(element, 'fontSize') /* GET */
|
||||
};
|
||||
|
||||
/* Determine if the same % ratio can be used. % is based on the element's position value and its parent's width and height dimensions. */
|
||||
var samePercentRatio = ((sameRatioIndicators.position === callUnitConversionData.lastPosition) && (sameRatioIndicators.myParent === callUnitConversionData.lastParent));
|
||||
|
||||
/* Determine if the same em ratio can be used. em is relative to the element's fontSize. */
|
||||
var sameEmRatio = (sameRatioIndicators.fontSize === callUnitConversionData.lastFontSize);
|
||||
|
||||
/* Store these ratio indicators call-wide for the next element to compare against. */
|
||||
callUnitConversionData.lastParent = sameRatioIndicators.myParent;
|
||||
callUnitConversionData.lastPosition = sameRatioIndicators.position;
|
||||
callUnitConversionData.lastFontSize = sameRatioIndicators.fontSize;
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
parsePropertyValue(), calculateUnitRatios(), Element-Specific Units
|
||||
**********************************************************************/
|
||||
|
||||
var measurement = 100,
|
||||
unitRatios = {};
|
||||
|
||||
if (!sameEmRatio || !samePercentRatio) {
|
||||
var dummy = data(element).isSVG ? document.createElementNS('http://www.w3.org/2000/svg', 'rect') : document.createElement('div');
|
||||
|
||||
Collide.init(dummy);
|
||||
sameRatioIndicators.myParent.appendChild(dummy);
|
||||
|
||||
/* To accurately and consistently calculate conversion ratios, the element's cascaded overflow and box-sizing are stripped.
|
||||
Similarly, since width/height can be artificially constrained by their min-/max- equivalents, these are controlled for as well. */
|
||||
/* Note: Overflow must be also be controlled for per-axis since the overflow property overwrites its per-axis values. */
|
||||
var cssPropNames = [ 'overflow', 'overflowX', 'overflowY' ];
|
||||
for (var x = 0; x < overflows.length; x++) {
|
||||
Collide.CSS.setPropertyValue(dummy, cssPropNames[x], 'hidden');
|
||||
}
|
||||
|
||||
Collide.CSS.setPropertyValue(dummy, 'position', sameRatioIndicators.position);
|
||||
Collide.CSS.setPropertyValue(dummy, 'fontSize', sameRatioIndicators.fontSize);
|
||||
Collide.CSS.setPropertyValue(dummy, 'boxSizing', 'content-box');
|
||||
|
||||
/* width and height act as our proxy properties for measuring the horizontal and vertical % ratios. */
|
||||
cssPropNames = [ 'minWidth', 'maxWidth', 'width', 'minHeight', 'maxHeight', 'height' ];
|
||||
for (var x = 0; x < overflows.length; x++) {
|
||||
Collide.CSS.setPropertyValue(dummy, cssPropNames[x], measurement + '%');
|
||||
}
|
||||
|
||||
/* paddingLeft arbitrarily acts as our proxy property for the em ratio. */
|
||||
Collide.CSS.setPropertyValue(dummy, 'paddingLeft', measurement + 'em');
|
||||
|
||||
/* Divide the returned value by the measurement to get the ratio between 1% and 1px. Default to 1 since working with 0 can produce Infinite. */
|
||||
unitRatios.percentToPxWidth = callUnitConversionData.lastPercentToPxWidth = (parseFloat(CSS.getPropertyValue(dummy, 'width', null, true)) || 1) / measurement; /* GET */
|
||||
unitRatios.percentToPxHeight = callUnitConversionData.lastPercentToPxHeight = (parseFloat(CSS.getPropertyValue(dummy, 'height', null, true)) || 1) / measurement; /* GET */
|
||||
unitRatios.emToPx = callUnitConversionData.lastEmToPx = (parseFloat(CSS.getPropertyValue(dummy, 'paddingLeft')) || 1) / measurement; /* GET */
|
||||
|
||||
sameRatioIndicators.myParent.removeChild(dummy);
|
||||
|
||||
} else {
|
||||
unitRatios.emToPx = callUnitConversionData.lastEmToPx;
|
||||
unitRatios.percentToPxWidth = callUnitConversionData.lastPercentToPxWidth;
|
||||
unitRatios.percentToPxHeight = callUnitConversionData.lastPercentToPxHeight;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
parsePropertyValue(), calculateUnitRatios(), Element-Agnostic Units
|
||||
***********************************************************************/
|
||||
|
||||
/* Whereas % and em ratios are determined on a per-element basis, the rem unit only needs to be checked
|
||||
once per call since it's exclusively dependant upon document.body's fontSize. If this is the first time
|
||||
that calculateUnitRatios() is being run during this call, remToPx will still be set to its default value of null,
|
||||
so we calculate it now. */
|
||||
if (callUnitConversionData.remToPx === null) {
|
||||
/* Default to browsers' default fontSize of 16px in the case of 0. */
|
||||
callUnitConversionData.remToPx = parseFloat(CSS.getPropertyValue(document.body, 'fontSize')) || 16; /* GET */
|
||||
}
|
||||
|
||||
/* Similarly, viewport units are %-relative to the window's inner dimensions. */
|
||||
if (callUnitConversionData.vwToPx === null) {
|
||||
callUnitConversionData.vwToPx = parseFloat(window.innerWidth) / 100; /* GET */
|
||||
callUnitConversionData.vhToPx = parseFloat(window.innerHeight) / 100; /* GET */
|
||||
}
|
||||
|
||||
unitRatios.remToPx = callUnitConversionData.remToPx;
|
||||
unitRatios.vwToPx = callUnitConversionData.vwToPx;
|
||||
unitRatios.vhToPx = callUnitConversionData.vhToPx;
|
||||
|
||||
if (Collide.debug >= 1) console.log('Unit ratios: ' + JSON.stringify(unitRatios), element);
|
||||
|
||||
return unitRatios;
|
||||
|
||||
} // END: calculateUnitRatios()
|
||||
|
||||
|
||||
/****************************************
|
||||
parsePropertyValue(), Unit Conversion
|
||||
*****************************************/
|
||||
@ -733,7 +613,7 @@ export function animationProcess(action, elements, elementsIndex, options, prope
|
||||
} else {
|
||||
/* By this point, we cannot avoid unit conversion (it's undesirable since it causes layout thrashing).
|
||||
If we haven't already, we trigger calculateUnitRatios(), which runs once per element per call. */
|
||||
elementUnitConversionData = elementUnitConversionData || calculateUnitRatios();
|
||||
elementUnitConversionData = elementUnitConversionData || calculateUnitRatios(element, callUnitConversionData);
|
||||
|
||||
/* The following RegEx matches CSS properties that have their % values measured relative to the x-axis. */
|
||||
/* Note: W3C spec mandates that all of margin and padding's properties (even top and bottom) are %-relative to the *width* of the parent element. */
|
||||
|
Reference in New Issue
Block a user