在App.vue 中引用即可
- //waves.vue
- <template>
- <div data-tname="WaveItem">
- <div class="main-container">
- <div class="waves">
- <div class="wave" v-for="(item, key) in waves" :key="key" :style="item">
- <div
- v-for="n in wavesConfig.total"
- :key="n"
- class="wave-item"
- :style="{
- transform: `scale(${0.1 * Math.sqrt(n - 1)})`, // 使得波纹大小指数增长
- opacity: 0.3 * (1 / n), // 因为相互层叠的波纹透明度会相互叠加,需要越小的波纹透明度越低,以免中心颜色过重
- animationDelay: `${(n - 1) * 0.12}s`, // 越大的波纹越晚出现,以呈现波纹逐渐扩散的效果
- animationDuration: `${0.6 +
- n * 0.3 +
- parseInt(item.width) * 0.002}s`, // 波纹动画时间渐增,表现波纹向外扩散渐慢的效果,波纹尺寸越大动画时间越长。
- backgroundColor: wavesConfig.waveColor
- }"
- ></div>
- </div>
- </div>
- </div>
- </div>
- </template>
-
- <script>
- export default {
- name: "WaveItem",
- data() {
- return {
- waves: [],
- wavesConfig: {
- maxSize: 300, // px,波纹最大尺寸
- minSize: 100, // px,波纹最小尺寸
- zIndexCount: 999, // 波纹父元素其z-index数值
- waveColor: "#3E8CE3", //波纹基础颜色
- total: 5 //波纹圈层数
- },
- clear: {
- delay: 5000,
- timeoutId: null
- }
- };
- },
- mounted() {
- document.getElementById("app").onclick = e => {
- this.createWave(e);
- this.intervalClearWave();
- };
- },
- methods: {
- createWave(e) {
- // 让新生成的波纹始终在之前波纹的上层产生叠加效果
- if (this.wavesConfig.zIndexCount > 99999) {
- this.wavesConfig.zIndexCount = 999;
- } else {
- this.wavesConfig.zIndexCount++;
- }
- // 在一定范围内随机生成波纹的大小
- const waveSize = parseInt(
- Math.random() * (this.wavesConfig.maxSize - this.wavesConfig.minSize) +
- this.wavesConfig.minSize
- );
- //添加新的波纹数据
- this.waves.push({
- left: `${e.clientX - waveSize / 2}px`,
- top: `${e.clientY - waveSize / 2}px`,
- zIndex: this.wavesConfig.zIndexCount,
- width: `${waveSize}px`,
- height: `${waveSize}px`
- });
- },
- intervalClearWave() {
- clearTimeout(this.clear.timeoutId);
- this.clear.timeoutId = setTimeout(() => {
- this.waves = [];
- }, this.clear.delay);
- }
- }
- };
- </script>
-
- <style lang="scss" scoped>
- .waves {
- .wave {
- position: fixed;
- pointer-events: none; // 点击事件穿透,使得鼠标点击可以穿透波纹,兼容ie11及以上
- @keyframes wave {
- to {
- //波纹逐渐扩散变大变透明
- transform: scale(1);
- opacity: 0;
- }
- }
- .wave-item {
- width: 100%;
- height: 100%;
- position: absolute;
- border-radius: 100%;
- animation: {
- name: wave;
- fill-mode: forwards; // 动画结束后保持最后一帧的状态
- timing-function: ease-out; // 波纹向外扩散渐缓
- }
- }
- }
- }
- </style>
-
-
-