IntersectionObserver
css
IntersectionObserver
IntersectionObserver 是一个非常强大且高效的 API,用于检测元素是否进入或离开视口(viewport)。相比于传统的 scroll 事件监听器,它能更高效地处理视口中的元素变化,不会频繁触发,适合用于懒加载图片、触发滚动动画等场景。
使用 IntersectionObserver 实现卡片从小到大的动画效果
!!!
text
1
2<template>
3 <div id="container" class="custom-scrollbar">
4 <card class="card" v-for="i in 100">
5 <div class="text-blurry">
6 白日依山尽,黄河入海流。{{ i }}
7 </div>
8 </card>
9 </div>
10</template>
11<script setup lang="ts">
12 import {onMounted, onUnmounted, ref} from 'vue';
13
14 const observer = ref<IntersectionObserver>();
15
16 function createObserver(cardCssName: string) {
17 // 使用 Intersection Observer 来检测卡片的可见性
18 observer.value = new IntersectionObserver((entries) => {
19 entries.forEach(entry => {
20 if (entry.isIntersecting) {
21 entry.target.classList.add('visible');
22 } else {
23 entry.target.classList.remove('visible');
24 }
25 });
26 }, {
27 threshold: 0.1, // 当 10% 的卡片可见时触发
28 });
29 // 观察所有卡片
30 document.querySelectorAll(cardCssName).forEach(card => {
31 observer.value.observe(card);
32 });
33 }
34
35 onMounted(() => {
36 createObserver('.card');
37 });
38
39 onUnmounted(() => {
40 observer.value.disconnect();
41 observer.value = null;
42 })
43</script>
44<style scope>
45 #container {
46 display: flex;
47 flex-direction: row;
48 flex-wrap: wrap;
49 justify-content: center;
50 align-items: center;
51 background-color: #7d7d7f;
52 }
53
54 .pattern-dots-xl {
55 background-image: radial-gradient(currentColor 1px, transparent 1px);
56 background-size: calc(10 * 1px) calc(10 * 1px);
57 }
58
59 .card {
60 width: 25%;
61 height: 200px;
62 background-color: rgba(255, 255, 255, 0.25);
63 backdrop-filter: blur(6px);
64 -webkit-backdrop-filter: blur(6px);
65 border: 1px solid rgba(255, 255, 255, 0.18);
66 box-shadow: rgba(142, 142, 142, 0.19) 0px 6px 15px 0px;
67 -webkit-box-shadow: rgba(142, 142, 142, 0.19) 0px 6px 15px 0px;
68 border-radius: 12px;
69 -webkit-border-radius: 12px;
70 color: rgba(255, 255, 255, 0.75);
71 margin: 6px;
72 //transform: translateY(100px) scale(0.95);
73 transition: opacity 0.6s ease, transform 0.3s ease;
74 }
75
76 .card.visible {
77 opacity: 1;
78 transform: translateY(0) scale(1);;
79 }
80
81 .text-blurry {
82 text-align: center;
83 color: transparent;
84 animation: blurAnimation 2s forwards; /* 添加动画 */
85 }
86
87 /* 定义模糊动画 */
88 @keyframes blurAnimation {
89 0% {
90 text-shadow: 0 0 0 rgba(0, 0, 0, 0.5); /* 开始时没有模糊 */
91 }
92 100% {
93 text-shadow: 0 0 5px rgba(0, 0, 0, 0.5),
94 0 0 10px rgba(0, 0, 0, 0.4),
95 0 0 15px rgba(0, 0, 0, 0.3); /* 结束时增加模糊效果 */
96 }
97 }
98</style>