美文网首页
水波纹效果,多功能-vue组件

水波纹效果,多功能-vue组件

作者: littlesunn | 来源:发表于2022-02-03 04:38 被阅读0次
    1643746641656202222437161.gif
    <template>
      <div class="water-ripples-container" ref="water-ripples-container" @[trigger]="onActive">
        <div ref="ripples" :class="{'out-ripples': isOut, 'inset-ripples': type == 'inset', 
        'animate-always--out': isActive && trigger == 'always' && type == 'out',
        'animate-once--out': isActive && (trigger == 'mouseenter' || trigger == 'click') && type == 'out',
        'animate-always--inset': isActive && trigger == 'always' && type == 'inset',
        'animate-once--inset': isActive && (trigger == 'mouseenter' || trigger == 'click') && type == 'inset',
        }" :style="{
            borderRadius:  isOut ? borderRadius : '50%',
            '--ripple-color': color,
            '--spread-width': spreadWidth,
            '--spread-size': mySpreadSize,
        }"></div>
        <slot />
      </div>
    </template>
    
    <script>
    export default {
      props: {
        type: {
          type: String,
          default: "out"  // out/inset
        },
        color: {
          type: String,
          default: "#337ab7"
        },
        borderRadius: {
          type: String,
          default: "0"
        },
        spreadWidth: {
          type: String,
          default: "8px"
        },
        trigger: {
          type: String,
          default: "always"  // always/mouseenter/click/focus
        },
        spreadSize: {
          type: String,
          default: null
        }
      },
      data() {
        return {
          isActive: false,
          mySpreadSize: '0px'
        }
      },
      computed: {
        isOut() {
          return this.type == "out"
        }
      },
      mounted() {
        this.initWidth();
    
      },
      watch: {
        trigger: {
          handler(val) {
            this.isActive = (val == "always")
          },
          immediate: true
        }
      },
      methods: {
        onActive() {
          this.isActive = true
        },
        initWidth() {
          let container = this.$refs['water-ripples-container']
          let ripples = this.$refs['ripples']
          if (this.type == "out") {
            this.$refs['ripples'].style.width = container.clientWidth + "px";
          } else {
            container.style.overflow = "hidden";
            if (!this.spreadSize) {
              this.mySpreadSize = container.clientWidth * 1.1 + "px"
            }else {
              this.mySpreadSize = this.spreadSize
            }
            console.log(this.spreadSize, "this.spreadSize");
          }
          ripples.addEventListener('animationend', () => {
            this.isActive = false
          }, false);
        }
      }
    }
    </script>
    
    <style scoped lang="scss">
    .water-ripples-container {
      position: relative;
      display: inline-block;
      .slot-container {
        position: relative;
        z-index: 2;
      }
      .out-ripples {
        position: absolute;
        left: 0;
        top: 0;
        height: 100%;
        opacity: 1;
        z-index: 1;
        pointer-events: none;
      }
      .animate-once--out {
        animation: ripple-effect 1s forwards;
      }
      .animate-always--out {
        animation: ripple-effect 1s infinite;
      }
      @keyframes ripple-effect {
        0% {
          box-shadow: 0 0 0 0px var(--ripple-color);
          opacity: 1;
        }
        100% {
          box-shadow: 0 0 0 var(--spread-width) var(--ripple-color);
          opacity: 0;
        }
      }
    
      .inset-ripples {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        opacity: 1;
        width: 0px;
        height: 0px;
        background: red;
        pointer-events: none;
      }
      @keyframes size-effect {
        0% {
          width: 0px;
          height: 0px;
          opacity: 0.8;
        }
        100% {
          width: var(--spread-size);
          height: var(--spread-size);
          opacity: 0;
        }
      }
      .animate-once--inset {
        animation: size-effect 1s forwards;
      }
      .animate-always--inset {
        animation: size-effect 1s infinite;
      }
    }
    </style>
    

    相关文章

      网友评论

          本文标题:水波纹效果,多功能-vue组件

          本文链接:https://www.haomeiwen.com/subject/rhwlkrtx.html