【vue.js】手把手教你做一个会躲避鼠标指针的登录按钮

10 篇文章 1 订阅

效果

在这里插入图片描述

背景

在登录的时候,我们都会做账号密码不可为空的验证,如何做出一个会躲避鼠标指针的登录按钮呢。废话不多说,3、2、1,上代码~

代码

<!DOCTYPE html>
<html lang="en" style="overflow: hidden;">
<head>
  <title>登录测试</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  <link rel="shortcut icon" href="../favicon.ico">
  <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/element-plus/2.3.3/index.css" rel="stylesheet">
  <script src="https://unpkg.com/vue@3"></script>
  <script src="https://cdn.bootcdn.net/ajax/libs/element-plus/2.3.3/index.full.js"></script>
  <style>
    body {
      background-color: rgb(132, 141, 156);
      user-select: none;
    }
    #form {
      width: 300px;
      perspective: 400px;
      position: absolute;
      top: 300px;
      left: 50%;
      margin-left: -150px;
      padding: 20px;
      box-shadow: var(--el-box-shadow-light);
      border-radius: 5px;
      border: 1px solid var(--el-card-border-color);
      background-color: rgb(230, 240, 250);
    }
    .remember-me-wrapper {
      float: right;
      margin-bottom: 18px;
    }
    .remember-me-wrapper .el-checkbox {
      z-index: 0;
    }
    #button {
      width: 100%;
      transition: all 0.1s ease;
      transform: translate(0px, 0px) rotateX(0deg) rotateY(0deg);
      box-shadow: 0px 0px 0px rgba(0, 0, 0, 0.15)
    }
  </style>
</head>
<body>
  <div id="app">
    <el-form id="form" :model="loginForm" :rules="loginRules" label-width="60">
      <el-form-item label="账号" prop="username">
        <el-input v-model="loginForm.username" clearable />
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input v-model="loginForm.password" clearable type="password" />
      </el-form-item>
      <div class="remember-me-wrapper">
        <el-checkbox v-model="loginForm.rememberMe" label="记住我" class="rememberMe" />
      </div>
      <el-button id="button" type="primary" @click="login()">登录</el-button>
    </el-form>
  </div>
  <script type="text/javascript">
    const { createApp, reactive, ref } = Vue
    const app = createApp({
      setup() {
        const loginForm = reactive({
          username: '',
          password: '',
          rememberMe: false
        })
        const loginRules = reactive({
          username: [
            { required: true, message: '不可为空', trigger: 'blur' }
          ],
          password: [
            { required: true, message: '不可为空', trigger: 'blur' }
          ]
        })
        const distanceBetween = (p1x, p1y, p2x, p2y) => {
          const dx = p1x - p2x
          const dy = p1y - p2y
          return Math.sqrt(dx * dx + dy * dy)
        }
        document.addEventListener('mousemove', (event) => {
          const button = document.getElementById('button')
          const form = document.getElementById('form')
          if (loginForm.username && loginForm.password) {
            button.style.transform = `translate(0px, 0px) rotateX(0deg) rotateY(0deg)`
            button.style.boxShadow = `0px 0px 0px rgba(0, 0, 0, 0.15)`
            button.style.pointerEvents = 'auto'
            return
          }
          const bx = form.offsetLeft + button.offsetLeft + button.offsetWidth / 2
          const by = form.offsetTop + button.offsetTop + button.offsetHeight / 2
          const dist = distanceBetween(event.clientX, event.clientY, bx, by) * 2
          const angle = Math.atan2(event.clientY - by, event.clientX - bx)
          // 椭圆半径公式
          const radius = Math.sqrt(Math.pow(button.offsetWidth + 20, 2) * Math.pow(Math.cos(angle), 2) + Math.pow(button.offsetHeight + 20, 2) * Math.pow(Math.sin(angle), 2))
          const ox = -1 * Math.cos(angle) * (Math.max((radius - dist) / 2, 0))
          const oy = -1 * Math.sin(angle) * (Math.max((radius - dist) / 2, 0))
          const rx = oy / 2
          const ry = -ox / 2
          button.style.transform = `translate(${ox}px, ${oy}px) rotateX(${rx}deg) rotateY(${ry}deg)`
          button.style.boxShadow = `0px ${Math.abs(oy)}px ${Math.abs(oy) / radius * 40}px rgba(0, 0, 0, 0.15)`
          button.style.pointerEvents = 'none'
        })
        const login = () => {
          if (loginForm.username && loginForm.password) {
            ElementPlus.ElMessage({
              message: '登录成功',
              type: 'success',
            })
          }
        }
        return {
          loginForm,
          loginRules,
          login
        }
      }
    })
    app.use(ElementPlus).mount("#app")
  </script>
</body>
</html>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

饺子大魔王12138

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值