Browser animation in 2017
動く・動かせ・動け!
動く
今できること
CSS Transitions
CSS Animations
CSS Transitions
A → B
CSS Animations
- A → B → C
- A → B → A
- 繰り返し
x
(でもCSSTransitionGroupに注意)
4+ (transitions)
5+
1+
10+
3+ (transitions)
4+
Script animations
Web Animations API
Animating like you just don't care with Element.animate()
48+
36+
Priority: Medium
実装中
動かせ
動け
これからのアニメ
問題① フレームのアニメーション
問題① フレームのアニメーション
問題① フレームのアニメーション
問題① フレームのアニメーション
問題① フレームのアニメーション
問題① フレームのアニメーション
frames(n) (n ≥ 2)
55+
実装済み?
(昨日)
?
?
問題②Transitionの終わりを待つ
// Style:
// transition: opacity 1s
// transitionを発火する
elem.style.opacity = '0';
getComputedStyle(elem);
// 終わったら次の画面をactiveにする
elem.addEventListener('transitionend', evt => {
if (evt.propertyName === 'opacity') {
evt.target.remove();
homeScreen.classList.add('active');
}
});
/*
* でも…
*/
button.addEventListener('focus', () => {
// もしこれがmustacheのようなテンプレート仕組み…
render();
});
問題②Transitionの終わりを待つ
transitionendが発火されないケース
- 要素が消えた
- 要素の親がdisplay:noneになった
- transition-propertyからtransitionされているpropertyが消えた
- transitionがそもそも生成されなかった
(例:opacityが既に0になった場合)
問題②Transitionの終わりを待つ
transitioncancel | 53+
|
|||
transitionrun | 53+ | |||
transitionstart | 53+ | 10 | ||
animationcancel | 54+ |
問題②Transitionの終わりを待つ
Promise.all(
elem.getAnimations().map(animation => animation.finished)
).then(() => {
// アニメーション全部終わった。ハズ。
});
Element.getAnimations()
Nightly
問題③アニメーションがぶつかる
問題③アニメーションがぶつかる
問題③アニメーションがぶつかる
問題③アニメーションがぶつかる
Nightly
Canary
(Experimental web platform features)
'animation-composition'
CSS Animations Level 2
https://drafts.csswg.org/css-animations-2/#animation-composition
問題④スクロールに沿ってアニメーションしたい
問題④スクロールに沿ってアニメーションしたい
問題④スクロールに沿ってアニメーションしたい
問題④スクロールに沿ってアニメーションしたい
const animation = target.animate({ transform: 'scale(2)' },
{ duration: 1000,
fill: 'both' });
animation.timeline =
new ScrollTimeline({ scrollSource: elem });
問題④スクロールに沿ってアニメーションしたい
問題④スクロールに沿ってアニメーションしたい
Scroll-linked animations
Mozilla bug:
https://bugzilla.mozilla.org/show_bug.cgi?id=1321428
問題⑤別のスレッドでアニメーションしたい
// twitter-header-animator.js
registerAnimator('twitter-header', class {
animate(timelines, outputEffects) {
const time = timelines[1].currentTime; // [0...timeRange]
outputEffects[0].localTime = time; // Sets the time used in the first output effect.
outputEffects[1].localTime = Math.min(1, time * 10); // Clamps the input time range.
}
});
// my-page.js
animationWorklet.import('twitter-header-animator.js').then( _ => {
var anim = new WorkletAnimation('twitter-header',
[
new KeyFrameEffect(avatarEl,
{ transform: [ 'translateX(100px)', 'translateX(0px)' ] },
{ duration: 100, iterations: infinite }),
new KeyFrameEffect(headerEl, { opacity: [ 0, 1 ] }, 100)
], [
document.timeline,
new ScrollTimeline(scrollingElement, { timeRange: 100 })
]
);
});
Browser animation in 2017 (Brian's fork)
By Brian Birtles
Browser animation in 2017 (Brian's fork)
- 2,132