1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var raf = (typeof window !== 'undefined' && window.requestAnimationFrame) || setTimeout;
|
4 | var nextFrame = function (fn) { raf(function () { raf(fn); }); };
|
5 | function setNextFrame(obj, prop, val) {
|
6 | nextFrame(function () { obj[prop] = val; });
|
7 | }
|
8 | function getTextNodeRect(textNode) {
|
9 | var rect;
|
10 | if (document.createRange) {
|
11 | var range = document.createRange();
|
12 | range.selectNodeContents(textNode);
|
13 | if (range.getBoundingClientRect) {
|
14 | rect = range.getBoundingClientRect();
|
15 | }
|
16 | }
|
17 | return rect;
|
18 | }
|
19 | function calcTransformOrigin(isTextNode, textRect, boundingRect) {
|
20 | if (isTextNode) {
|
21 | if (textRect) {
|
22 |
|
23 | var relativeCenterX = textRect.left + textRect.width / 2 - boundingRect.left;
|
24 | var relativeCenterY = textRect.top + textRect.height / 2 - boundingRect.top;
|
25 | return relativeCenterX + 'px ' + relativeCenterY + 'px';
|
26 | }
|
27 | }
|
28 | return '0 0';
|
29 | }
|
30 | function getTextDx(oldTextRect, newTextRect) {
|
31 | if (oldTextRect && newTextRect) {
|
32 | return ((oldTextRect.left + oldTextRect.width / 2) - (newTextRect.left + newTextRect.width / 2));
|
33 | }
|
34 | return 0;
|
35 | }
|
36 | function getTextDy(oldTextRect, newTextRect) {
|
37 | if (oldTextRect && newTextRect) {
|
38 | return ((oldTextRect.top + oldTextRect.height / 2) - (newTextRect.top + newTextRect.height / 2));
|
39 | }
|
40 | return 0;
|
41 | }
|
42 | function isTextElement(elm) {
|
43 | return elm.childNodes.length === 1 && elm.childNodes[0].nodeType === 3;
|
44 | }
|
45 | var removed, created;
|
46 | function pre() {
|
47 | removed = {};
|
48 | created = [];
|
49 | }
|
50 | function create(oldVnode, vnode) {
|
51 | var hero = vnode.data.hero;
|
52 | if (hero && hero.id) {
|
53 | created.push(hero.id);
|
54 | created.push(vnode);
|
55 | }
|
56 | }
|
57 | function destroy(vnode) {
|
58 | var hero = vnode.data.hero;
|
59 | if (hero && hero.id) {
|
60 | var elm = vnode.elm;
|
61 | vnode.isTextNode = isTextElement(elm);
|
62 | vnode.boundingRect = elm.getBoundingClientRect();
|
63 | vnode.textRect = vnode.isTextNode ? getTextNodeRect(elm.childNodes[0]) : null;
|
64 | var computedStyle = window.getComputedStyle(elm, void 0);
|
65 | vnode.savedStyle = JSON.parse(JSON.stringify(computedStyle));
|
66 | removed[hero.id] = vnode;
|
67 | }
|
68 | }
|
69 | function post() {
|
70 | var i, id, newElm, oldVnode, oldElm, hRatio, wRatio, oldRect, newRect, dx, dy, origTransform, origTransition, newStyle, oldStyle, newComputedStyle, isTextNode, newTextRect, oldTextRect;
|
71 | for (i = 0; i < created.length; i += 2) {
|
72 | id = created[i];
|
73 | newElm = created[i + 1].elm;
|
74 | oldVnode = removed[id];
|
75 | if (oldVnode) {
|
76 | isTextNode = oldVnode.isTextNode && isTextElement(newElm);
|
77 | newStyle = newElm.style;
|
78 | newComputedStyle = window.getComputedStyle(newElm, void 0);
|
79 | oldElm = oldVnode.elm;
|
80 | oldStyle = oldElm.style;
|
81 |
|
82 | newRect = newElm.getBoundingClientRect();
|
83 | oldRect = oldVnode.boundingRect;
|
84 |
|
85 | if (isTextNode) {
|
86 | newTextRect = getTextNodeRect(newElm.childNodes[0]);
|
87 | oldTextRect = oldVnode.textRect;
|
88 | dx = getTextDx(oldTextRect, newTextRect);
|
89 | dy = getTextDy(oldTextRect, newTextRect);
|
90 | }
|
91 | else {
|
92 |
|
93 | dx = oldRect.left - newRect.left;
|
94 | dy = oldRect.top - newRect.top;
|
95 | }
|
96 | hRatio = newRect.height / (Math.max(oldRect.height, 1));
|
97 | wRatio = isTextNode ? hRatio : newRect.width / (Math.max(oldRect.width, 1));
|
98 |
|
99 | origTransform = newStyle.transform;
|
100 | origTransition = newStyle.transition;
|
101 | if (newComputedStyle.display === 'inline')
|
102 | newStyle.display = 'inline-block';
|
103 | newStyle.transition = origTransition + 'transform 0s';
|
104 | newStyle.transformOrigin = calcTransformOrigin(isTextNode, newTextRect, newRect);
|
105 | newStyle.opacity = '0';
|
106 | newStyle.transform = origTransform + 'translate(' + dx + 'px, ' + dy + 'px) ' +
|
107 | 'scale(' + 1 / wRatio + ', ' + 1 / hRatio + ')';
|
108 | setNextFrame(newStyle, 'transition', origTransition);
|
109 | setNextFrame(newStyle, 'transform', origTransform);
|
110 | setNextFrame(newStyle, 'opacity', '1');
|
111 |
|
112 | for (var key in oldVnode.savedStyle) {
|
113 | if (parseInt(key) != key) {
|
114 | var ms = key.substring(0, 2) === 'ms';
|
115 | var moz = key.substring(0, 3) === 'moz';
|
116 | var webkit = key.substring(0, 6) === 'webkit';
|
117 | if (!ms && !moz && !webkit)
|
118 | oldStyle[key] = oldVnode.savedStyle[key];
|
119 | }
|
120 | }
|
121 | oldStyle.position = 'absolute';
|
122 | oldStyle.top = oldRect.top + 'px';
|
123 | oldStyle.left = oldRect.left + 'px';
|
124 | oldStyle.width = oldRect.width + 'px';
|
125 | oldStyle.height = oldRect.height + 'px';
|
126 | oldStyle.margin = '0';
|
127 | oldStyle.transformOrigin = calcTransformOrigin(isTextNode, oldTextRect, oldRect);
|
128 | oldStyle.transform = '';
|
129 | oldStyle.opacity = '1';
|
130 | document.body.appendChild(oldElm);
|
131 | setNextFrame(oldStyle, 'transform', 'translate(' + -dx + 'px, ' + -dy + 'px) scale(' + wRatio + ', ' + hRatio + ')');
|
132 | setNextFrame(oldStyle, 'opacity', '0');
|
133 | oldElm.addEventListener('transitionend', function (ev) {
|
134 | if (ev.propertyName === 'transform')
|
135 | document.body.removeChild(ev.target);
|
136 | });
|
137 | }
|
138 | }
|
139 | removed = created = undefined;
|
140 | }
|
141 | exports.heroModule = { pre: pre, create: create, destroy: destroy, post: post };
|
142 | exports.default = exports.heroModule;
|
143 |
|
\ | No newline at end of file |