transition tests
by nkovacs
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/0.12.16/vue.min.js"></script>
<a href="#" v-on="click: setone">Set one</a>
<a href="#" v-on="click: testsimple">Simple</a>
<a href="#" v-on="click: testback">Back</a>
<a href="#" v-on="click: testquick">Quick</a>
<a href="#" v-on="click: testslow">Slow</a>
<a href="#" v-on="click: testinstant">Instant</a>
<a href="#" v-on="click: set('one')">One</a>
<a href="#" v-on="click: set('two')">Two</a>
<a href="#" v-on="click: set('three')">Three</a>
<section id="main">
<component is="{{currentView}}" v-transition="page" transition-mode="in-out"></component>
</section>
CSS
#comp1 {
background: red;
width: 300px;
height: 200px;
}
#comp1b {
background: lightsteelblue;
height: 50px;
width: 100px;
}
#comp2 {
background: blue;
width: 100px;
height: 100px;
}
#comp2b {
background: orange;
height: 40px;
width: 200px;
}
#comp3 {
background: green;
width: 400px;
height: 200px;
}
.morphing-box {
transition: background ease 1.5s, width ease 1.5s, height ease 1.5s, top ease 1.5s, left ease 1.5s, opacity ease 1.5s;
}
/* without this, it acts as css:false, which is buggy */
.page-transition {
transition: background ease 1.5s;
}
.hiding {
transition: opacity ease 0.5s;
opacity: 0;
}
.showing {
transition: opacity ease 0.5s;
}
.pre-show {
opacity: 0;
}
JavaScript
Vue.config.debug = true;
var target = null;
var transitioner = null;
function getPosition(elem)
{
var box = elem.getBoundingClientRect();
var docElement = document.documentElement;
return {
top: box.top + window.pageYOffset - docElement.clientTop,
left: box.left + window.pageXOffset - docElement.clientLeft
};
}
function morph(source, target, callback) {
var sourceElements = source.querySelectorAll('[data-transition-id]');
var targetElements = target.querySelectorAll('[data-transition-id]');
var transitionPairs = {};
var i, l;
var transId;
for (i = 0, l = sourceElements.length; i < l; i++) {
transId = sourceElements[i].getAttribute('data-transition-id');
transitionPairs[transId] = {
source: sourceElements[i]
};
}
for (i = 0, l = targetElements.length; i < l; i++) {
transId = targetElements[i].getAttribute('data-transition-id');
if (transitionPairs[transId]) {
transitionPairs[transId].target = targetElements[i];
}
}
source.style.position = "absolute";
var sourcePosition = getPosition(source);
source.style.top = sourcePosition.top + "px";
source.style.left = sourcePosition.left + "px";
target.style.visibility = 'hidden';
target.style.display = '';
var targetEl;
var sourceEl;
var sourceElPosition;
var sourceStyle;
var targetStyle;
var callbackCalled = false; // TODO make it smarter with multiple elements
// fade out all other elements
var otherElements = source.querySelectorAll(':not([data-transition-id])');
for (i = 0, l = otherElements.length; i < l; i++) {
Vue.util.addClass(otherElements[i], 'hiding');
}
function handleCallback(sourceEl) {
if (!callbackCalled && callback !== undefined) {
callbackCalled = true;
var trdone = function() {
...