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",
|
"terser-webpack-plugin": "^1.2.2",
|
||||||
"text-encoding": "^0.7.0",
|
"text-encoding": "^0.7.0",
|
||||||
"tiny-queue": "^0.2.1",
|
"tiny-queue": "^0.2.1",
|
||||||
"web-animations-js": "^2.3.1",
|
|
||||||
"webpack": "^4.29.3",
|
"webpack": "^4.29.3",
|
||||||
"webpack-bundle-analyzer": "^3.0.4"
|
"webpack-bundle-analyzer": "^3.0.4"
|
||||||
},
|
},
|
||||||
|
|
|
@ -107,6 +107,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { classname } from '../_utils/classname'
|
import { classname } from '../_utils/classname'
|
||||||
import { store } from '../_store/store'
|
import { store } from '../_store/store'
|
||||||
|
import { animate } from '../_utils/animate'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data: () => ({
|
data: () => ({
|
||||||
|
@ -143,8 +144,7 @@
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let svg = this.refs.svg
|
let svg = this.refs.svg
|
||||||
let animations = animation.map(({ properties, options }) => svg.animate(properties, options))
|
animate(svg, animation)
|
||||||
animations.forEach(anim => anim.play())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
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'
|
/* webpackChunkName: '$polyfill$-requestidlecallback' */ 'requestidlecallback'
|
||||||
)
|
)
|
||||||
|
|
||||||
export const importWebAnimationPolyfill = () => import(
|
|
||||||
/* webpackChunkName: '$polyfill$-web-animations-js' */ 'web-animations-js'
|
|
||||||
)
|
|
||||||
|
|
||||||
export const importIndexedDBGetAllShim = () => import(
|
export const importIndexedDBGetAllShim = () => import(
|
||||||
/* webpackChunkName: '$polyfill$-indexeddb-getall-shim' */ 'indexeddb-getall-shim'
|
/* webpackChunkName: '$polyfill$-indexeddb-getall-shim' */ 'indexeddb-getall-shim'
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,15 +2,13 @@ import {
|
||||||
importCustomElementsPolyfill,
|
importCustomElementsPolyfill,
|
||||||
importIndexedDBGetAllShim,
|
importIndexedDBGetAllShim,
|
||||||
importIntersectionObserver,
|
importIntersectionObserver,
|
||||||
importRequestIdleCallback,
|
importRequestIdleCallback
|
||||||
importWebAnimationPolyfill
|
|
||||||
} from './asyncPolyfills'
|
} from './asyncPolyfills'
|
||||||
|
|
||||||
export function loadPolyfills () {
|
export function loadPolyfills () {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
typeof IntersectionObserver === 'undefined' && importIntersectionObserver(),
|
typeof IntersectionObserver === 'undefined' && importIntersectionObserver(),
|
||||||
typeof requestIdleCallback === 'undefined' && importRequestIdleCallback(),
|
typeof requestIdleCallback === 'undefined' && importRequestIdleCallback(),
|
||||||
!Element.prototype.animate && importWebAnimationPolyfill(),
|
|
||||||
!IDBObjectStore.prototype.getAll && importIndexedDBGetAllShim(),
|
!IDBObjectStore.prototype.getAll && importIndexedDBGetAllShim(),
|
||||||
typeof customElements === 'undefined' && importCustomElementsPolyfill()
|
typeof customElements === 'undefined' && importCustomElementsPolyfill()
|
||||||
])
|
])
|
||||||
|
|
|
@ -7754,11 +7754,6 @@ watchpack@^1.5.0:
|
||||||
graceful-fs "^4.1.2"
|
graceful-fs "^4.1.2"
|
||||||
neo-async "^2.5.0"
|
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:
|
webauth@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/webauth/-/webauth-1.1.0.tgz#64704f6b8026986605bc3ca629952e6e26fdd100"
|
resolved "https://registry.yarnpkg.com/webauth/-/webauth-1.1.0.tgz#64704f6b8026986605bc3ca629952e6e26fdd100"
|
||||||
|
|
Loading…
Reference in a new issue