From 72e7e18e0bbe4ae6b2979f43fa2076e29bd5d575 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Wed, 21 Mar 2018 09:38:20 -0700 Subject: [PATCH] add favorite/reblog animations --- package-lock.json | 5 ++++ package.json | 4 +++- routes/_components/IconButton.html | 16 ++++++++++--- routes/_components/status/StatusToolbar.html | 9 +++++++ routes/_static/animations.js | 25 ++++++++++++++++++++ routes/_utils/asyncModules.js | 4 ++++ routes/_utils/loadPolyfills.js | 6 +++-- 7 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 routes/_static/animations.js diff --git a/package-lock.json b/package-lock.json index 582609b3..3cd23daf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10471,6 +10471,11 @@ } } }, + "web-animations-js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/web-animations-js/-/web-animations-js-2.3.1.tgz", + "integrity": "sha1-Om2bwVGWN3qQ+OKAP6UmIWWwRRA=" + }, "webauth": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/webauth/-/webauth-1.1.0.tgz", diff --git a/package.json b/package.json index 1ae90ffa..822957fc 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "testcafe": "^0.19.0", "timeago.js": "^3.0.2", "tiny-queue": "^0.2.1", + "web-animations-js": "^2.3.1", "webpack": "^4.1.0", "webpack-bundle-analyzer": "^2.11.1", "workerize-loader": "^1.0.1", @@ -100,7 +101,8 @@ "FormData", "atob", "btoa", - "Blob" + "Blob", + "Element" ], "ignore": [ "dist", diff --git a/routes/_components/IconButton.html b/routes/_components/IconButton.html index 332b250b..dfeeac26 100644 --- a/routes/_components/IconButton.html +++ b/routes/_components/IconButton.html @@ -6,7 +6,7 @@ :disabled delegate-key="{{delegateKey}}" focus-key="{{focusKey || ''}}" > - + @@ -18,7 +18,7 @@ focus-key="{{focusKey || ''}}" :disabled on:click > - + @@ -50,7 +50,7 @@ } .icon-button.pressed .icon-button-svg { - fill: var(--action-button-fill-color-pressed) + fill: var(--action-button-fill-color-pressed); } .icon-button.pressed:hover .icon-button-svg { @@ -66,6 +66,16 @@ import { classname } from '../_utils/classname' export default { + oncreate() { + this.observe('animation', animation => { + if (!animation) { + return + } + let svg = this.refs.svg + let animations = animation.map(({properties, options}) => svg.animate(properties, options)) + animations.forEach(anim => anim.play()) + }) + }, computed: { computedClass: (pressable, pressed, big, className) => { return classname( diff --git a/routes/_components/status/StatusToolbar.html b/routes/_components/status/StatusToolbar.html index de55b0b4..89978269 100644 --- a/routes/_components/status/StatusToolbar.html +++ b/routes/_components/status/StatusToolbar.html @@ -13,6 +13,7 @@ disabled="{{reblogDisabled}}" href="{{reblogIcon}}" delegateKey="{{reblogKey}}" + animation="{{animateReblog && reblogAnimation}}" /> ({ + favoriteAnimation: FAVORITE_ANIMATION, + reblogAnimation: REBLOG_ANIMATION + }), computed: { reblogLabel: (visibility) => { switch (visibility) { diff --git a/routes/_static/animations.js b/routes/_static/animations.js new file mode 100644 index 00000000..4fb2a809 --- /dev/null +++ b/routes/_static/animations.js @@ -0,0 +1,25 @@ +export const FAVORITE_ANIMATION = [ + { + properties: [ + {transform: 'scale(1)'}, + {transform: 'scale(2)'}, + {transform: 'scale(1)'} + ], + options: { + duration: 400, + easing: 'ease-in-out' + } + }, + { + properties: [ + {fill: 'var(--action-button-fill-color)'}, + {fill: 'var(--action-button-fill-color-pressed)'} + ], + options: { + duration: 400, + easing: 'linear' + } + } +] + +export const REBLOG_ANIMATION = FAVORITE_ANIMATION diff --git a/routes/_utils/asyncModules.js b/routes/_utils/asyncModules.js index e5aae720..4127f097 100644 --- a/routes/_utils/asyncModules.js +++ b/routes/_utils/asyncModules.js @@ -14,6 +14,10 @@ export const importIndexedDBGetAllShim = () => import( /* webpackChunkName: 'indexeddb-getall-shim' */ 'indexeddb-getall-shim' ) +export const importWebAnimationPolyfill = () => import( + /* webpackChunkName: 'web-animations-js' */ 'web-animations-js' + ) + export const importWebSocketClient = () => import( /* webpackChunkName: '@gamestdio/websocket' */ '@gamestdio/websocket' ).then(mod => mod.default) diff --git a/routes/_utils/loadPolyfills.js b/routes/_utils/loadPolyfills.js index 6bf27cc7..9642c9d6 100644 --- a/routes/_utils/loadPolyfills.js +++ b/routes/_utils/loadPolyfills.js @@ -1,13 +1,15 @@ import { importIntersectionObserver, importRequestIdleCallback, - importIndexedDBGetAllShim + importIndexedDBGetAllShim, + importWebAnimationPolyfill } from './asyncModules' export function loadPolyfills () { return Promise.all([ typeof IntersectionObserver === 'undefined' && importIntersectionObserver(), typeof requestIdleCallback === 'undefined' && importRequestIdleCallback(), - !IDBObjectStore.prototype.getAll && importIndexedDBGetAllShim() + !IDBObjectStore.prototype.getAll && importIndexedDBGetAllShim(), + !Element.prototype.animate && importWebAnimationPolyfill() ]) }