VUE+TailwindCSS 卡片效果-卡片随鼠标3D旋转效果

先上效果图

代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<pre class="wp-block-code"><code>&lt;script setup>
import { ref } from 'vue'

const props = defineProps({
    title: String,      //标题
    siteUrl: String,    //点击跳转Url
    imageUrl: String,   //背景图片Url
})

const x = ref(0)        //卡片X轴旋转角度
const y = ref(0)        //卡片Y轴旋转角度
const z = ref(1)        //卡片放大倍数
const light = ref(0)    //高光角度

/**
 * 卡片随鼠标3D效果
 * @param e 
 */
function onMousemove(e) {
    // 获取dom元素
    let box = e.target.getBoundingClientRect();
    // 获取鼠标位置并计算卡片旋转角度
    y.value = (e.clientX - box.x - (box.width / 2)) / 10 * -1;
    x.value = (e.clientY - box.y - (box.height / 2)) / 10;
    //卡片放大
    z.value = 1.1;
    //计算高光
    light.value = (box.height * box.y) / 60;
}

/**
 * 鼠标离开时复原
 * @param e 
 */
function onMouseleave(e) {
    // 鼠标离开时还原
    x.value = y.value = 0;
    z.value = 1;
    light.value = 0;
}
&lt;/script>

&lt;template>
    &lt;!-- 卡片层 -->
    &lt;a class="card h-40 w-40 m-10 shadow-lg shadow-gray-500 rounded-2xl" @mousemove="onMousemove" @mouseleave="onMouseleave"
        :href="siteUrl" target="_blank" :style="{ transform: `rotateX(${x}deg) rotateY(${y}deg) scale(${z})` }">

        &lt;!-- 渐变层 -->
        &lt;div class="card-shine z-10 absolute top-0 bottom-0 left-0 right-0 rounded-2xl border-2 border-solid border-slate-400"
            :style="{ background: `linear-gradient(${light}deg,rgba(0,0,0,0.3),rgba(241,241,241,0.3))` }">&lt;/div>

        &lt;!-- 阴影层 -->
        &lt;div class="card-shadow absolute shadow-2xl shadow-slate-50 opacity-25">&lt;/div>

        &lt;!-- 图片层 -->
        &lt;div class="card-layer -z-10 relative w-full h-full rounded-2xl bg-cover"
            :style="{ backgroundImage: `url(${imageUrl})` }">&lt;/div>

        &lt;!-- 标题 -->
        &lt;div class="card-title z-20 absolute bottom-0.5 left-0.5 right-0.5 backdrop-blur-lg rounded-b-2xl">
            &lt;span class="text-pearly text-lg font-mono">{{ title }}&lt;/span>
        &lt;/div>

    &lt;/a>
&lt;/template>

&lt;style scoped>
.card {
    transform-style: preserve-3d;
    perspective: 200px;
    transition: 50ms all ease;
}

.card-shadow {
    top: 5%;
    left: 5%;
    width: 90%;
    height: 90%;
}

.card-title {
    height: 20%;
    /* Make Text Center */
    display: flex;
    align-items: center;
    justify-content: center;
}
&lt;/style></code></pre>

使用方法:

直接使用:<Card title="标题" siteUrl="跳转URL" imageUrl="图片URL"/>
列表渲染:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<pre class="wp-block-code"><code>&lt;script setup>
import Card from "./Card.vue";

// load objects from somewhere
const sites = &#91;
    {
        'id': '1',
        'title': 'Title',
        'siteUrl': 'https://tmp.whitepeach.top',
        'imageUrl': 'https://t.alcy.cc/tx',
    },
    {
        'id': '2',
        'title': 'TEST',
        'siteUrl': 'https://tmp.whitepeach.top',
        'imageUrl': 'https://t.alcy.cc/tx',
    },
]
&lt;/script>

&lt;template>
    &lt;div class="flex flex-wrap justify-evenly items-center content-evenly">
        &lt;!-- 列表渲染 -->
        &lt;Card v-for="(site, index) in sites" :key="site.id" :title="site.title" :siteUrl="site.siteUrl"
            :imageUrl="site.imageUrl" />

    &lt;/div>
&lt;/template>

&lt;style>&lt;/style></code></pre>

然后就大功告成啦

遇到问题欢迎在评论区留言

Licensed under CC BY-NC-SA 4.0
最后更新于 Jan 11, 2025 09:47 UTC