mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-06-06 08:27:54 +08:00
feat: 添加两种数字动画组件
This commit is contained in:
parent
a64b236707
commit
0701692461
2
src/components/ReCountTo/README.md
Normal file
2
src/components/ReCountTo/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
normal 普通数字动画组件
|
||||
rebound 回弹式数字动画组件
|
@ -1,10 +1,15 @@
|
||||
import { App } from "vue";
|
||||
import reCountTo from "./src";
|
||||
import reNormalCountTo from "./src/normal";
|
||||
import reboundCountTo from "./src/rebound";
|
||||
|
||||
export const ReCountTo = Object.assign(reCountTo, {
|
||||
export const ReNormalCountTo = Object.assign(reNormalCountTo, {
|
||||
install(app: App) {
|
||||
app.component(reCountTo.name, reCountTo);
|
||||
app.component(reNormalCountTo.name, reNormalCountTo);
|
||||
}
|
||||
});
|
||||
|
||||
export default ReCountTo;
|
||||
export const ReboundCountTo = Object.assign(reboundCountTo, {
|
||||
install(app: App) {
|
||||
app.component(reboundCountTo.name, reboundCountTo);
|
||||
}
|
||||
});
|
||||
|
@ -10,7 +10,7 @@ import { countToProps } from "./props";
|
||||
import { isNumber } from "/@/utils/is";
|
||||
|
||||
export default defineComponent({
|
||||
name: "CountTo",
|
||||
name: "Normal",
|
||||
props: countToProps,
|
||||
emits: ["mounted", "callback"],
|
||||
setup(props, { emit }) {
|
73
src/components/ReCountTo/src/rebound/index.tsx
Normal file
73
src/components/ReCountTo/src/rebound/index.tsx
Normal file
@ -0,0 +1,73 @@
|
||||
import "./rebound.css";
|
||||
import {
|
||||
defineComponent,
|
||||
ref,
|
||||
unref,
|
||||
onBeforeMount,
|
||||
onBeforeUnmount,
|
||||
getCurrentInstance
|
||||
} from "vue";
|
||||
import { reboundProps } from "./props";
|
||||
|
||||
export default defineComponent({
|
||||
name: "Rebound",
|
||||
props: reboundProps,
|
||||
setup(props) {
|
||||
const timer = ref(null);
|
||||
|
||||
onBeforeMount(() => {
|
||||
const ua = navigator.userAgent.toLowerCase();
|
||||
const testUA = regexp => regexp.test(ua);
|
||||
const isSafari = testUA(/safari/g) && !testUA(/chrome/g);
|
||||
|
||||
// Safari浏览器的兼容代码
|
||||
isSafari &&
|
||||
(timer.value = setTimeout(() => {
|
||||
// @ts-ignore
|
||||
getCurrentInstance().refs["ul"].setAttribute(
|
||||
"style",
|
||||
`
|
||||
animation: none;
|
||||
transform: translateY(calc(var(--i) * -9.09%))
|
||||
`
|
||||
);
|
||||
}, props.delay * 1000));
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
clearTimeout(unref(timer));
|
||||
});
|
||||
|
||||
return () => (
|
||||
<>
|
||||
<div
|
||||
class="scroll-num"
|
||||
// @ts-ignore
|
||||
style={{ "--i": props.i, "--delay": props.delay }}>
|
||||
<ul ref="ul" style={{ fontSize: "32px" }}>
|
||||
<li>0</li>
|
||||
<li>1</li>
|
||||
<li>2</li>
|
||||
<li>3</li>
|
||||
<li>4</li>
|
||||
<li>5</li>
|
||||
<li>6</li>
|
||||
<li>7</li>
|
||||
<li>8</li>
|
||||
<li>9</li>
|
||||
<li>0</li>
|
||||
</ul>
|
||||
|
||||
<svg width="0" height="0">
|
||||
<filter id="blur">
|
||||
<feGaussianBlur
|
||||
in="SourceGraphic"
|
||||
stdDeviation={`0 ${props.blur}`}
|
||||
/>
|
||||
</filter>
|
||||
</svg>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
});
|
14
src/components/ReCountTo/src/rebound/props.ts
Normal file
14
src/components/ReCountTo/src/rebound/props.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { PropType } from "vue";
|
||||
import { propTypes } from "/@/utils/propTypes";
|
||||
export const reboundProps = {
|
||||
delay: propTypes.number.def(1),
|
||||
blur: propTypes.number.def(2),
|
||||
i: {
|
||||
type: Number as PropType<number>,
|
||||
required: false,
|
||||
default: 0,
|
||||
validator(value: number) {
|
||||
return value < 10 && value >= 0 && Number.isInteger(value);
|
||||
}
|
||||
}
|
||||
};
|
66
src/components/ReCountTo/src/rebound/rebound.css
Normal file
66
src/components/ReCountTo/src/rebound/rebound.css
Normal file
@ -0,0 +1,66 @@
|
||||
.scroll-num {
|
||||
width: var(--width, 20px);
|
||||
height: var(--height, calc(var(--width, 20px) * 1.8));
|
||||
color: var(--color, #333);
|
||||
font-size: var(--height, calc(var(--width, 20px) * 1.1));
|
||||
line-height: var(--height, calc(var(--width, 20px) * 1.8));
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
animation: enhance-bounce-in-down 1s calc(var(--delay) * 1s) forwards;
|
||||
}
|
||||
|
||||
ul {
|
||||
animation: move 0.3s linear infinite,
|
||||
bounce-in-down 1s calc(var(--delay) * 1s) forwards;
|
||||
}
|
||||
|
||||
@keyframes move {
|
||||
from {
|
||||
transform: translateY(-90%);
|
||||
filter: url(#blur);
|
||||
}
|
||||
to {
|
||||
transform: translateY(1%);
|
||||
filter: url(#blur);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bounce-in-down {
|
||||
from {
|
||||
transform: translateY(calc(var(--i) * -9.09% - 7%));
|
||||
filter: none;
|
||||
}
|
||||
25% {
|
||||
transform: translateY(calc(var(--i) * -9.09% + 3%));
|
||||
}
|
||||
50% {
|
||||
transform: translateY(calc(var(--i) * -9.09% - 1%));
|
||||
}
|
||||
70% {
|
||||
transform: translateY(calc(var(--i) * -9.09% + 0.6%));
|
||||
}
|
||||
85% {
|
||||
transform: translateY(calc(var(--i) * -9.09% - 0.3%));
|
||||
}
|
||||
to {
|
||||
transform: translateY(calc(var(--i) * -9.09%));
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes enhance-bounce-in-down {
|
||||
25% {
|
||||
transform: translateY(8%);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-4%);
|
||||
}
|
||||
70% {
|
||||
transform: translateY(2%);
|
||||
}
|
||||
85% {
|
||||
transform: translateY(-1%);
|
||||
}
|
||||
to {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
<el-row :gutter="24">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<el-card shadow="always">
|
||||
<CountTo
|
||||
<ReNormalCountTo
|
||||
prefix="$"
|
||||
:duration="1000"
|
||||
:color="'#409EFF'"
|
||||
@ -15,14 +15,15 @@
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<el-card shadow="always">
|
||||
<CountTo
|
||||
prefix="$"
|
||||
:duration="2000"
|
||||
:color="'green'"
|
||||
:fontSize="'2.3em'"
|
||||
:startVal="1"
|
||||
:endVal="2000"
|
||||
/>
|
||||
<ul class="flex">
|
||||
<ReboundCountTo
|
||||
v-for="(num, inx) of [1, 6, 6, 6]"
|
||||
:key="inx"
|
||||
:i="num"
|
||||
:blur="inx"
|
||||
:delay="inx + 1"
|
||||
/>
|
||||
</ul>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -30,10 +31,11 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import CountTo from "/@/components/ReCountTo";
|
||||
import { ReNormalCountTo, ReboundCountTo } from "/@/components/ReCountTo";
|
||||
export default {
|
||||
components: {
|
||||
CountTo
|
||||
ReNormalCountTo,
|
||||
ReboundCountTo
|
||||
},
|
||||
setup() {
|
||||
return {};
|
||||
@ -42,6 +44,9 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
:deep(.el-card) {
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
|
Loading…
x
Reference in New Issue
Block a user