vue3 数据可视化大屏实现自上而下展开的动画效果

数据大屏项目开发过程中,会增加一些动画效果,让大屏页面看起来更加酷炫.今天我们来实现一个自上而下展开的动画效果.

效果截图

数据可视化大屏实现自上而下展开的动画效果

动态效果

实现思路

在上面的动画效果中,我们要实现的是自上而下的展开动画,动画执行完成后,再显示内容。

首先隐藏我们要显示的内容,然后再做一个div,给这个div一个背景渐变色,然后动态设置这个高度,让其从1变到100,达到100以后,我们再隐藏我们的背景色,把应该要显示的内容显示出来。

html部分

html分为两部分,一个背景部分 一个主题

<div class="pageItemBody">
    <div class="bg" ref="bg" v-if="!show"></div>
    <div class="title" v-if="show">
      <span>{{ title }}</span>
    </div>
    <div class="itemMain" v-if="show">
      <slot></slot>
    </div>
</div>

js

使用gsap来动态调整div的高度,动画执行完成后,我们显示div的高度。因为数据可视化大屏 中可能会复用多个组件,并且每个组件动画开始时间和持续时间都不同,我们可以把延迟时间以及持续时间的参数抽离出来。

gsap.to(this.$refs.bg, {
  height: '100%',
  delay: that.delay,
  duration: that.duration, // 动画持续时间(以秒为单位)
  ease: 'none', // 使用线性动画缓动函数
  onComplete: () => {
    // 动画完成后触发的回调函数
    console.log('动画执行完成');
    setTimeout(() => {
      that.show = true
    }, 100)
  },
});

css

.pageItemBody {
  width: 100%;
  position: relative;
  height: 100%;
  display: flex;
  justify-content: flex-start;
  align-items: flex-start;
  flex-wrap: nowrap;
  flex-direction: column;
  z-index: 1;
  align-content: flex-start;

  .title {
    height: 55px;
    width: 100%;
    background-image: url('./assets/titleLeft.png'),
    url('./assets/titleCenter.png'),
    url('./assets/titleRight.png');
    background-repeat: no-repeat, no-repeat, no-repeat;
    background-position: top left, 16PX top, top right;
    background-size: 16PX 100%, calc(100% - 16PX - 13PX) 100%, 13PX 100%;
    display: flex;
    justify-content: flex-start;
    align-items: center;
    flex-wrap: nowrap;
    flex-direction: row;
    align-content: flex-start;

    span {
      font-size: 18px;
      font-family: SourceHanSansCN;
      font-weight: 400;
      color: #FFFFFF;
      text-shadow: 0px 2px 1px rgba(0, 14, 17, 0.19);
      margin-left: 25px;
      margin-bottom: 10px;
    }
  }

  .itemMain {
    position: relative;
    width: 100%;
    height: calc(100% - 55px);
    background-image: url('./assets/leftTop.png'),
    url('./assets/top.png'),
    url('./assets/rightTop.png'),
    url('./assets/leftCenter.png'),
    url('./assets/center.png'),
    url('./assets/rightCenter.png'),
    url('./assets/leftBottom.png'),
    url('./assets/bottom.png'),
    url('./assets/rightBottom.png');
    background-repeat: no-repeat,
    no-repeat,
    no-repeat,
    no-repeat,
    no-repeat,
    no-repeat,
    no-repeat,
    no-repeat,
    no-repeat,
    no-repeat,
    no-repeat;
    background-position: top left,
    15PX top,
    top right,
    left 15PX,
    5PX 15PX,
    right 15PX,
    bottom left,
    15PX bottom,
    bottom right;
    background-size: 15PX 15PX,
    calc(100% - 15PX - 15PX) 15PX,
    15PX 15PX,
    5PX calc(100% - 15PX - 33PX),
    calc(100% - 5PX - 5PX) calc(100% - 15PX - 33PX),
    5PX calc(100% - 15PX - 33PX),
    15PX 33PX,
    calc(100% - 15PX - 35PX) 33PX,
    35PX 33PX;
  }

  .bg {
    height: 0;
    position: relative;
    width: 100%;
    background: linear-gradient(to bottom, rgba(22, 85, 109, 0.3), rgba(22, 85, 109, 1));
  }
}

到这里一个自上而下展开动画效果就实现了。

完整实例代码

<template>
  <div class="pageItemBody">
    <div class="title" v-if="show">
      <span>{{ title }}</span>
    </div>
    <div class="itemMain" v-if="show">
      <slot></slot>
    </div>
    <bg v-if="show"></bg>
    <div class="bg" ref="bg"></div>
  </div>
</template>

<script>
import gsap from 'gsap'
import bg from './bg.vue'

export default {
  name: "title",
  data() {
    return {
      show: false
    }
  },
  components: {
    bg,
  },
  props: {
    title: {
      type: String,
      default() {
        return '测试的';
      }
    },
    delay: {
      type: Number,
      default() {
        return 0;
      }
    },
    duration: {
      type: Number,
      default() {
        return 0.5;
      }
    },
  },
  mounted() {
    var that = this;
    gsap.to(this.$refs.bg, {
      height: '100%',
      delay: that.delay,
      duration: that.duration, // 动画持续时间(以秒为单位)
      ease: 'none', // 使用线性动画缓动函数
      onComplete: () => {
        // 动画完成后触发的回调函数
        console.log('动画执行完成');
        setTimeout(() => {
          that.show = true
        }, 100)
      },
    });
  },
}
</script>

<style lang="scss" scoped>
.pageItemBody {
  width: 100%;
  position: relative;
  height: 100%;
  display: flex;
  justify-content: flex-start;
  align-items: flex-start;
  flex-wrap: nowrap;
  flex-direction: column;
  z-index: 1;
  align-content: flex-start;

  .title {
    height: 32PX;
    min-width: 148px;
    margin: 0 auto;
    padding: 0 20px;
    background-image: url('./assets/titleLeft.png'),
    url('./assets/titleCenter.png'),
    url('./assets/titleRight.png');
    background-repeat: no-repeat, no-repeat, no-repeat;
    background-position: top left, 47PX top, top right;
    background-size: 47PX 100%, calc(100% - 47PX - 47PX) 100%, 47PX 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: nowrap;
    flex-direction: row;
    align-content: flex-start;

    span {
      font-size: 18px;
      font-family: YouSheBiaoTiHei;
      font-weight: 400;
      color: #DEF1FF;
      padding-top: 5px;
    }
  }
}

.bg {
  height: 50%;
  position: relative;
  width: 100%;
  background: linear-gradient(to bottom, rgba(22, 85, 109, 0.3), rgba(22, 85, 109, 1));
}

.itemMain {
  position: relative;
  width: 100%;
  height: calc(100% - 50px);
}
</style>


更多动画效果

gsap 动画效果汇总

喜欢