Skip to content

3D 卡片

字数: 0 字 时长: 0 分钟

鼠标坐标(0, 0)

思路

鼠标位置=> 翻转角度 => transform属性

vue
<script setup>
import { ref } from 'vue'

const cardRef = ref(null)
const offsetX = ref(0)  // 添加鼠标X坐标的响应式变量
const offsetY = ref(0)  // 添加鼠标Y坐标的响应式变量

const yRange = [-12, 12]
const xRange = [-12, 12]

const getRotate = (range, value, max) => {
    return (value/max) * (range[1] - range[0]) + range[0]
}

const handleMouseMove = (e) => {
  // 更新鼠标坐标
  offsetX.value = e.offsetX
  offsetY.value = e.offsetY
  
  const {offsetWidth, offsetHeight} = cardRef.value
  const ry = getRotate(yRange, offsetX.value, offsetWidth)
  const rx = getRotate(xRange, offsetY.value, offsetHeight)
  
  // 使用setProperty设置CSS变量
  cardRef.value.style.setProperty('--rotate-x', `${rx}deg`)
  cardRef.value.style.setProperty('--rotate-y', `${ry}deg`)
}
</script>

<div :class="$style.div" ref="cardRef" @mousemove="handleMouseMove">
  <div>鼠标坐标({{offsetX}}, {{offsetY}})</div>
</div>

<style module>
.div {
  width: 300px;
  height: 400px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  font-weight: bold;
  border-radius: 5px;
  
  /* 3D变换相关样式 */
  transform-style: preserve-3d;
  transform: perspective(1000px) rotateX(var(--rotate-x, 0deg)) rotateY(var(--rotate-y, 0deg));
  transition: transform 0.2s ease-out;
  
  /* 布局样式 */
  display: flex;
  flex-direction: column;  /* 改为垂直排列 */
  align-items: center;
  justify-content: center;
  font-size: 24px;
  
  /* 添加阴影增强3D效果 */
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
}
</style>