web-ui-pack
Version:
Web package with UI elements
87 lines (86 loc) • 2.77 kB
JavaScript
import animate from "./animate";
import { styleTransform } from "./styleHelpers";
export default function animateDropdown(el, ms, isHide = false) {
if (!ms) {
const p = Promise.resolve(false);
return Object.assign(p, { stop: () => p });
}
const reg = / *scale[YX]\(([%\d \w.-]+)\) */;
const parseScale = (e) => {
let prev = e.style.transform;
let from = isHide ? 1 : 0;
const r = reg.exec(prev);
if (r) {
prev = prev.replace(r[0], "");
from = Number.parseFloat(r[1]);
}
prev = prev.replace("translateZ(0px)", "");
if (prev) {
prev = `${prev.trim().replace(" ", " ")} `;
}
return { prev, from };
};
const nested = [];
const ch = el.children;
for (let i = 0; i < ch.length; ++i) {
const c = ch.item(i);
const parsed = parseScale(c);
nested.push({ el: c, prev: parsed.prev });
}
const reset = () => {
styleTransform(el, "scaleY", "");
styleTransform(el, "scaleX", "");
el.style.transformOrigin = "";
nested.forEach((e) => {
e.el.style.transform = e.prev.trimEnd();
e.el.style.transformOrigin = "";
!e.el.getAttribute("style") && e.el.removeAttribute("style");
});
const was = el.style.display;
el.style.display = "none";
reset._cached = el.offsetHeight;
el.style.display = was;
!el.getAttribute("style") && el.removeAttribute("style");
};
const to = isHide ? 0 : 1;
const { from } = parseScale(el);
ms *= Math.abs(to - from);
const p = animate(from, to, ms, (v, _t, isLast) => {
if (!el.isConnected) {
p.stop(false);
}
if (isLast || !el.isConnected) {
reset();
return;
}
const pos = el.getAttribute("position");
let tmo = "bottom";
let tmo2 = "top";
let scale = "scaleY";
switch (pos) {
case "bottom":
tmo = "top";
tmo2 = "bottom";
break;
case "left":
tmo = "right";
scale = "scaleX";
tmo2 = "left";
break;
case "right":
tmo = "left";
scale = "scaleX";
tmo2 = "right";
break;
default: break;
}
el.style.transformOrigin = tmo;
styleTransform(el, scale, v);
v !== 0 &&
nested.forEach((e) => {
e.el.style.transform = `${e.prev + scale}(${1 / v}) translateZ(0px)`;
e.el.style.transformOrigin = tmo2;
});
});
return p;
}