前端实现转盘抽奖 - 使用 lucky-canvas 插件

目录

  • 需求背景
  • 需求实现
    • 实现过程图片示意
    • 实现代码
  • 页面效果
  • lucky-canvas 插件官方文档

需求背景

要求实现转盘转动抽奖的功能:

  1. 只有正确率大于等于 80% 才可以进行抽奖;
  2. “谢谢参与”概率为 90%,“恭喜中奖”概率为 10%;

需求实现

在这里插入图片描述
在这里插入图片描述

实现过程图片示意

在这里插入图片描述

实现代码

安装插件

npm install @lucky-canvas/vue@latest

main.js 全局引入组件

import VueLuckyCanvas from '@lucky-canvas/vue'
Vue.use(VueLuckyCanvas)

实现代码

<template><div class="exam-result"><div class="info"><div class="progress"><nut-circleprogress:progress="(correct / total).toFixed(1) * 100":is-auto="true"color="#ff4d4f"path-color="#ffeded"><div class="progressDiv"><div class="accuracy">正确率{{ (correct / total).toFixed(1) * 100 }}%</div></div></nut-circleprogress></div></div><div class="content"><div class="result-table"><div style="padding: 10px 10px 10px 15px">试卷分析</div></div><div class="result-table"><div class="item"><div class="title">题目总量:</div><div class="total">{{ total }}</div><div class="unit"></div></div></div><div class="result-table"><div class="item"><div class="title">正确题数:</div><div class="correct">{{ correct }}</div><div class="unit"></div></div><div class="item"><div class="title">错误题数:</div><div class="error">{{ total - correct }}</div><div class="unit"></div></div></div></div><div v-if="examType === 'challenge' && (correct / total).toFixed(1) >= 0.8" class="lottery_draw_btn">恭喜您获得抽奖资格 <nut-button type="primary" size="mini" @click="toLotteryDraw">点击进行抽奖</nut-button></div><nut-dialog teleport="#app" :title="isShowlotteryDraw ? '点击“开始”抽奖' : ''" content="" v-model:visible="dialogVisible" customClass="task" :noCancelBtn="true" :noOkBtn="true" :closeOnClickOverlay="false"><nut-icon name="close" @click="dialogVisible = false" /><LuckyWheelv-if="isShowlotteryDraw"class="myLucky"ref="myLuckyRef"width="320px"height="320px":prizes="prizes":blocks="blocks":buttons="buttons"@start="startCallback"@end="endCallback"/><div v-else class="result" :style="{'--color': lotteryDrawIndex === 1 ? 'red' : '#000'}">{{ lotteryDrawIndex === 1 ? "恭喜中奖" : "谢谢参与" }}</div></nut-dialog></div><fallback></fallback>
</template><script>
import {reactive, toRefs, ref, getCurrentInstance
} from 'vue'
import { useRoute } from 'vue-router'export default {name: 'result',setup() {// const myLuckyRef = ref(null) // 【ref问题】我的代码里这种办法取不到 ref,使用 getCurrentInstance 取 refconst instance = getCurrentInstance() // 【ref解决】使用 getCurrentInstance 取 refconst route = useRoute()const state = reactive({lotteryDrawIndex: 0, // 最终转盘定格的索引isShowlotteryDraw: true, // 是否抽奖完成// 转盘背景配置blocks: [{padding: '20px',imgs: [{// src: 'https://img.iwave.net.cn/jeep/51c95637a377c3a12d09abe8b0f975e6.png',src: require('@/assets/images/lottery_draw.png'),width: 320,height: 320,rotate: true}]}],// 每个扇形区域奖品配置prizes: [...Array(10).keys()].map((index) => ({fonts: [{text: index % 2 === 0 ? '谢谢参与' : '恭喜中奖',top: '15%',fontSize: '15px',fontColor: '#ed1c24',},],background: index % 2 === 0 ? '#fff5cc' : '#e9d6e9',})),// 抽奖按钮配置buttons: [{ radius: '50px', background: '#d034ac' },{ radius: '45px', background: '#fe97b2' },{radius: '35px',background: '#f04a07',pointer: true,fonts: [{ text: '开始', top: '-10px', fontColor: '#fff' }]}],// 抽奖弹框是否展示dialogVisible: false})// 获取正确题数、总题数const { correct, total, examType } = route.queryconst toLotteryDraw = () => {state.dialogVisible = true}// 点击抽奖按钮会触发star回调const startCallback = () => {console.log('"开始抽奖"----', '开始抽奖')// 调用抽奖组件的play方法开始游戏// console.log('myLucky.value----', myLuckyRef.value) // 【ref问题】// myLuckyRef.value?.play() // 【ref问题】if (instance) {instance.refs?.myLuckyRef?.play() // 【ref解决】}// this.$refs.myLucky.play()  // 【ref】vue2写法// 模拟调用接口异步抽奖setTimeout(() => {// 假设index(谢谢参与90%,恭喜中奖10%)const index = `${Math.random()}`.slice(2, 3) * 1state.lotteryDrawIndex = index === 1 ? 1 : 2// 调用stop停止旋转并传递中奖索引// this.$refs.myLuckyRef.stop(index)   // 【ref】vue2写法// myLuckyRef.value?.stop(index) // 【ref问题】if (instance) {instance.refs?.myLuckyRef?.stop(state.lotteryDrawIndex) // 【ref解决】}}, 3000)}// 抽奖结束会触发end回调const endCallback = (prize) => {console.log('"结束抽奖"----', '结束抽奖')console.log(prize)state.isShowlotteryDraw = false}return {...toRefs(state),correct,total,examType,toLotteryDraw,startCallback,endCallback}}
}
</script><style scoped lang="less">
.exam-result {.info {margin: 0 0 5px;padding: 10px;background-color: white;.progress {display: flex;flex-direction: column;align-items: center;padding: 5px;position: relative;.nut-circleprogress {width: 145px !important;height: 145px !important;position: relative;.progressDiv {display: flex;flex-direction: column;align-items: center;.accuracy {color: #00000080;background-color: #ffeded;padding: 2px 8px;font-size: 13px;border-radius: 5px;}}}.circle {position: absolute;height: 145px;width: 145px;background-color: #ffeded;border-radius: 50%;top: 5px;left: 50%;transform: translate(-50%);.circle1 {position: absolute;height: 115px;width: 115px;background-color: #ffffff;border-radius: 50%;top: 50%;left: 50%;transform: translate(-50%, -50%);}}}.count {background-color: #fffbf3;margin-top: 10px;padding-top: 5px;color: #797e79;font-size: 14px;display: flex;justify-content: space-around;.centerDiv {display: flex;align-items: baseline;justify-content: center;.number {margin-right: 5px;font-size: 20px;color: #FAAD14;}.text {font-size: 12px;}}}}.content {margin-bottom: 10px;background: white;border-bottom: 1px solid #dcdcdc;.result-table {display: flex;font-size: 16px;font-weight: bolder;color: #000;.item {display: flex;align-items: baseline;border-top: 0.5px solid #dcdcdc;flex: 1;font-size: 16px;padding: 10px 10px 10px 15px;color: #7f7f7f;font-weight: normal;&:nth-child(2n+1) {border-right: 0.5px solid #dcdcdc;}.title {margin-right: 5px;font-size: 14px;}.unit {font-size: 12px;margin-left: 5px;}.time,.total {color: black;font-size: 16px;}.correct {color: #04be01;font-size: 18px;}.error {color: red;font-size: 18px;}}}}// 弹框样式::v-deep .popup-center.round {width: 90%;.nut-dialog {width: 100%;padding: 20px 5px;.nut-dialog__content {max-height: unset;.nut-icon-close {position: absolute;top: 15px;right: 15px;}// 转盘结束展示结果.result {height: 80px;line-height: 80px;font-size: 20px;font-weight: bold;color: var(--color);}// 转盘.myLucky {display: inline-block;}}}}// 抽奖弹框按钮.lottery_draw_btn {height: 25PX;line-height: 25PX;padding: 0 10px;cursor: pointer;font-size: 16px;color: red;}
}
</style>

页面效果

在这里插入图片描述

lucky-canvas 插件官方文档

lucky-canvas 插件官网
lucky-canvas 插件官网文档

可参考文档

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

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

相关文章

综合CRM客户管理系统

技术框架&#xff1a; JAVA MYSQL SSH 功能介绍&#xff1a; 个人工作、信息中心、客户管理、合同订单、财务管理、产品管理、人事管理以及数据回收站等8个模块。另包括权限管理模块用于系统的用户、角色和相关权限&#xff0c;收发邮件功能用于获得客户的详细需求&#xf…

docker 基础手册

文章目录 docker 基础手册docker 容器技术镜像与容器容器与虚拟机docker 引擎docker 架构docker 底层技术docker 二进制安装docker 镜像加速docker 相关链接docker 生态 docker 基础手册 docker 容器技术 开源的容器项目&#xff0c;使用 Go 语言开发原意“码头工人”&#x…

Java基础进阶02-xml

一、XML&#xff08;可拓展标记语言&#xff09; 1.学习网站&#xff1a; https://www.w3schoo1.com.cn 标记语言:通过标签来描述数据的一门语言(标签有时我们也将其称之为元素) 可扩展:标签的名字是可以自定义的 2.作用 用于进行存储数据和传输数据 作为软件的配置文件 …

MySQL 8.3 发布, 它带来哪些新变化?

1月16号 MySQL 官方发布 8.3 创新版 和 8.0.36 长期支持版本 (该版本 没有新增功能&#xff0c;更多是修复bug )&#xff0c;本文基于 官方文档 说一下 8.3 版本带来的变化。 一 增加的特性 1.1 GTID_NEXT 支持增加 TAG 选项。 之前的版本中 GTID_NEXTUUID:number &#xff…

使用IntelliJ IDEA快速搭建springboot 基础模板项目

使用IntelliJ IDEA快速搭建springboot 基础模板项目&#xff01;今天和大家分享一下&#xff0c;如何使用IntelliJ IDEA里面的maven插件&#xff0c;来快速搭建一个简单的Springboot基础项目。 第一步&#xff0c;菜单里面找到&#xff0c;文件-》新建-项目。如图。我们勾选了是…

ChatGPT用来润色论文\生成完整长篇论文\进行AI绘图,到底有多强大!!

​课程安排 学习内容 第一章 2024年AI领域最新技术 1.OpenAI新模型-GPT-5 2.谷歌新模型-Gemini Ultra 3.Meta新模型-LLama3 4.科大讯飞-星火认知 5.百度-文心一言 6.MoonshotAI-Kimi 7.智谱AI-GLM-4 第二章 OpenAI开发者大会后GPT最新技术 1.最新大模型GPT-4 Turbo详细介…

Spring Boot 整合 Camunda 实现工作流

工作流是我们开发企业应用几乎必备的一项功能&#xff0c;工作流引擎发展至今已经有非常多的产品。最近正好在接触Camunda&#xff0c;所以来做个简单的入门整合介绍。如果您也刚好在调研或者刚开始计划接入&#xff0c;希望本文对您有所帮助。如果您是一名Java开发或Spring框架…

【博客搭建记录贴】问题记录:hexo : 无法加载文件 C:\Program Files\nodejs\hexo.ps1,因为在此系统上禁止运行脚本。

1&#xff0c;背景 hexo&#xff08;博客框架&#xff09;安装完毕之后&#xff0c;正准备看看其版本&#xff0c;发现出现下面脚本禁止运行的错误。 PS C:\Users\PC> hexo -v hexo : 无法加载文件 C:\Program Files\nodejs\hexo.ps1&#xff0c;因为在此系统上禁止运行脚…

AMIS的组件学习使用

部分代码片段 {"id": "filterForm","className": " xysd-zbkb-pubquery","labelWidth": 130,"body": [{"type": "grid","className": "xysd-grid-query-input","c…

第12章_集合框架(Collection接口,Iterator接口,List,Set,Map,Collections工具类)

文章目录 第12章_集合框架本章专题与脉络1. 集合框架概述1.1 生活中的容器1.2 数组的特点与弊端1.3 Java集合框架体系1.4 集合的使用场景 2. Collection接口及方法2.1 添加2.2 判断2.3 删除2.4 其它 3. Iterator(迭代器)接口3.1 Iterator接口3.2 迭代器的执行原理3.3 foreach循…

dolphinscheduler节点二次开发需要改动的部分

dolphinscheduler节点二次开发需要改动的部分 前端 在dolphinscheduler-ui/public/images/task-icons/目录下新增两个节点的logo图片&#xff0c;一个为激活状态的一个为非激活状态的&#xff0c;如下。 修改文件dolphinscheduler-ui/src/views/projects/task/constants/task…

实战:加密传输数据解密

前言 下面将分享一些实际的渗透测试经验&#xff0c;帮助你应对在测试中遇到的数据包内容加密的情况。我们将以实战为主&#xff0c;技巧为辅&#xff0c;进入逆向的大门。 技巧 开局先讲一下技巧&#xff0c;掌握好了技巧&#xff0c;方便逆向的时候可以更加快速的找到关键…

HCIE之BGP基础概念(一)

BGP 一、BGP的基本概述二、BGP分类三、BGP的工作原理BGP报文类型&#xff1a;BGP状态机&#xff1a; 四、BGP对等体之间的交互原则解决BGP路由黑洞方法&#xff1a; 五、路由反射器路由反射规则路由反射器下防环联邦 六、BGP属性特点优选协议首选值&#xff08;PrefVal&#xf…

PHP编程实践:实际商品价格数据采集

引言 在电子商务领域&#xff0c;对商品价格进行数据采集和对比是一项常见的需求。本文将介绍如何使用PHP编程语言实现对1688和淘宝商品价格数据的采集和对比&#xff0c;帮助读者了解实际的编程实践过程。 一、数据采集原理 数据采集是指从互联网上获取数据的过程&#xff…

【前端web入门第一天】01 开发环境、HTML基本语法文本标签

文章目录: 1. 准备开发环境 1.1 vs Code基本使用 2.HTML文本标签 2.1 标签语法2.2 HTML基本骨架2.3 标签的关系2.4 注释2.5 标题标签2.6 段落标签2.7 换行与水平线标签2.8 文本格式化标签 1. 准备开发环境 VSCode与谷歌浏览器离线版,安装包评论区自提. VSCode默认安装位置:C…

3、非数值型的分类变量

非数值型的分类变量 有很多非数字的数据,这里介绍如何使用它来进行机器学习。 在本教程中,您将了解什么是分类变量,以及处理此类数据的三种方法。 本课程所需数据集夸克网盘下载链接:https://pan.quark.cn/s/9b4e9a1246b2 提取码:uDzP 文章目录 1、简介2、三种方法的使用1…

书生·浦语大模型实战营-学习笔记5

LMDeploy 大模型量化部署实践 大模型部署背景 LMDeploy简介 轻量化、推理引擎、服务 核心功能-量化 显存消耗变少了 大语言模型是典型的访存密集型任务&#xff0c;因为它是decoder-by-decoder 先把数据量化为INT4存起来&#xff0c;算的时候会反量化为FP16 AWQ算法&a…

Angular组件(一) 分割面板ShrinkSplitter

Angular组件(一) 分割面板ShrinkSplitter 前言 分割面板在日常开发中经常使用&#xff0c;可将一片区域&#xff0c;分割为可以拖拽整宽度或高度的两部分区域。模仿iview的分割面板组件&#xff0c;用angular实现该功能&#xff0c;支持拖拽和[(ngModel)]双向绑定的方式控制区…

Docker容器引擎(2)

目录 一.批量删除镜像&#xff0c;容器 二.Docker 网络实现原理 随机映射端口&#xff08;从32768开始&#xff09; 访问自己&#xff1a; 在10服务器上配置路由转发&#xff1a; 指定映射端口&#xff1a; 查看容器的输出和日志信息&#xff1a; 将宿主机目标|文件挂载…

RabbitMQ中交换机的应用及原理,案例的实现

目录 一、介绍 1. 概述 2. 作用及优势 3. 工作原理 二、交换机Exchange 1. Direct 2. Topic 3. Fanout 三、代码案例 消费者代码 1. 直连direct 生产者代码 测试 2. 主题topic 生产者代码 测试 3. 扇形fanout 生产者代码 测试 每篇一获 一、介绍 1. …