@varlet/ui
Version:
A Vue3 component library based on Material Design 2 and 3, supporting mobile and desktop.
169 lines (168 loc) • 4.69 kB
JavaScript
import { defineComponent, onActivated, onDeactivated, onMounted, onUnmounted, ref, watch } from "vue";
import { call, cancelAnimationFrame, requestAnimationFrame, toNumber } from "@varlet/shared";
import { createNamespace } from "../utils/components.mjs";
import { padStart } from "../utils/shared.mjs";
import { props } from "./props.mjs";
const { name, n } = createNamespace("countdown");
const SECOND = 1e3;
const MINUTE = 60 * SECOND;
const HOUR = 60 * MINUTE;
const DAY = 24 * HOUR;
import { normalizeProps as _normalizeProps, guardReactiveProps as _guardReactiveProps, renderSlot as _renderSlot, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, normalizeClass as _normalizeClass, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue";
function __render__(_ctx, _cache) {
return _openBlock(), _createElementBlock(
"div",
{
class: _normalizeClass(_ctx.n())
},
[
_renderSlot(_ctx.$slots, "default", _normalizeProps(_guardReactiveProps(_ctx.timeData)), () => [
_createTextVNode(
_toDisplayString(_ctx.showTime),
1
/* TEXT */
)
])
],
2
/* CLASS */
);
}
const __sfc__ = defineComponent({
name,
props,
setup(props2) {
const showTime = ref("");
const timeData = ref({
days: 0,
hours: 0,
minutes: 0,
seconds: 0,
milliseconds: 0
});
let endTime = 0;
let isStart = false;
let handle = 0;
let remainingTime = 0;
let cacheIsStart;
watch(
() => props2.time,
() => {
reset();
if (props2.autoStart) {
start();
}
}
);
onMounted(() => {
countdown();
if (props2.autoStart) {
start();
}
});
onActivated(() => {
if (cacheIsStart == null) {
return;
}
isStart = cacheIsStart;
if (isStart === true) {
start(true);
}
});
onDeactivated(() => {
cacheIsStart = isStart;
pause();
});
onUnmounted(pause);
function parseFormat(format, time) {
const scannedTimes = Object.values(time);
const scannedFormats = ["DD", "HH", "mm", "ss"];
const padValues = [24, 60, 60, 1e3];
scannedFormats.forEach((scannedFormat, index) => {
if (!format.includes(scannedFormat)) {
scannedTimes[index + 1] += scannedTimes[index] * padValues[index];
} else {
format = format.replace(scannedFormat, padStart(`${scannedTimes[index]}`, 2, "0"));
}
});
if (format.includes("S")) {
const ms = padStart(`${scannedTimes[scannedTimes.length - 1]}`, 3, "0");
if (format.includes("SSS")) {
format = format.replace("SSS", ms);
} else if (format.includes("SS")) {
format = format.replace("SS", ms.slice(0, 2));
} else {
format = format.replace("S", ms.slice(0, 1));
}
}
return format;
}
function displayTime(durationTime) {
const days = Math.floor(durationTime / DAY);
const hours = Math.floor(durationTime % DAY / HOUR);
const minutes = Math.floor(durationTime % HOUR / MINUTE);
const seconds = Math.floor(durationTime % MINUTE / SECOND);
const milliseconds = Math.floor(durationTime % SECOND);
const time = {
days,
hours,
minutes,
seconds,
milliseconds
};
timeData.value = time;
call(props2.onChange, timeData.value);
showTime.value = parseFormat(props2.format, time);
}
function countdown() {
const { time, onEnd } = props2;
const now = performance.now();
if (!endTime) {
endTime = now + toNumber(time);
}
remainingTime = endTime - now;
if (remainingTime < 0) {
remainingTime = 0;
}
displayTime(remainingTime);
if (remainingTime === 0) {
call(onEnd);
return;
}
if (isStart) {
handle = requestAnimationFrame(countdown);
}
}
function start(resume = false) {
if (isStart && !resume) {
return;
}
isStart = true;
endTime = performance.now() + (remainingTime || toNumber(props2.time));
countdown();
}
function pause() {
isStart = false;
cancelAnimationFrame(handle);
}
function reset() {
endTime = 0;
isStart = false;
cancelAnimationFrame(handle);
countdown();
}
return {
showTime,
timeData,
n,
start,
pause,
reset
};
}
});
__sfc__.render = __render__;
var stdin_default = __sfc__;
export {
stdin_default as default
};