凭据上面提到的javascript hook,我们可以在before-enter钩子函数里配置初始状态,接着在enter钩子函数里配置transition竣事状态。那么,我们的初始状态是什么呢?我们通过getBoundingClientRect,可以获取到enter元素(后用to来标识)的DOMRect数据,包罗top, left, bottom, right, width, height , x, y。 同时我们也能通过之前生存的leave位置map获取到leave条目标位置信息(称为from)。所以在before-enter时,我们通过计较获得的偏移量,通过translate去初始化to元素的位置。然后再在enter阶段,translate其值到from, 再加上transition到css中即可。
在before-enter钩子中:
// 移动元素的标识符 const key = el.dataset.key; // enter条目 map,留意这里,在before-enter钩子中, // receiveRectMap是get不到to的。需要非凡处理惩罚。后头有提及 const to = receiveRectMap.get(key); // leave条目 map const from = sendRectMap.get(key); // 计较偏移量 const dx = from.left - to.left; const dy = from.top - to.top; // 初始化to条目标位置 el.style.transform = `translate(${dx}px, ${dy}px)`; el.style.opacity = 0;
在enter钩子中:
el.style.transition = "all 800ms"; el.style.transform = ""; el.style.opacity = 1; el.style.display = "block";
上面的代码中,在before-enter内里,to是通过receiveRectMap.get(key)来获取的。可是,这时,receiveRectMap中还没有对应key的DOMRect值。固然,before-enter的入参是el(HTMLElement),可是该el元素的DOMRect中的所有值都为0,所以我们需要在enter要领中,把el塞入到receiveRectMap中。这样就会有一个抵牾,那就是无法在before-enter中通过translate初始化to元素的位置了。所以,我们这里利用defer transition技能,延迟transition的产生。
我们可以在enter中利用setTimeout可能requestAnimationFrame实现defer transition,
requestAnimationFrame(() => { const key = el.dataset.key; // 这样,receiveRectMap中就有该key的值了。 const to = receiveRectMap.get(key); const from = sendRectMap.get(key); const dx = from.left - to.left; const dy = from.top - to.top; // 由于我们延迟了transition的产生, // 所以to元素的位置其实已经达到了目标职位置, // 所以我们需要利用transition手动地将其过渡到from位置,这一行很重要 el.style.transition = "all 0ms"; el.style.transform = `translate(${dx}px, ${dy}px)`; // 初始化竣事后,在下一个animation frame中,利用FLIP技能,使其移动返来。 requestAnimationFrame(() => { el.style.transition = "all 800ms"; el.style.transform = ""; el.style.opacity = 1; el.style.display = "block"; }); });
完整代码可以参考codepen
最后结果:
以上就是如安在Vue中实现Svelte的Defer Transition的具体内容,更多关于Vue 实现Svelte的Defer Transition的资料请存眷剧本之家其它相关文章!
您大概感乐趣的文章: