perf: use lite web animations polyfill (#1011)
This commit is contained in:
parent
ef5fb4ce0c
commit
cd5b6f8e81
|
@ -99,7 +99,6 @@
|
|||
"terser-webpack-plugin": "^1.2.2",
|
||||
"text-encoding": "^0.7.0",
|
||||
"tiny-queue": "^0.2.1",
|
||||
"web-animations-js": "^2.3.1",
|
||||
"webpack": "^4.29.3",
|
||||
"webpack-bundle-analyzer": "^3.0.4"
|
||||
},
|
||||
|
|
|
@ -107,6 +107,7 @@
|
|||
<script>
|
||||
import { classname } from '../_utils/classname'
|
||||
import { store } from '../_store/store'
|
||||
import { animate } from '../_utils/animate'
|
||||
|
||||
export default {
|
||||
data: () => ({
|
||||
|
@ -143,8 +144,7 @@
|
|||
return
|
||||
}
|
||||
let svg = this.refs.svg
|
||||
let animations = animation.map(({ properties, options }) => svg.animate(properties, options))
|
||||
animations.forEach(anim => anim.play())
|
||||
animate(svg, animation)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
59
src/routes/_utils/animate.js
Normal file
59
src/routes/_utils/animate.js
Normal file
|
@ -0,0 +1,59 @@
|
|||
// Lightweight polyfill for web animations API element.animate()
|
||||
// This is good enough for my use case, although not a full polyfill
|
||||
// of the entire API
|
||||
|
||||
// via https://stackoverflow.com/a/15710692
|
||||
function hashCode (s) {
|
||||
return s.split('')
|
||||
.reduce((a, b) => {
|
||||
a = ((a << 5) - a) + b.charCodeAt(0)
|
||||
return a & a
|
||||
}, 0)
|
||||
}
|
||||
|
||||
function generateCss (id, animations) {
|
||||
let keyframes = animations.map(({ properties }, i) => (
|
||||
`@keyframes keyframe-${id}-${i} {
|
||||
${properties.map((obj, i) => (`${Math.round(100 * i / (properties.length - 1))}% {
|
||||
${Object.keys(obj).map(key => `${key}: ${obj[key]};`).join('')}
|
||||
}`
|
||||
)).join('')}
|
||||
}`
|
||||
))
|
||||
|
||||
let animationCss = `.${id} {
|
||||
animation: ${animations.map(({ options }, i) => {
|
||||
return `keyframe-${id}-${i} ${options.duration}ms ${options.easing}`
|
||||
}).join(',')};
|
||||
}`
|
||||
|
||||
return keyframes + animationCss
|
||||
}
|
||||
|
||||
export function animate (el, animations) {
|
||||
if (typeof el.animate === 'function') {
|
||||
return animations
|
||||
.map(({ properties, options }) => el.animate(properties, options))
|
||||
.map(anim => anim.play())
|
||||
}
|
||||
|
||||
let hash = hashCode(JSON.stringify(animations))
|
||||
let id = `anim-${hash}`
|
||||
|
||||
if (!document.getElementById(id)) {
|
||||
let style = document.createElement('style')
|
||||
style.id = id
|
||||
style.textContent = generateCss(id, animations)
|
||||
document.head.appendChild(style)
|
||||
}
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
el.classList.add(id)
|
||||
let wait = Math.max.apply(Math, animations.map(({ options }) => options.duration))
|
||||
setTimeout(() => {
|
||||
requestAnimationFrame(() => {
|
||||
el.classList.remove(id)
|
||||
})
|
||||
}, wait)
|
||||
})
|
||||
}
|
|
@ -6,10 +6,6 @@ export const importRequestIdleCallback = () => import(
|
|||
/* webpackChunkName: '$polyfill$-requestidlecallback' */ 'requestidlecallback'
|
||||
)
|
||||
|
||||
export const importWebAnimationPolyfill = () => import(
|
||||
/* webpackChunkName: '$polyfill$-web-animations-js' */ 'web-animations-js'
|
||||
)
|
||||
|
||||
export const importIndexedDBGetAllShim = () => import(
|
||||
/* webpackChunkName: '$polyfill$-indexeddb-getall-shim' */ 'indexeddb-getall-shim'
|
||||
)
|
||||
|
|
|
@ -2,15 +2,13 @@ import {
|
|||
importCustomElementsPolyfill,
|
||||
importIndexedDBGetAllShim,
|
||||
importIntersectionObserver,
|
||||
importRequestIdleCallback,
|
||||
importWebAnimationPolyfill
|
||||
importRequestIdleCallback
|
||||
} from './asyncPolyfills'
|
||||
|
||||
export function loadPolyfills () {
|
||||
return Promise.all([
|
||||
typeof IntersectionObserver === 'undefined' && importIntersectionObserver(),
|
||||
typeof requestIdleCallback === 'undefined' && importRequestIdleCallback(),
|
||||
!Element.prototype.animate && importWebAnimationPolyfill(),
|
||||
!IDBObjectStore.prototype.getAll && importIndexedDBGetAllShim(),
|
||||
typeof customElements === 'undefined' && importCustomElementsPolyfill()
|
||||
])
|
||||
|
|
|
@ -7754,11 +7754,6 @@ watchpack@^1.5.0:
|
|||
graceful-fs "^4.1.2"
|
||||
neo-async "^2.5.0"
|
||||
|
||||
web-animations-js@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/web-animations-js/-/web-animations-js-2.3.1.tgz#3a6d9bc15196377a90f8e2803fa5262165b04510"
|
||||
integrity sha1-Om2bwVGWN3qQ+OKAP6UmIWWwRRA=
|
||||
|
||||
webauth@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/webauth/-/webauth-1.1.0.tgz#64704f6b8026986605bc3ca629952e6e26fdd100"
|
||||
|
|
Loading…
Reference in a new issue