motion-knowledge and ContactFloatingButton optimize
This commit is contained in:
parent
58b3e14e8e
commit
a27e168865
|
|
@ -1,97 +1,22 @@
|
||||||
<!-- components/ContactFloatingButton.vue -->
|
<!-- components/ContactFloatingButton.vue -->
|
||||||
<template>
|
<template>
|
||||||
<div class="fixed right-6 top-1/2 transform -translate-y-1/2 z-50 flex items-center">
|
<div class="fixed right-6 top-1/2 transform -translate-y-1/2 z-50 flex items-center">
|
||||||
<!-- 二维码面板 -->
|
<UPopover mode="hover">
|
||||||
<Transition name="fade-slide">
|
<UButton
|
||||||
<div v-if="showQR" class="w-64 overflow-hidden transition-all duration-300 ease-out;">
|
|
||||||
<img
|
|
||||||
:alt="qrAltText"
|
|
||||||
:src="qrImage"
|
|
||||||
class="w-full h-auto border-4 border-white rounded-lg shadow-xl"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
|
|
||||||
<!-- 客服按钮 -->
|
class="bg-green-500 hover:bg-green-600 text-white px-4 py-3 rounded-l-lg shadow-lg transition-all duration-300"
|
||||||
<button
|
color="neutral" label="联系客服"
|
||||||
:class="{ 'ml-2': showQR }"
|
variant="subtle"/>
|
||||||
class="bg-green-500 hover:bg-green-600 text-white px-4 py-3 rounded-l-lg shadow-lg transition-all duration-300"
|
<template #content>
|
||||||
@click="onButtonClick"
|
<div class="w-64 overflow-hidden transition-all duration-300 ease-out;">
|
||||||
@mouseenter="showQR = true"
|
<img
|
||||||
@mouseleave="onMouseLeave"
|
alt="QRCode"
|
||||||
>
|
class="w-full h-auto border-4 border-white rounded-lg shadow-xl"
|
||||||
<span class="button-text">{{ buttonText }}</span>
|
src="/img/QRCode.png"
|
||||||
</button>
|
>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</UPopover>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import {ref} from 'vue'
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
qrImage: {
|
|
||||||
type: String,
|
|
||||||
default: '/img/img.png'
|
|
||||||
},
|
|
||||||
qrAltText: {
|
|
||||||
type: String,
|
|
||||||
default: '客服二维码'
|
|
||||||
},
|
|
||||||
buttonText: {
|
|
||||||
type: String,
|
|
||||||
default: '联系客服'
|
|
||||||
},
|
|
||||||
hoverDelay: {
|
|
||||||
type: Number,
|
|
||||||
default: 300 // 延迟隐藏时间(ms)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const emit = defineEmits(['click'])
|
|
||||||
|
|
||||||
const showQR = ref(false)
|
|
||||||
let hideTimer = null
|
|
||||||
|
|
||||||
const onMouseLeave = () => {
|
|
||||||
hideTimer = setTimeout(() => {
|
|
||||||
showQR.value = false
|
|
||||||
}, props.hoverDelay)
|
|
||||||
}
|
|
||||||
|
|
||||||
const cancelHide = () => {
|
|
||||||
if (hideTimer) {
|
|
||||||
clearTimeout(hideTimer)
|
|
||||||
hideTimer = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const onButtonClick = () => {
|
|
||||||
emit('click')
|
|
||||||
// 点击后保持二维码显示
|
|
||||||
cancelHide()
|
|
||||||
showQR.value = true
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
/* 按钮样式 */
|
|
||||||
|
|
||||||
|
|
||||||
.writing-mode-vertical {
|
|
||||||
writing-mode: vertical-rl;
|
|
||||||
text-orientation: mixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* 动画效果 */
|
|
||||||
.fade-slide-enter-active,
|
|
||||||
.fade-slide-leave-active {
|
|
||||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.fade-slide-enter-from,
|
|
||||||
.fade-slide-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateX(10px);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -93,22 +93,13 @@ const cardItems = ref([
|
||||||
class="shadow-lg hover:shadow-2xl transition-shadow duration-300 h-full"
|
class="shadow-lg hover:shadow-2xl transition-shadow duration-300 h-full"
|
||||||
reverse
|
reverse
|
||||||
>
|
>
|
||||||
<Motion
|
|
||||||
:initial="{ scale: 0.9, opacity: 0.7 }"
|
<img
|
||||||
:transition="{ duration: 0.4, delay: 0.2 + 0.1 * index }"
|
:src="item.image"
|
||||||
:while-hover="{
|
alt="Illustration"
|
||||||
scale: 1.1,
|
class="w-full shadow-2xl rounded-2xl"
|
||||||
rotate: 2,
|
|
||||||
transition: { duration: 0.3 }
|
|
||||||
}"
|
|
||||||
:while-in-view="{ scale: 1, opacity: 1 }"
|
|
||||||
>
|
>
|
||||||
<img
|
|
||||||
:src="item.image"
|
|
||||||
alt="Illustration"
|
|
||||||
class="w-full shadow-2xl rounded-2xl"
|
|
||||||
>
|
|
||||||
</Motion>
|
|
||||||
</UPageCTA>
|
</UPageCTA>
|
||||||
</Motion>
|
</Motion>
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -120,7 +111,7 @@ const cardItems = ref([
|
||||||
:transition="{
|
:transition="{
|
||||||
duration: 0.8,
|
duration: 0.8,
|
||||||
delay: 0.3,
|
delay: 0.3,
|
||||||
type: 'spring',
|
|
||||||
stiffness: 100,
|
stiffness: 100,
|
||||||
damping: 15
|
damping: 15
|
||||||
}"
|
}"
|
||||||
|
|
|
||||||
BIN
public/img/QRCode.png
Normal file
BIN
public/img/QRCode.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 59 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.5 MiB |
Loading…
Reference in New Issue
Block a user