upper entranceTransition.ts
This commit is contained in:
@@ -1,105 +0,0 @@
|
|||||||
import type { ObjectDirective } from "vue";
|
|
||||||
|
|
||||||
const ENTRANCE_DURATION = 400;
|
|
||||||
const ACTIVE_CLASS = "entrance-fade-up-enter-active";
|
|
||||||
const FROM_CLASS = "entrance-fade-up-enter-from";
|
|
||||||
const TO_CLASS = "entrance-fade-up-enter-to";
|
|
||||||
const STATE_KEY = Symbol("entrance-transition-state");
|
|
||||||
|
|
||||||
type EntranceTransitionValue = number | string | { delay?: number | string } | undefined;
|
|
||||||
|
|
||||||
interface EntranceTransitionState {
|
|
||||||
frameId?: number;
|
|
||||||
timerId?: number;
|
|
||||||
delay: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
type EntranceTransitionElement = HTMLElement & {
|
|
||||||
[STATE_KEY]?: EntranceTransitionState;
|
|
||||||
};
|
|
||||||
|
|
||||||
function getDelay(value: EntranceTransitionValue): number {
|
|
||||||
const rawDelay = typeof value === "object" && value !== null ? value.delay : value;
|
|
||||||
const delay = Number(rawDelay ?? 0);
|
|
||||||
return Number.isFinite(delay) ? Math.max(0, delay) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setDelay(element: EntranceTransitionElement, delay: number): void {
|
|
||||||
element.style.setProperty("--entrance-delay", `${delay}ms`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function cleanup(element: EntranceTransitionElement): void {
|
|
||||||
const state = element[STATE_KEY];
|
|
||||||
if (!state) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.frameId !== undefined) {
|
|
||||||
window.cancelAnimationFrame(state.frameId);
|
|
||||||
}
|
|
||||||
if (state.timerId !== undefined) {
|
|
||||||
window.clearTimeout(state.timerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
element.classList.remove(ACTIVE_CLASS, FROM_CLASS, TO_CLASS);
|
|
||||||
element.style.removeProperty("--entrance-delay");
|
|
||||||
delete element[STATE_KEY];
|
|
||||||
}
|
|
||||||
|
|
||||||
const vEntranceTransition: ObjectDirective<HTMLElement, EntranceTransitionValue> = {
|
|
||||||
beforeMount(element, binding) {
|
|
||||||
if (!(element instanceof HTMLElement)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const target = element as EntranceTransitionElement;
|
|
||||||
const delay = getDelay(binding.value);
|
|
||||||
target[STATE_KEY] = { delay };
|
|
||||||
setDelay(target, delay);
|
|
||||||
target.classList.add(ACTIVE_CLASS, FROM_CLASS);
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted(element) {
|
|
||||||
if (!(element instanceof HTMLElement)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const target = element as EntranceTransitionElement;
|
|
||||||
const state = target[STATE_KEY];
|
|
||||||
if (!state) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.frameId = window.requestAnimationFrame(() => {
|
|
||||||
state.frameId = window.requestAnimationFrame(() => {
|
|
||||||
state.frameId = undefined;
|
|
||||||
target.classList.remove(FROM_CLASS);
|
|
||||||
target.classList.add(TO_CLASS);
|
|
||||||
state.timerId = window.setTimeout(() => cleanup(target), ENTRANCE_DURATION + state.delay);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
updated(element, binding) {
|
|
||||||
if (!(element instanceof HTMLElement) || binding.value === binding.oldValue) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const target = element as EntranceTransitionElement;
|
|
||||||
const state = target[STATE_KEY];
|
|
||||||
if (!state) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.delay = getDelay(binding.value);
|
|
||||||
setDelay(target, state.delay);
|
|
||||||
},
|
|
||||||
|
|
||||||
beforeUnmount(element) {
|
|
||||||
if (element instanceof HTMLElement) {
|
|
||||||
cleanup(element as EntranceTransitionElement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default vEntranceTransition;
|
|
||||||
+2
-2
@@ -10,7 +10,7 @@ import { VCan, VRole } from "timi-web-api/utils/directives/Access";
|
|||||||
import type { ApiResponse } from "timi-web-api";
|
import type { ApiResponse } from "timi-web-api";
|
||||||
import { Message } from "@/utils/message";
|
import { Message } from "@/utils/message";
|
||||||
import { initializeTwaBridge } from "@/utils/twaBridge";
|
import { initializeTwaBridge } from "@/utils/twaBridge";
|
||||||
import vEntranceTransition from "@/directives/entranceTransition";
|
import { VEntranceTransition } from "timi-tdesign-mobile";
|
||||||
import timiWebStyle from "../../timi-web/src/assets/style/timi-web.less?inline";
|
import timiWebStyle from "../../timi-web/src/assets/style/timi-web.less?inline";
|
||||||
import tdesignCustomStyle from "../../timi-tdesign-mobile/src/assets/style/tdesign-custom.less?inline";
|
import tdesignCustomStyle from "../../timi-tdesign-mobile/src/assets/style/tdesign-custom.less?inline";
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ async function bootstrap(): Promise<void> {
|
|||||||
app.use(pinia);
|
app.use(pinia);
|
||||||
app.directive("can", VCan);
|
app.directive("can", VCan);
|
||||||
app.directive("role", VRole);
|
app.directive("role", VRole);
|
||||||
app.directive("entrance-transition", vEntranceTransition);
|
app.directive("entrance-transition", VEntranceTransition);
|
||||||
|
|
||||||
const userStore = useUserStore(pinia);
|
const userStore = useUserStore(pinia);
|
||||||
const currentStoreStore = useCurrentStoreStore(pinia);
|
const currentStoreStore = useCurrentStoreStore(pinia);
|
||||||
|
|||||||
Reference in New Issue
Block a user