-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of https://github.com/rzx007/nav
- Loading branch information
Showing
10 changed files
with
204 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Card3d.tsx | ||
import { defineComponent, onMounted, ref, PropType, CSSProperties } from 'vue' | ||
const style: CSSProperties = { | ||
width: '200px', | ||
borderRadius: '10px', | ||
background: '#fff', | ||
transformStyle: 'preserve-3d', | ||
transition: 'all 0.5s ease', | ||
overflow: 'hidden', | ||
transform: 'perspective(500px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg))', | ||
} | ||
// 验证范围 | ||
const validatorFn = (val: Array<number>) => { | ||
return val.length === 2 && val[0] > -90 && val[1] < 90 | ||
} | ||
export const Card3D = defineComponent({ | ||
name: 'Card3D', | ||
props: { | ||
yRange: { | ||
type: Array as PropType<Array<number>>, | ||
validator: validatorFn, | ||
default: () => [-20, 20], | ||
}, | ||
xRange: { | ||
type: Array as PropType<Array<number>>, | ||
validator: validatorFn, | ||
default: () => [-15, 15], | ||
}, | ||
}, | ||
setup(props, { slots }) { | ||
const cardRef = ref<HTMLDivElement | null>(null) | ||
onMounted(() => { | ||
const card3d = cardRef.value! | ||
const { yRange, xRange } = props | ||
const effectHandle = (e: MouseEvent) => { | ||
const { clientX, clientY } = e | ||
const { left, top, width, height } = card3d.getBoundingClientRect() | ||
// 相对卡片的实际移动距离 | ||
const x = clientX - left | ||
const y = clientY - top | ||
// 计算比例 | ||
const yPercent = y / height | ||
const xPercent = x / width | ||
// 等比运算计算角度 | ||
const yDeg = yRange[0] + (yRange[1] - yRange[0]) * yPercent | ||
const xDeg = xRange[0] + (xRange[1] - xRange[0]) * xPercent | ||
// 设置css变量 | ||
card3d.style.setProperty('--ry', `${xDeg}deg`) | ||
card3d.style.setProperty('--rx', `${-yDeg}deg`) | ||
} | ||
card3d.addEventListener('mousemove', effectHandle) | ||
card3d.addEventListener('mouseleave', () => { | ||
card3d.style.setProperty('--ry', `0deg`) | ||
card3d.style.setProperty('--rx', `0deg`) | ||
}) | ||
}) | ||
return () => ( | ||
<div style={style} ref={cardRef}> | ||
{slots.default && slots.default()} | ||
</div> | ||
) | ||
}, | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
<!-- 3DHover.vue --> | ||
<template> | ||
<div class="card-wrap"> | ||
<div class="card-3d"> | ||
<img src="https://fun.youth.cn/gnzx/202011/W020201119307688300465.jpg" alt="" /> | ||
</div> | ||
</div> | ||
</template> | ||
<script setup lang="tsx"> | ||
import { onMounted } from 'vue' | ||
onMounted(() => { | ||
const card3d = document.querySelector('.card-3d') as HTMLDivElement | ||
const yRange = [-20, 20] | ||
const xRange = [-15, 15] | ||
|
||
const effectHandle = (e) => { | ||
const { clientX, clientY } = e | ||
const { left, top, width, height } = card3d.getBoundingClientRect() | ||
// 相对卡片的实际移动距离 | ||
const x = clientX - left | ||
const y = clientY - top | ||
// 计算比例 | ||
const yPercent = y / height | ||
const xPercent = x / width | ||
// 等比运算计算角度 | ||
const yDeg = yRange[0] + (yRange[1] - yRange[0]) * yPercent | ||
const xDeg = xRange[0] + (xRange[1] - xRange[0]) * xPercent | ||
// 设置css变量 | ||
card3d.style.setProperty('--ry', `${xDeg}deg`) | ||
card3d.style.setProperty('--rx', `${-yDeg}deg`) | ||
card3d.style.setProperty('--per', `${xDeg}%`) | ||
} | ||
card3d.addEventListener('mousemove', effectHandle) | ||
card3d.addEventListener('mouseleave', () => { | ||
card3d.style.setProperty('--ry', `0deg`) | ||
card3d.style.setProperty('--rx', `0deg`) | ||
}) | ||
}) | ||
</script> | ||
<style lang="scss"> | ||
.card-wrap { | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
position: relative; | ||
overflow: hidden; | ||
background-color: transparent; | ||
padding: 12px 0; | ||
&:before { | ||
content: ''; | ||
position: absolute; | ||
top: 0; | ||
left: 0; | ||
right: 0; | ||
bottom: 0; | ||
z-index: -1; | ||
background: url('https://fun.youth.cn/gnzx/202011/W020201119307688300465.jpg'); | ||
background-size: cover; | ||
filter: blur(50px); | ||
transform: scale(2); | ||
} | ||
.card-3d { | ||
position: relative; | ||
width: 200px; | ||
border-radius: 10px; | ||
background: #fff; | ||
// 核心样式 | ||
transform-style: preserve-3d; | ||
transition: all 0.5s ease; | ||
transform: perspective(500px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); | ||
&:hover { | ||
box-shadow: -3px 3px 10px rgba(0, 0, 0, 0.5); | ||
} | ||
&:hover::before { | ||
display: block; | ||
} | ||
// 添加反光效果 | ||
&::before { | ||
content: ''; | ||
display: none; | ||
position: absolute; | ||
border-radius: inherit; | ||
inset: 0; | ||
background: linear-gradient( | ||
115deg, | ||
transparent 0%, | ||
rgba(255, 255, 255, 0.5) var(--per, 30%), | ||
rgba(0, 0, 0, 0.5) calc(var(--per, 55%) + 25%), | ||
rgba(255, 255, 255, 0.5) calc(var(--per, 80%) + 50%), | ||
transparent 100% | ||
); | ||
mix-blend-mode: color-dodge; | ||
} | ||
|
||
img { | ||
border-radius: inherit; | ||
width: 100%; | ||
} | ||
} | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# 3D卡片悬浮效果 | ||
|
||
<<< @/code/demo/3DHover.vue{vue} | ||
|
||
|
||
### 封装成组件 | ||
::: details 点击查看代码 | ||
<<< @/code/demo/3DCard.tsx{tsx} | ||
::: | ||
|
||
|
||
### 效果 | ||
|
||
<script setup> | ||
import threedHover from '../code/demo/3DHover.vue' | ||
</script> | ||
|
||
<threedHover /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
::: | ||
|
||
<<< @/code/demo/vSlideIn.vue{vue} | ||
|
||
### 示例 | ||
|
||
<script setup> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters