Adjust animations to number of items

This commit is contained in:
Tom Raithel
2017-03-01 21:40:59 +01:00
parent 6d4f1d0c09
commit a92aeac253
5 changed files with 129 additions and 119 deletions

View File

@@ -72,7 +72,7 @@ export const createAnimationRunner = (animations, subscriber) => {
const animationsDuration = getMaxAnimationsDuration(animations); const animationsDuration = getMaxAnimationsDuration(animations);
const animate = (name, animation, stateName, getDelay) => { const animate = (name, animation) => {
if (animation instanceof Array) { if (animation instanceof Array) {
animation.map((a, index) => { animation.map((a, index) => {
window.requestAnimationFrame(() => { window.requestAnimationFrame(() => {
@@ -81,12 +81,12 @@ export const createAnimationRunner = (animations, subscriber) => {
...state, ...state,
[name]: [ [name]: [
...(state[name].slice(0, index)), ...(state[name].slice(0, index)),
a[stateName], a.stateB,
...(state[name].slice(index + 1, state[name].length)), ...(state[name].slice(index + 1, state[name].length)),
], ],
}; };
subscriber(); subscriber();
}, getDelay(a)) }, a.delay);
}); });
}); });
} else { } else {
@@ -94,10 +94,10 @@ export const createAnimationRunner = (animations, subscriber) => {
window.setTimeout(() => { window.setTimeout(() => {
state = { state = {
...state, ...state,
[name]: animation[stateName], [name]: animation.stateB,
}; };
subscriber(); subscriber();
}, getDelay(animation)) }, animation.delay);
}); });
} }
} }
@@ -108,27 +108,11 @@ export const createAnimationRunner = (animations, subscriber) => {
}, },
run() { run() {
Object.entries(animations).forEach(([name, animation]) => { Object.entries(animations).forEach(([name, animation]) => {
animate(name, animation, 'stateB', a => a.delay) animate(name, animation)
}) });
},
runReverse() {
Object.entries(animations).reverse().forEach(([name, animation]) => {
animate(name, animation, 'stateA', a => animationsDuration - a.delay)
})
}, },
awaitAnimationComplete(callback) { awaitAnimationComplete(callback) {
window.setTimeout(callback, animationsDuration); window.setTimeout(callback, animationsDuration);
}, },
} }
} }
// prepare(callback) {
// callback(stateA);
// },
// run(callback) {
// window,requestAnimationFrame(() => {
// window.setTimeout(() => {
// callback(stateB);
// }, delay)
// });
// },

View File

@@ -6,11 +6,21 @@ import Link from './Link';
import Fadeable from './Fadeable'; import Fadeable from './Fadeable';
import { createAnimation, createAnimationRunner } from '../animation'; import { createAnimation, createAnimationRunner } from '../animation';
import { translate } from '../../common/config';
import { groupByQuadrants } from '../../common/model'; import { groupByQuadrants } from '../../common/model';
const items = [1, 2]; // TODO use real items const setAnimations = (state, animations) => ({
...state,
animations,
});
const animationsIn = { class PageItem extends React.Component {
constructor(props) {
super(props);
const itemsInRing = this.getItemsInRing(props);
this.animationsIn = {
background: createAnimation({ background: createAnimation({
transform: 'translateX(calc((100vw - 1200px) / 2 + 800px))', transform: 'translateX(calc((100vw - 1200px) / 2 + 800px))',
transition: 'transform 450ms cubic-bezier(0.24, 1.12, 0.71, 0.98)', transition: 'transform 450ms cubic-bezier(0.24, 1.12, 0.71, 0.98)',
@@ -40,7 +50,7 @@ const animationsIn = {
}, },
600 600
), ),
items: items.map((item, i) => (createAnimation({ items: props.items.map((item, i) => (createAnimation({
transform: 'translateX(-40px)', transform: 'translateX(-40px)',
opacity: '0', opacity: '0',
}, { }, {
@@ -50,16 +60,16 @@ const animationsIn = {
}, },
400 + 100 * i 400 + 100 * i
))) )))
}; };
const animationsOut = { this.animationsOut = {
background: createAnimation( background: createAnimation(
animationsIn.background.stateB, this.animationsIn.background.stateB,
animationsIn.background.stateA, this.animationsIn.background.stateA,
0 0
), ),
navHeader: createAnimation( navHeader: createAnimation(
animationsIn.navHeader.stateB, this.animationsIn.navHeader.stateB,
{ {
transition: 'opacity 150ms ease-out, transform 300ms ease-out', transition: 'opacity 150ms ease-out, transform 300ms ease-out',
transform: 'translateX(40px)', transform: 'translateX(40px)',
@@ -68,7 +78,7 @@ const animationsOut = {
0 0
), ),
text: createAnimation( text: createAnimation(
animationsIn.text.stateB, this.animationsIn.text.stateB,
{ {
transform: 'translateY(20px)', transform: 'translateY(20px)',
transition: 'opacity 150ms ease-out, transform 300ms ease-out', transition: 'opacity 150ms ease-out, transform 300ms ease-out',
@@ -76,8 +86,8 @@ const animationsOut = {
}, },
0 0
), ),
items: items.map((item, i) => (createAnimation( items: itemsInRing.map((item, i) => (createAnimation(
animationsIn.items[i].stateB, this.animationsIn.items[i].stateB,
{ {
transition: 'opacity 150ms ease-out, transform 300ms ease-out', transition: 'opacity 150ms ease-out, transform 300ms ease-out',
transform: 'translateX(40px)', transform: 'translateX(40px)',
@@ -85,19 +95,10 @@ const animationsOut = {
}, },
100 + 100 * i 100 + 100 * i
))) )))
}; };
const setAnimations = (state, animations) => ({
...state,
animations,
});
class PageItem extends React.Component {
constructor(props) {
super(props);
if (props.leaving) { // entering from an other page if (props.leaving) { // entering from an other page
this.state = setAnimations({}, createAnimationRunner(animationsIn).getState()); this.state = setAnimations({}, createAnimationRunner(this.animationsIn).getState());
} else { // Hard refresh } else { // Hard refresh
this.state = {}; this.state = {};
} }
@@ -105,12 +106,12 @@ class PageItem extends React.Component {
componentWillReceiveProps({ leaving }) { componentWillReceiveProps({ leaving }) {
if (!this.props.leaving && leaving) { // page will be left if (!this.props.leaving && leaving) { // page will be left
this.animationRunner = createAnimationRunner(animationsOut, this.handleAnimationsUpdate); this.animationRunner = createAnimationRunner(this.animationsOut, this.handleAnimationsUpdate);
this.animationRunner.run(); this.animationRunner.run();
this.animationRunner.awaitAnimationComplete(this.props.onLeave); this.animationRunner.awaitAnimationComplete(this.props.onLeave);
} }
if (this.props.leaving && !leaving) { // page is entered if (this.props.leaving && !leaving) { // page is entered
this.animationRunner = createAnimationRunner(animationsIn, this.handleAnimationsUpdate); this.animationRunner = createAnimationRunner(this.animationsIn, this.handleAnimationsUpdate);
this.animationRunner.run(); this.animationRunner.run();
} }
} }
@@ -132,21 +133,28 @@ class PageItem extends React.Component {
return this.state.animations[name]; return this.state.animations[name];
}; };
getItem = (props) => {
const [quadrantName, itemName] = props.pageName.split('/');
const item = props.items.filter(item => item.quadrant === quadrantName && item.name === itemName)[0];
return item;
}
getItemsInRing = (props) => {
const item = this.getItem(props);
const itemsInRing = groupByQuadrants(props.items)[item.quadrant][item.ring];
return itemsInRing;
};
render() { render() {
const { leaving, onLeave, pageName, items } = this.props; const item = this.getItem(this.props);
const [quadrantName, itemName] = pageName.split('/'); const itemsInRing = this.getItemsInRing(this.props);
const item = items.filter(item => item.quadrant === quadrantName && item.name === itemName)[0];
const itemsInRing = groupByQuadrants(items)[item.quadrant][item.ring];
// console.log(this.getAnimationState('items'));
return ( return (
<div> <div>
<div className="item-page"> <div className="item-page">
<div className="item-page__nav"> <div className="item-page__nav">
<div className="item-page__nav__inner"> <div className="item-page__nav__inner">
<div className="item-page__header" style={this.getAnimationState('navHeader')}> <div className="item-page__header" style={this.getAnimationState('navHeader')}>
<h3 className="headline">Languages &amp; Frameworks</h3> <h3 className="headline">{translate(item.quadrant)}</h3>
</div> </div>
<ItemList <ItemList

View File

@@ -37,11 +37,21 @@ class Router extends React.Component {
} }
componentWillReceiveProps({ pageName }) { componentWillReceiveProps({ pageName }) {
const leaving = getPageByName(this.props.items, pageName) !== getPageByName(this.props.items, this.state.pageName);
if (leaving) {
this.setState({ this.setState({
...this.state, ...this.state,
nextPageName: pageName, nextPageName: pageName,
leaving: true, leaving: true,
}); });
} else {
// stay on same page
this.setState({
...this.state,
pageName,
});
}
} }
handlePageLeave = () => { handlePageLeave = () => {

View File

@@ -0,0 +1,8 @@
---
title: "Flow"
ring: assess
quadrant: languages-and-frameworks
---
Irgendwas über flow...

View File

@@ -1,7 +1,7 @@
:root { :root {
--color-gray-dark: #475157; --color-gray-dark: #475157;
--color-gray-dark-alt: #4F585E; --color-gray-dark-alt: #4F585E;
--color-gray-dark-alt2: #525C63; --color-gray-dark-alt2: #434D53;
--color-gray-normal: #A1A6AA; --color-gray-normal: #A1A6AA;
--color-gray-light: #7D878D; --color-gray-light: #7D878D;