js写了个鼠标进入卡片3D效果的demo

1、效果图

2、上代码 :)

js 复制代码
<template>
  <div class="w-150 h-180 p-12 perspective-1000px transform-style-preserve-3d transform-origin-0">
    <div id="demo" class="w-80 h-120 bg-rose-500 font-bold text-3xl text-center line-height-120 rounded-2xl cursor-grab pos-relative transform-style-preserve-3d shadow-black shadow-2xl">
      demo
    </div>
  </div>
</template>

<script setup>
import { onMounted } from 'vue'
import { ParallaxTiltEffect } from '@/utils/index.js'

onMounted(() => {
  const element = document.querySelector('#demo')
  new ParallaxTiltEffect(element)
})
</script>

<style lang="scss" scoped>
#demo{
  --X: 0;
  --Y: 0;
  transform: rotateX(var(--X)) rotateY(var(--Y));
  transition: all 0.5s ease;
}
</style>

封装了个class

js 复制代码
export class ParallaxTiltEffect{
  constructor(dom) {
    // 最大旋转角度
    this.maxRotateDeg = 20
    // 获取到元素
    this.element = dom
    // 获取宽高的一半
    this.halfW = this.element.clientWidth / 2
    this.halfH = this.element.clientHeight /2 
    this.init()
  }
  init(){
    // 绑定鼠标事件
    console.log('this', this);
    this.element.addEventListener("mouseenter", this.handleMouseEnter.bind(this))
    this.element.addEventListener("mousemove", this.handleMouseMove.bind(this))
    this.element.addEventListener("mouseleave", this.handleMouseLeave.bind(this))

  }
  computed(offsetX, offsetY){
    // 获取鼠标位置距离元素中心点的距离, 然后除以 this.halfW,得到百分比
    let dxPercent = (offsetX - this.halfW) / this.halfW
    let dyPercent = -(offsetY - this.halfH) / this.halfH
    console.log(dxPercent,dyPercent,'11')
    let rotateX = this.maxRotateDeg * dxPercent
    let rotateY = this.maxRotateDeg * dyPercent
    console.log(rotateX,rotateY,'22')
    this.setElementRotate(rotateY,rotateX)
  }
  handleMouseEnter(e){
    let {offsetX, offsetY} = e
    // requestAnimationFrame设置刷新帧率随浏览器画面刷新而刷新
    requestAnimationFrame(() => {
      return this.computed(offsetX, offsetY)
    })
  }
  handleMouseMove(e){
    let {offsetX, offsetY} = e
    requestAnimationFrame(() => {
      return this.computed(offsetX, offsetY)
    })
  }
  handleMouseLeave(e){
    setTimeout(() => {
      this.setElementRotate(0, 0)
    }, 200)
  }
  setElementRotate(rotateX, rotateY){
    // js设置css变量的方式
    this.element.style.setProperty('--X', rotateX + "deg");
    this.element.style.setProperty('--Y', rotateY + "deg");
  }
}
相关推荐
天平5 小时前
油猴脚本创建webworker踩坑记录
前端·javascript·typescript
原则猫6 小时前
前端基础大厦
前端
陈随易8 小时前
编程语言级别的Skill市场,AI Agent 的未来形态
前端·后端·程序员
SoaringHeart9 小时前
Flutter进阶:基于 EasyRefresh 的下拉刷新封装 n_easy_refresh_mixin.dart
前端·flutter
IT_陈寒10 小时前
Vite的热更新突然不香了,排查三小时差点砸键盘
前端·人工智能·后端
子兮曰11 小时前
Agency-Agents 深度解析:400+ AI 专家的"梦之队"如何重塑开发工作流
前端·后端·vibecoding
山河木马11 小时前
渲染管线-计算得到gl_Position(顶点着色器)之后续GPU流程
javascript·webgl·图形学
竹林81812 小时前
用 The Graph 查询链上数据实战:从手搓 RPC 到 Subgraph,我的 NFT 项目数据加载快了 10 倍
前端·javascript
妙码生花12 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(十九):点选验证码代码逐行目检
前端·后端·go
Awu122713 小时前
⚡从零开发 Agent CLI(五)实现一个可治理、可扩展的工具系统
前端·人工智能·claude