Add demonstration of hero animations

pull/2/head
paldepind 10 years ago
parent f43fe5a107
commit f11a3c9571

@ -0,0 +1,142 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Hero animation</title>
<script type="text/javascript" src="build.js"></script>
<style>
html, body {
height: 100%;
margin: 0;
}
body {
background: #aaaaaa;
font-family: sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#container {
width: 28em;
max-width: 100%;
height: 40em;
max-height: 100%;
background: #fff;
box-shadow: 0 0 1em rgba(0, 0, 0, .5);
position: relative;
overflow: hidden;
}
.page {
transition: opacity 0.4s ease-in-out,
transform 0.4s ease-in-out;
width: 100%;
}
h2 {
font-size: 1.1em;
margin: .2em 0;
}
.header {
height: 3.5em;
background: #1293ea;
}
.header-content {
width: 100%;
box-sizing: border-box;
padding: .4em .8em;
color: #fff;
display: flex;
align-items: center;
position: absolute;
transition: opacity 0.4s ease-in-out,
transform 0.4s ease-in-out;
}
.header h1 {
font-weight: normal;
margin: 0;
font-size: 1.5em;
line-height: 1.8em;
}
.header-title {
color: #fff;
font-size: 1.5em;
line-height: 1.8em;
transition: transform 0.4s ease-in-out;
}
.header .rank {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 2.7em;
height: 2.7em;
margin-right: .5em;
position: relative;
}
.header .rank-circle {
position: absolute;
background: #fff;
width: 2.7em;
height: 2.7em;
border-radius: 1.35em;
margin-right: .5em;
transition: transform 0.4s ease-in-out;
top: 0;
left: 0;
}
.header-rank {
z-index: 2;
color: #1293ea;
font-size: 1.5em;
}
.header .close {
line-height: 1.8em;
cursor: pointer;
text-align: center;
width: 1.8em;
height: 1.8em;
border-radius: .9em;
background: rgba(0, 0, 0, .5);
transition: transform 0.4s ease-in-out;
}
.hero {
transition: transform 0.4s ease-in-out,
opacity 0.4s ease-in-out;
}
.page-content {
position: relative;
}
.list {
transition: transform 0.4s ease-in-out,
opacity 0.4s ease-in-out;
}
.desc {
transition: transform 0.4s ease-in-out,
opacity 0.4s ease-in-out;
padding: 1em;
}
.spacer {
flex: 1;
}
.row {
cursor: pointer;
box-sizing: border-box;
padding: 1em;
}
.row:not(:first-child) {
border-top: 1px solid #eeeeee;
}
.row div {
display: inline-block;
}
.row > div:nth-child(1) {
text-align: center;
margin-right: 1em;
width: 1em;
}
</style>
</head>
<body>
<div id="container"></div>
</body>
</html>

@ -0,0 +1,117 @@
/* jshint esnext: true */
var snabbdom = require('../../snabbdom.js');
var patch = snabbdom.init([
require('../../modules/class'),
require('../../modules/hero'),
require('../../modules/style'),
require('../../modules/eventlisteners'),
]);
var h = require('../../h.js');
var vnode;
var data = {
selected: undefined,
movies: [
{rank: 1, title: 'This is an', desc: 'Lorem ipsum dolor sit amet, sed pede integer vitae bibendum, accumsan sit, vulputate aenean tempora ipsum. Lorem sed id et metus, eros posuere suspendisse nec nunc justo, fusce augue placerat nibh purus suspendisse. Aliquam aliquam, ut eget. Mollis a eget sed nibh tincidunt nec, mi integer, proin magna lacus iaculis tortor. Aliquam vel arcu arcu, vivamus a urna fames felis vel wisi, cursus tortor nec erat dignissim cras sem, mauris ac venenatis tellus elit.'},
{rank: 2, title: 'example of', desc: 'Consequuntur ipsum nulla, consequat curabitur in magnis risus. Taciti mattis bibendum tellus nibh, at dui neque eget, odio pede ut, sapien pede, ipsum ut. Sagittis dui, sodales sem, praesent ipsum conubia eget lorem lobortis wisi.'},
{rank: 3, title: 'Snabbdom', desc: 'Quam lorem aliquam fusce wisi, urna purus ipsum pharetra sed, at cras sodales enim vestibulum odio cras, luctus integer phasellus.'},
{rank: 4, title: 'doing hero transitions', desc: 'Et orci hac ultrices id in. Diam ultrices luctus egestas, sem aliquam auctor molestie odio laoreet. Pede nam cubilia, diam vestibulum ornare natoque, aenean etiam fusce id, eget dictum blandit et mauris mauris. Metus amet ad, elit porttitor a aliquet commodo lacus, integer neque imperdiet augue laoreet, nonummy turpis lacus sed pulvinar condimentum platea. Wisi eleifend quis, tristique dictum, ac dictumst. Sem nec tristique vel vehicula fringilla, nibh eu et posuere mi rhoncus.'},
{rank: 5, title: 'using the', desc: 'Pede nam cubilia, diam vestibulum ornare natoque, aenean etiam fusce id, eget dictum blandit et mauris mauris. Metus amet ad, elit porttitor a aliquet commodo lacus, integer neque imperdiet augue laoreet, nonummy turpis lacus sed pulvinar condimentum platea. Wisi eleifend quis, tristique dictum, ac dictumst. Sem nec tristique vel vehicula fringilla, nibh eu et posuere mi rhoncus.'},
{rank: 6, title: 'module for hero transitions', desc: 'Sapien laoreet, ligula elit tortor nulla pellentesque, maecenas enim turpis, quae duis venenatis vivamus ultricies, nunc imperdiet sollicitudin ipsum malesuada. Ut sem. Wisi fusce nullam nibh enim. Nisl hymenaeos id sed sed in. Proin leo et, pulvinar nunc pede laoreet.'},
{rank: 7, title: 'click on ar element in', desc: 'Accumsan quia, id nascetur dui et congue erat, id excepteur, primis ratione nec. At nulla et. Suspendisse lobortis, lobortis in tortor fringilla, duis adipiscing vestibulum voluptates sociosqu auctor.'},
{rank: 8, title: 'the list', desc: 'Ante tellus egestas vel hymenaeos, ut viverra nibh ut, ipsum nibh donec donec dolor. Eros ridiculus vel egestas convallis ipsum, commodo ut venenatis nullam porta iaculis, suspendisse ante proin leo, felis risus etiam.'},
{rank: 9, title: 'to witness', desc: 'Metus amet ad, elit porttitor a aliquet commodo lacus, integer neque imperdiet augue laoreet, nonummy turpis lacus sed pulvinar condimentum platea. Wisi eleifend quis, tristique dictum, ac dictumst.'},
{rank: 10, title: 'the effect', desc: 'Et orci hac ultrices id in. Diam ultrices luctus egestas, sem aliquam auctor molestie odio laoreet. Pede nam cubilia, diam vestibulum ornare natoque, aenean etiam fusce id, eget dictum blandit et mauris mauris'},
]
};
function select(m) {
data.selected = m;
render();
}
function render() {
vnode = patch(vnode, view(data));
}
const fadeInOutStyle = {
opacity: '0', 'd-opacity': '1', remove: {opacity: '0'}
};
const detailView = (movie) =>
h('div.page', {style: fadeInOutStyle}, [
h('div.header', [
h('div.header-content.detail', {
style: {opacity: '1', remove: {opacity: '0'}},
}, [
h('div.rank', [
h('span.header-rank.hero', {hero: {id: 'rank'+movie.rank}}, movie.rank),
h('div.rank-circle', {
style: {transform: 'scale(0)', 'd-transform': 'scale(1)',
destroy: {transform: 'scale(0)'}},
}),
]),
h('div.hero.header-title', {hero: {id: movie.title}}, movie.title),
h('div.spacer'),
h('div.close', {
on: {click: [select, undefined]},
style: {transform: 'scale(0)', 'd-transform': 'scale(1)',
destroy: {transform: 'scale(0)'}},
}, 'x'),
]),
]),
h('div.page-content', [
h('div.desc', {
style: {opacity: '0', 'd-opacity': '1',
transform: 'translateX(3em)', 'd-transform': 'translate(0)',
remove: {opacity: '0', position: 'absolute', top: '0', left: '0',
transform: 'translateX(3em)'}
}
}, [
h('h2', 'Description:'),
h('span', movie.desc),
]),
]),
]);
const overviewView = (movies) =>
h('div.page', {style: fadeInOutStyle}, [
h('div.header', [
h('div.header-content.overview', {
style: fadeInOutStyle,
}, [
h('div.header-title', {
style: {transform: 'translateY(-2em)', 'd-transform': 'translate(0)',
destroy: {transform: 'translateY(-2em)'}}
}, 'Top 10 movies'),
h('div.spacer'),
]),
]),
h('div.page-content', [
h('div.list', {
style: {opacity: '0', 'd-opacity': '1',
remove: {opacity: '0', position: 'absolute', top: '0', left: '0'}}
}, movies.map((movie) =>
h('div.row', {
on: {click: [select, movie]},
}, [
h('div.hero.rank', [
h('span.hero', {hero: {id: 'rank'+movie.rank}}, movie.rank)
]),
h('div.hero', {hero: {id: movie.title}}, movie.title)
])
)),
]),
]);
const view = (data) =>
h('div', [
data.selected ? detailView(data.selected) : overviewView(data.movies),
]);
window.addEventListener('DOMContentLoaded', () => {
var container = document.getElementById('container');
vnode = patch(snabbdom.emptyNodeAt(container), view(data));
render();
});

@ -224,38 +224,48 @@ function updateStyle(oldVnode, vnode) {
}
}
function applyDestroyStyle(vnode) {
var style,
name,
elm = vnode.elm,
s = vnode.data.style;
if (!s || !(style = s.destroy)) return;
for (name in style) {
elm.style[name] = style[name];
}
}
function applyRemoveStyle(vnode, rm) {
var s = vnode.data.style;
if (!s || !s.remove) return;
var cur,
name,
if (!s || !s.remove) {
rm();
return;
}
var name,
elm = vnode.elm,
idx,
i = 0,
maxDur = 0,
compStyle,
style = s.remove;
style = s.remove,
amount = 0;
var applied = [];
for (name in style) {
applied.push(name);
elm.style[name] = style[name];
}
if (applied.length > 0) {
compStyle = getComputedStyle(elm);
var dels = compStyle['transition-delay'].split(', ');
var durs = compStyle['transition-duration'].split(', ');
var props = compStyle['transition-property'].split(', ');
for (; i < applied.length; ++i) {
idx = props.indexOf(applied[i]);
if (idx !== -1) maxDur = Math.max(maxDur, parseFloat(dels[idx]) + parseFloat(durs[idx]));
}
setTimeout(rm, maxDur * 1000); // s to ms
} else {
rm();
for (; i < props.length; ++i) {
if (applied.indexOf(props[i]) !== -1) amount++;
}
elm.addEventListener('transitionend', function (ev) {
if (ev.target === elm) --amount;
if (amount === 0) rm();
});
}
module.exports = { create: updateStyle, update: updateStyle, remove: applyRemoveStyle };
module.exports = { create: updateStyle, update: updateStyle, destroy: applyDestroyStyle, remove: applyRemoveStyle };
},{}],8:[function(require,module,exports){
// jshint newcap: false

Loading…
Cancel
Save