mirror of
				https://github.com/pure-admin/vue-pure-admin.git
				synced 2025-11-03 13:44:47 +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