summaryrefslogtreecommitdiffstats
path: root/src/components/CountUp.vue
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/CountUp.vue')
-rw-r--r--src/components/CountUp.vue79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/components/CountUp.vue b/src/components/CountUp.vue
new file mode 100644
index 0000000..3bd0107
--- /dev/null
+++ b/src/components/CountUp.vue
@@ -0,0 +1,79 @@
+<template>
+ <span v-if="isNum" ref="output">{{ outputFixed }}</span> <span v-if="isNum">{{ unit }}</span>
+ <span v-else>{{ value }}</span>
+</template>
+
+<script lang="ts">
+
+import { sleep } from "../util.ts";
+
+export default {
+
+ props: {
+ /** Value to count */
+ value: {
+ type: [ String, Number ],
+ default: 0,
+ },
+ time: {
+ type: Number,
+ default: 0.3,
+ },
+ /** Unit of the value */
+ unit: {
+ type: String,
+ default: "ms",
+ },
+ },
+
+ data() {
+ return {
+ output: "",
+ frameDuration: 30,
+ };
+ },
+
+ computed: {
+ isNum() {
+ return typeof this.value === "number";
+ },
+ outputFixed() {
+ if (typeof this.output === "number") {
+ if (this.output < 1) {
+ return "<1";
+ } else if (Number.isInteger(this.output)) {
+ return this.output;
+ } else {
+ return this.output.toFixed(2);
+ }
+ } else {
+ return this.output;
+ }
+ }
+ },
+
+ watch: {
+ async value(from, to) {
+ let diff = to - from;
+ let frames = 12;
+ let step = Math.floor(diff / frames);
+
+ if (! (isNaN(step) || ! this.isNum || (diff > 0 && step < 1) || (diff < 0 && step > 1) || diff === 0)) {
+ for (let i = 1; i < frames; i++) {
+ this.output += step;
+ await sleep(15);
+ }
+ }
+
+ this.output = this.value;
+ },
+ },
+
+ mounted() {
+ this.output = this.value;
+ },
+
+ methods: {},
+
+};
+</script>