vue开发H5 实现滑动图片获取验证码

news2025/5/25 22:50:54

在这里插入图片描述

<template>
  <div>
    <van-button type="primary" @click="sendVerification">获取验证码</van-button>
    <van-popup
      v-model="captchaVisible"
      closeable
      position="bottom"
      class="login-captcha"
      :close-on-click-overlay="false"
      safe-area-inset-bottom
    >
      <div class="login-captcha-title">拖动下方滑块完成验证</div>
      <div class="login-captcha-main">
        <img alt="网络错误" ref="shade" class="login-captcha-shade" />
        <img alt="网络错误" ref="puzzle" class="login-captcha-puzzle" />
        <div class="login-captcha-refresh" @click="getCaptchaPuzzle"></div>
      </div>
      <van-slider
        class="login-captcha-slider"
        active-color="transparent"
        v-model="slider"
        @change="getVerification"
      >
        <template #button>
          <div class="login-captcha-slider__button"></div>
        </template>
      </van-slider>
    </van-popup>
  </div>
</template>

<script>
import { getCaptchaPuzzle, getVerification } from '@/api/utils'

export default {
  data() {
    return {
      captchaVisible: false,
      // 滑块位置 和 滑块图
      captchaPuzzle: {
        x: 0,
        y: 0,
        shadeImageUrl: '',
        cutoutImageUrl: '',
      },
      loginForm: {
        mobile: '13333333333',
      },
      slider: 13,
      puzzleLeft: 0,
    }
  },
  watch: {
    slider(val) {
      const max = (1 - this.$refs.puzzle.width / this.$refs.shade.width) * 100
      const slope = max / 74
      this.puzzleLeft = Math.min(Math.max(0, slope * (val - 13)), max)
      this.$refs.puzzle.style.left = this.puzzleLeft + '%'
    },
    captchaVisible(val) {
      if (val) {
        this.$nextTick(() => {
          this.calcPuzzle()
        })
      }
    },
  },
  methods: {
    sendVerification() {
      this.getCaptchaPuzzle().then((val) => {
        if (val) {
          this.captchaVisible = true
        }
      })
    },
    getVerification() {
      const { mobile } = this.loginForm
      const { y } = this.captchaPuzzle
      const x = ((this.puzzleLeft / 100) * this.$refs.shade.naturalWidth).toFixed(0)
      getVerification({
        Mobile: mobile,
        X: x,
        Y: y + '',
      })
        .then(({ data: res }) => {
          if (res.code !== '0') {
            this.$toast(res.msg || '验证码发送失败,请重试')
            this.slider = 13
            this.getCaptchaPuzzle()
          } else {
            this.$toast('短信验证已发送')
            this.slider = 13
            this.captchaVisible = false
          }
        })
        .catch((err) => {
          if (err) {
            this.$toast('系统或网络异常')
            this.slider = 13
            this.getCaptchaPuzzle()
          }
        })
    },
    async getCaptchaPuzzle() {
      const { mobile } = this.loginForm
      return getCaptchaPuzzle({
        Mobile: mobile,
      })
        .then((data) => {
          const res = data.data
          if (res.code !== '0') {
            this.$toast(res.msg || '系统或网络异常')
            return false
          }
          this.captchaPuzzle = res.data
          if (this.captchaVisible) {
            this.calcPuzzle()
          } else {
            this.captchaVisible = false
          }
          return true
        })
        .catch((err) => {
          if (err) {
            this.$toast('系统或网络异常')
          }
          return false
        })
    },
    async calcPuzzle() {
      const { x, y } = this.captchaPuzzle,
        shade = this.$refs.shade,
        puzzle = this.$refs.puzzle
      await this.loadImage(shade, this.captchaPuzzle.shadeImageUrl)
      puzzle.style.top = (((y + 1) / shade.naturalHeight) * 100).toFixed(6) + '%'
      await this.loadImage(puzzle, this.captchaPuzzle.cutoutImageUrl)
      puzzle.style.left = x + 'px'
    },
    async loadImage(img, url) {
      return new Promise((resolve, reject) => {
        img.onload = () => resolve(img)
        img.onerror = reject
        img.src = url
      })
    },
  },
}
</script>

<style lang="less" scoped>
.login {
  &-captcha {
    height: 408px;
    text-align: center;
    padding: 0 24px;
    box-sizing: border-box;
    border-radius: 20px 20px 0px 0px;

    &-title {
      height: 28px;
      font-size: 20px;
      font-weight: 600;
      color: #292b2e;
      line-height: 28px;
      padding: 32px 0 20px;
    }
    &-main {
      width: 327px;
      margin: 0 auto;
      border-radius: 8px;
      position: relative;
      overflow: hidden;
    }
    &-shade {
      display: block;
      width: 100%;
    }
    &-puzzle {
      position: absolute;
      width: 50px;
    }
    &-refresh {
      position: absolute;
      top: 6px;
      right: 12px;
      width: 24px;
      height: 24px;
      background: url('../../assets/images/icon_login_refresh.png');
    }
    &-slider {
      display: inline-block;
      margin-top: 32px;
      width: 290px;
      height: 52px;
      background: rgba(188, 191, 200, 0.3);
      border-radius: 27px;
      pointer-events: none;

      &::before {
        // 向右滑动验证;
        content: '\5411\53f3\6ed1\52a8\9a8c\8bc1';
        font-size: 16px;
        line-height: 52px + 8px + 8px;
        color: #8b91a0;
      }
      .van-slider__bar {
        min-width: 13%;
        max-width: 87%;
      }
      .van-slider__button-wrapper {
        pointer-events: auto;
      }
      &__button {
        pointer-events: auto;
        width: 61px;
        height: 44px;
        background-size: cover !important;
        background: url('../../assets/images/btn_verify.png');
      }
    }
  }
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1381668.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于JAVA+SSM框架开发的志愿者服务管理系统设计与实现【附源码】

&#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 &#x1f4dd; &#x1f680;&#x1f680;&#x1f6…

强化学习(一)简介

强化学习这一概念在历史上来源于行为心理学&#xff0c;来描述生物为了趋利避害而改变自己行为的学习过程。人类学习的过程其实就是为达到某种目的不断地与环境进行互动试错&#xff0c;比如婴儿学习走路。强化学习算法探索了一种从交互中学习的计算方法。 1、强化学习 强化学…

31 树的存储结构一

无法直接用数组表示树的逻辑结构&#xff0c;但是可以设计结构体数组对节点间的关系进行描述&#xff1a;【如表】 这样做的问题&#xff1a; 可以利用 组织链表 parent指针&#xff1a; 注意&#xff1a;树结点在 组织链表 中的位置不代表树的任何逻辑关系 树的架构图&#xf…

DNS 在互联网中的作用是什么?

互联网的运作离不开DNS&#xff0c;那么DNS到底是什么&#xff1f;它在互联网中发挥着怎样的作用呢&#xff1f; DNS&#xff0c;全称为Domain Name System&#xff0c;即域名系统&#xff0c;是互联网的一项基础设施。它负责将人们易于记忆的域名&#xff08;如www.example.…

MySQL 从零开始:06 数据检索

文章目录 1、数据准备2、限制结果3、完全限定名4、排序检索 所谓数据检索&#xff0c;就是前面所讲的”增删改查“的”查“。 注&#xff1a;本文使用的“行”指数据表中的“记录”&#xff0c;“列”指数据表中的“字段”。 在第四节《表的增删改查》中已经介绍了 select 查询…

C# Cad2016二次开发api(三)

直线 Line 属性中文数据类型作用Length长度double直线的长度Angle角度double直线的弧度&#xff0c;0~2πDelta增量Vector3d起点到终点的向量Normal法向向量Vector3d直线所在平面的法向单位向量Thickness厚度doubleEndPoint终点Point3d直线的终点StartPoint起点Point3d直线的起…

Memory Wall in Neural Network Inference

Memory Wall in Neural Network Inference 神经网络推理的瓶颈在于访存带宽&#xff0c;通常无法发挥出加速器的全部算力。本文总结了目前常用的推理加速器及其设计&#xff0c;并分析了常用神经网络的访存瓶颈。文章大部分内容参考自Computer Architecture: A Quantitative A…

JavaScript基础(26)_dom增删改练习

<!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><title>DOM增删改练习</title><link rel"stylesheet" href"../browser_default_style/reset.css"><style>table {borde…

软件测试|Selenium StaleElementException异常的原因与方法

简介 在使用Selenium进行Web自动化测试时&#xff0c;我们可能会遇到StaleElementException异常。这个异常通常在我们操作一个之前已经找到的元素时抛出&#xff0c;但该元素已经不再处于DOM树中&#xff0c;导致元素过时&#xff08;stale&#xff09;。本文将介绍StaleEleme…

C++11 左右值引用、移动语义

右值引用和移动语义 什么是左值&#xff1f;什么是左值引用&#xff1f; 左值是一个表示数据的表达式(如变量名或解引用的指针)&#xff0c;我们可以获取它的地址可以对它赋值&#xff0c;左值可以出现赋值符号的左边&#xff0c;右值不能出现在赋值符号左边。定义时const修饰…

SpringSecurity入门demo(二)表单认证

上一篇博客集成 Spring Security&#xff0c;使用其默认生效的 HTTP 基本认证保护 URL 资源&#xff0c;下面使用表单认证来保护 URL 资源。 一、默认表单认证&#xff1a; 代码改动&#xff1a;自定义WebSecurityConfig配置类 package com.security.demo.config; import or…

基于python的基金分析可视化系统

项目背景&#xff1a; 随着金融市场的发展和人们对财富管理的重视&#xff0c;越来越多的人开始参与基金投资。然而&#xff0c;由于市场上基金产品众多且复杂&#xff0c;投资者往往难以快速准确地获取基金信息和进行分析&#xff0c;从而导致投资决策不够科学和有效。为了解决…

PyCharm安装使用教程2024

简介 PyCharm是一种PythonIDE&#xff08;Integrated Development Environment&#xff0c;集成开发环境&#xff09;&#xff0c;带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具&#xff0c;比如调试、语法高亮、项目管理、代码跳转、智能提示、自动完成、单…

三棋先手必胜证明

目录 创作原因 游戏规则 初始状态图 证明过程 先手必胜的证明 失败的博弈树&#xff08;三个多小时的成果&#xff09; 创作原因 这个棋不是网上流行的成三棋&#xff0c;我也不知道这个棋叫什么。由于这个棋是&#xff08;横竖斜&#xff09;连成三个就获胜&#xff0c;…

Vulnhub-HACKSUDO: PROXIMACENTAURI渗透

文章目录 一、前言1、靶机ip配置2、渗透目标3、渗透概括 开始实战一、信息获取二、端口敲门三、web密码爆破四、getShell五、获取新用户六、提权 一、前言 由于在做靶机的时候&#xff0c;涉及到的渗透思路是非常的广泛&#xff0c;所以在写文章的时候都是挑重点来写&#xff0…

【同济子豪兄斯坦福CS224W中文精讲】NetworkX代码学习笔记

文章目录 安装配置创建图可视化图图数据挖掘参考资料 安装配置 matplotlib中文字体设置 import networkx as nx import matplotlib.pyplot as plt # 魔法指令&#xff0c;设置后在jupyter notebook中绘制的图形会显示在输出单元格中&#xff0c;而不是弹出一个新窗口 %matplo…

ssm基于Javaweb的网上奶茶店系统的设计与实现论文

摘 要 计算机网络发展到现在已经好几十年了&#xff0c;在理论上面已经有了很丰富的基础&#xff0c;并且在现实生活中也到处都在使用&#xff0c;可以说&#xff0c;经过几十年的发展&#xff0c;互联网技术已经把地域信息的隔阂给消除了&#xff0c;让整个世界都可以即时通话…

爬虫之牛刀小试(四):爬取B站番剧的简介

今天爬取的是b站。 如何爬取b站中的番剧呢&#xff1f; 首先我们来到番剧索引中&#xff0c;随便点开一部动漫&#xff0c;检查代码。 每个作品对应一个链接: https://www.bilibili.com/bangumi/play/ss…&#xff08;ss后面的数字称为ss号&#xff09; 发现关于动漫的信息…

【数据库】sql优化有哪些?从query层面和数据库层面分析

目录 归纳sql本身的优化数据库层面的优化 归纳 这类型问题可以称为&#xff1a;Query Optimization&#xff0c;从清华AI4DB的paper list中&#xff0c;该类问题大致可以分为&#xff1a; Query RewriterCardinality EstimationCost EstimationPlan Optimization 从中文的角…

某厂校招一道关于C的笔试题

一、笔试原题 题目&#xff1a;在Linux x86 _ 54 gcc环境下&#xff0c;下面的程序会出现什么问题&#xff1f;运行结果是什么&#xff1f;为什么&#xff1f; 程序如下图&#xff1a; 通过在gcc的环境下编译运行&#xff0c;发现运行结果为不断死循环打印0-17的数字 我们…