数据可视化大屏组件记录

2,243 阅读2分钟

数字翻牌器

element plus已经封装好了 element-plus.org/zh-CN/compo…

image.png

效果:

大佬封装的vue3版本,还没试过

转载的源地址

<template>
  <div v-if="to" :id="nodeId" class="count-to">
    <span class="num count-color"></span>
    <span class="num count-color">
      <slot name="unit"></slot>
    </span>
  </div>

  <!-- fix flip插件数字为0的时候不显示 -->
  <span v-else-if="to == 0 || !to" class="num_0 count-color">{{ 0 }}</span>
</template>

<script setup name='count-to'>
import uniqueId from 'lodash/uniqueId'
import { nextTick, onMounted, onUnmounted, onUpdated, ref, watch } from 'vue'
import { Flip } from 'number-flip'

const props = defineProps({
  // 翻动起始数值
  from: {
    type: [String, Number],
    default: 0
  },
  // 最终展示数值
  to: [String, Number],
  // 数字翻动时间
  duration: {
    type: Number,
    default: 2
  },
  color: {
    type: String,
    default: '#fff'
  },
  nodeId: {
    type: String,
    default: () => {
      // 生成随机不重复id
      return uniqueId(['countCard_'])
    }
  },
  // flip插件的其他参数
  params: {
    type: Object,
    default: () => ({})
  }
})
let flip = null
const initFlip = () => {
  const numNode = document.querySelector(`#${props.nodeId} .num`)
  if (numNode && props.to) {
    numNode.innerHTML = ''
    flip = new Flip({
      ...props.params,
      node: numNode,
      from: props.from,
      to: props.to,
      duration: props.duration
    })
  }
}
onMounted(() => {
  initFlip()
})
onUpdated(() => {
  initFlip()
})

onUnmounted(() => {
  flip = null
})
</script>

<style lang="less" scoped>
.count-to {
  overflow: hidden;
  height: 24px;
  text-align: center;
  width: 100%;
}

.num,
.num_0 {
  font-size: 20px;
  text-align: center;
}

.count-color {
  color: v-bind(color);
}
</style>

屏幕自适应包autofit.js

异形屏幕不支持自适应,也可能是我不会用吧。。。 autofit.js 问答和食用指南

下载

npm i autofit.js

引入

import autofit from 'autofit.js'

快速开始

autofit.init()

onMounted使用

autofit.init({
        dh: 1080,
        dw: 1920,
        el:"body",
        resize: true
    })

onBeforeUnmount停用

autofit.off()

3D旋转菜单

效果: 3D旋转菜单.gif

感觉还挺好的,不过没试过,代码如下:

转载的源地址

<template>
<div class="menu">
  <div
    v-for="(item, index) in MENU_LIST"
    :key="index"
    class="menu-item"
    @click="linkTo(xxx)"
  >
    <img :src="item.icon" alt="" class="menu-icon" />
  </div>
</div>
</template>
<script setup>
const MENU_LIST = [
  {
    icon: '/imgs/icon1.png',
    name: '菜单1',
  },
  {
    icon: '/imgs/icon2.png',
    name: '菜单2',
  },
  {
    icon: '/imgs/icon3.png',
    name: '菜单3',
]
</script>  
<style lang="less">
.menu {
  position: relative;
  width: 80%;
  height: 100%;
  left: 50%;
  transform: translateX(-50%);
  .menu-item {
      width: 376px;
      height: 436px;
      display: flex;
      flex-direction: column;
      align-items: center;
      padding: 33px 0;
      position: absolute;
      cursor: pointer;
      //3个卡片,x和y轴动画加起来是20s , 20s/3 约等于 6.667s
      //每个球y轴动画延迟 从0递减2.857s,x轴与y相差动画时长的一半(10s/2)
      &:nth-child(1) {
        animation: animateX 10s cubic-bezier(0.36, 0, 0.64, 1) -5s infinite alternate,
          animateY 10s cubic-bezier(0.36, 0, 0.64, 1) 0s infinite alternate,
          scaleAnimate 20s cubic-bezier(0.36, 0, 0.64, 1) 0s infinite alternate;
      }
      &:nth-child(2) {
        animation: animateX 10s cubic-bezier(0.36, 0, 0.64, 1) -11.667s infinite alternate,
          animateY 10s cubic-bezier(0.36, 0, 0.64, 1) -6.667s infinite alternate,
          scaleAnimate 20s cubic-bezier(0.36, 0, 0.64, 1) -6.667s infinite alternate;
      }

      &:nth-child(3) {
        animation: animateX 10s cubic-bezier(0.36, 0, 0.64, 1) -18.334s infinite alternate,
          animateY 10s cubic-bezier(0.36, 0, 0.64, 1) -13.334s infinite alternate,
          scaleAnimate 20s cubic-bezier(0.36, 0, 0.64, 1) -13.334s infinite alternate;
      }
    }
}
@keyframes animateX {
  0% {
    left: -50px;
  }
  100% {
    left: 75%;
  }
}

@keyframes animateY {
  0% {
    top: -100px;
  }
  100% {
    top: 400px;
  }
}

@keyframes scaleAnimate {
  0% {
    transform: scale(0.6);
  }
  50% {
    transform: scale(1);
  }
  100% {
    transform: scale(0.6);
  }
}
</style>