-
Notifications
You must be signed in to change notification settings - Fork 843
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* transition services * use transition services * add doc example * snapshot updates * Update src/services/transition/transition.ts Co-Authored-By: Chandler Prall <chandler.prall@gmail.com> * clean up * update regex; distinguish s and ms * clean up * CL
- Loading branch information
1 parent
5643b3c
commit c5ceab9
Showing
8 changed files
with
148 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export { | ||
getDurationAndPerformOnFrame, | ||
getTransitionTimings, | ||
getWaitDuration, | ||
performOnFrame, | ||
} from './transition'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
const GROUP_NUMERIC = /^([\d.]+)(s|ms)/; | ||
|
||
function getMilliseconds(value: string, unit: string) { | ||
// Given the regex match and capture groups, we can assume `unit` to be either 's' or 'ms' | ||
const multiplier = unit === 's' ? 1000 : 1; | ||
return parseFloat(value) * multiplier; | ||
} | ||
// Find CSS `transition-duration` and `transition-delay` intervals | ||
// and return the value of each computed property in 'ms' | ||
export const getTransitionTimings = (element: Element) => { | ||
const computedStyle = window.getComputedStyle(element); | ||
|
||
const computedDuration = computedStyle.getPropertyValue( | ||
'transition-duration' | ||
); | ||
const durationMatchArray = computedDuration.match(GROUP_NUMERIC); | ||
const durationMatch = durationMatchArray | ||
? getMilliseconds(durationMatchArray[1], durationMatchArray[2]) | ||
: 0; | ||
|
||
const computedDelay = computedStyle.getPropertyValue('transition-delay'); | ||
const delayMatchArray = computedDelay.match(GROUP_NUMERIC); | ||
const delayMatch = delayMatchArray | ||
? getMilliseconds(delayMatchArray[1], delayMatchArray[2]) | ||
: 0; | ||
|
||
return { durationMatch, delayMatch }; | ||
}; | ||
|
||
function isElementNode(element: Node): element is Element { | ||
return element.nodeType === document.ELEMENT_NODE; | ||
} | ||
// Uses `getTransitionTimings` to find the total transition time for | ||
// all elements targeted by a MutationObserver callback | ||
export const getWaitDuration = (records: MutationRecord[]) => { | ||
return records.reduce((waitDuration, record) => { | ||
// only check for CSS transition values for ELEMENT nodes | ||
if (isElementNode(record.target)) { | ||
const { durationMatch, delayMatch } = getTransitionTimings(record.target); | ||
waitDuration = Math.max(waitDuration, durationMatch + delayMatch); | ||
} | ||
|
||
return waitDuration; | ||
}, 0); | ||
}; | ||
|
||
// Uses `requestAnimationFrame` to perform a given callback after a specified waiting period | ||
export const performOnFrame = (waitDuration: number, toPerform: () => void) => { | ||
if (waitDuration > 0) { | ||
const startTime = Date.now(); | ||
const endTime = startTime + waitDuration; | ||
|
||
const onFrame = () => { | ||
toPerform(); | ||
|
||
if (endTime > Date.now()) { | ||
requestAnimationFrame(onFrame); | ||
} | ||
}; | ||
|
||
requestAnimationFrame(onFrame); | ||
} | ||
}; | ||
|
||
// Convenience method for combining the result of 'getWaitDuration' directly with 'performOnFrame' | ||
export const getDurationAndPerformOnFrame = ( | ||
records: MutationRecord[], | ||
toPerform: () => void | ||
) => { | ||
performOnFrame(getWaitDuration(records), toPerform); | ||
}; |