H5 Canvas实现转盘效果,控制指定数字

news2024/11/29 10:33:47

效果图

实现思路:

用Canvas画圆,然后再画扇形,然后中奖的开始用一张图片代替,点击的时候触发转动效果。

实现代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>活动中心</title>
    <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0" />
    <meta name="format-detection" content="telephone=no,email=no,date=no,address=no">
    <style type="text/css">
        * {
            margin: 0px;
            padding: 0px;
            border: none;
            width: 100%;
        }

        body {
            background-color: #F6FBF7;
        }
    </style>
</head>
<body>
    <div style="border: solid 1px #ECECEC;font-weight:bold;background-color:white;line-height:50px;text-align:center;margin:0px auto;width:80%;margin-top:20px;">幸运转盘</div>
    <div id="number" style="line-height: 50px; font-weight: bold; text-align: center; margin: 0px auto; width: 80%; margin-top: 50px;">????</div>
    <div style="width: calc(100wh); margin: 0px auto 0 auto; text-align: center;">
        <img onClick="spin();" src="~/Content/H5Game/click.jpg" style="width: 100px; height: 100px; margin: 0px auto; display: block; position: absolute; left: calc(50% - 50px); top: 315px " />
        <canvas id="wheelcanvas" width="500" height="500"></canvas>
    </div>
    <script type="text/javascript">
        //颜色
        var colors = ["#ED6E40", "#D7363C", "#D5386B", "#B731C4", "#7936D4", "#215ACD", "#4192BE", "#82AD49"];
        var restaraunts = [];
        var number = 48;//数字,需要12的倍数
        for (var i = 1; i <= number; i++) {
            restaraunts.push(i);
        }
        var startAngle = 0;
        var arc = Math.PI / (number / 2);
        var spinTimeout = null;
        var spinArcStart = 10;
        var spinTime = 0;
        var spinTimeTotal = 0;
        // 你指定的数字
        var targetNumber = 37;//1=37 2=36 .....37=1, 38=48 39=47.....48=38
        //不出现的数据
        var hideNumber = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30];
        //数字的对应关系
        var targetKeyValue = {};
        var ctx;

        //初始化数字和对应关系,如果你要得到1,那么数字就是targetKeyValue.1得到的37
        for (var i = 1; i <= 37; i++) {
            targetKeyValue[i] = 38 - i;
        }
        for (var i = 1; i <= 11; i++) {
            targetKeyValue[37 + i] = 49 - i;
        }

        //获取随机数
        function randomNumber() {
            var randomNumber = getRandomInt(1, 48);
            //判断如果在不出现的数字内,继续生成一个其他的
            while (hideNumber.includes(randomNumber)) {
                randomNumber = getRandomInt(1, 48);
            }
            return targetKeyValue[randomNumber];
        }

        function getRandomInt(min, max) {
            return Math.floor(Math.random() * (max - min + 1)) + min;
        }

        function draw() {
            drawRouletteWheel();
        }

        function drawRouletteWheel() {
            var canvas = document.getElementById("wheelcanvas");
            if (canvas.getContext) {
                var outsideRadius = 200;//外圈大小
                var textRadius = 170;//数字显示的位置
                var insideRadius = 40;//内圈大小
                ctx = canvas.getContext("2d");
                ctx.clearRect(0, 0, 500, 500);
                ctx.strokeStyle = "white";//两个圈圈的边框颜色
                ctx.lineWidth = 6;//外面圈圈的边框,会影响到显示
                ctx.font = ' 14px Microsoft YaHei';//转盘数字,字体,微软雅黑
                var colorIndex = 0;
                for (var i = 0; i < number; i++) {
                    var angle = startAngle + i * arc;
                    ctx.fillStyle = colors[colorIndex];
                    colorIndex++;
                    if (colorIndex == colors.length - 1) {
                        colorIndex = 0;
                    }
                    ctx.beginPath();

                    ctx.arc(250, 250, 0, 0, 0, true);//扇形区域的间隔

                    ctx.arc(250, 250, outsideRadius, angle, angle + arc, false);
                    ctx.arc(250, 250, insideRadius, angle + arc, angle, true);
                    ctx.stroke();
                    ctx.fill();
                    ctx.save();
                    ctx.shadowOffsetX = 0;
                    ctx.shadowOffsetY = 0;
                    ctx.shadowBlur = 0;
                    ctx.shadowColor = "";//"rgb(220,220,220)";//字体的阴影
                    ctx.fillStyle = "#FFFFFF"; //字体颜色
                    //-2调整字体的位置
                    ctx.translate(250 + Math.cos(angle + arc / 2) * textRadius, 250 + Math.sin(angle + arc / 2) * textRadius);
                    ctx.rotate(angle + arc / 2 + Math.PI / 2);
                    var text = restaraunts[i];
                    ctx.fillText(text, -ctx.measureText(text).width / 2, 0);
                    ctx.restore();
                }

                箭头
                //ctx.fillStyle = "black";
                //ctx.beginPath();
                //ctx.moveTo(250 - 4, 250 - (outsideRadius + 5));
                //ctx.lineTo(250 + 4, 250 - (outsideRadius + 5));
                //ctx.lineTo(250 + 4, 250 - (outsideRadius - 5));
                //ctx.lineTo(250 + 9, 250 - (outsideRadius - 5));
                //ctx.lineTo(250 + 0, 250 - (outsideRadius - 13));
                //ctx.lineTo(250 - 9, 250 - (outsideRadius - 5));
                //ctx.lineTo(250 - 4, 250 - (outsideRadius - 5));
                //ctx.lineTo(250 - 4, 250 - (outsideRadius + 5));
                //ctx.fill();
            }
        }

        function spin() {

            init();

            //点击的时候,指定一个数据
            targetNumber = randomNumber();

            document.getElementById("number").innerText = "????";

            // 计算总旋转角度
            //var targetNumber = 1; // 你指定的数字
            var targetIndex = restaraunts.indexOf(targetNumber);
            var targetAngle = targetIndex * arc;
            var totalRotations = 10; // 10圈
            var totalAngle = totalRotations * 2 * Math.PI + targetAngle;

            spinTime = 0;
            spinTimeTotal = 6000; // 旋转时间
            rotateWheel(totalAngle);
        }

        function rotateWheel(totalAngle) {
            spinTime += 30;

            var degrees = startAngle * 180 / Math.PI + 90;
            var arcd = arc * 180 / Math.PI;
            var index = Math.floor((360 - degrees % 360) / arcd);
            var finalNumber = restaraunts[index];
            console.log(finalNumber);

            startAngle += (totalAngle - startAngle) * 0.05; // 平滑旋转

            drawRouletteWheel();

            if (spinTime < spinTimeTotal) {
                spinTimeout = setTimeout(function () {
                    rotateWheel(totalAngle);
                }, 30);
            } else {
                document.getElementById("number").innerText = finalNumber;
            }
        }

        function init() {
            // 确保默认停在数字1
            var targetIndex = restaraunts.indexOf(37);
            var targetAngle = targetIndex * arc;
            startAngle = targetAngle;

            draw();

        }

        init();
    </script>
</body>
</html>

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

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

相关文章

开源六轴协作机械臂myCobot 280接入GPT4大模型!实现更复杂和智能化的任务

本文已经或者同济子豪兄作者授权对文章进行编辑和转载 引言 随着人工智能和机器人技术的快速发展&#xff0c;机械臂在工业、医疗和服务业等领域的应用越来越广泛。通过结合大模型和多模态AI&#xff0c;机械臂能够实现更加复杂和智能化的任务&#xff0c;提升了人机协作的效率…

孟德尔随机化 --痛风与酒精消耗量

写在前面 最近看了微信公众号&#xff0c;jimmy谈到生信与基础之间&#xff0c;个人觉得生信与基础技术是无高低之分的&#xff0c;本质上都是科研中为了证实结果的一个工具。生信的实质是用计算机分析数据&#xff0c;接触基础比较好&#xff0c;感觉是实验操作。分析上游为实…

ESD管ESD113-B1-02EL(S)国产替代型号ULC0342CDNH,ULC0321CDNH

雷卯型号全&#xff0c;能替代大量infineon型号。具体如下&#xff1a; 应用于3.3V高速信号静电保护器件&#xff0c;infineon的ESD113-B1-02EL(DFN1006)和ESD113-B1-02ELS(DFN0603)&#xff0c;交期长&#xff0c;价格高。已经有很多客户选雷卯的 ULC0342CDNH(DFN1006)&#…

RK3568平台(opencv篇)opencv处理图像视频

一.读取图像文件并展示 灰度图像&#xff1a; 灰度图需要用 8 位二进制来表示&#xff0c;取值范围是 0-255。用 0 表示 0&#xff08;黑色&#xff09;&#xff0c; 用 255 表示 1&#xff08;白色&#xff09;&#xff0c;取值越大表示该点越亮。 RGB 彩色图像&#xff1a;…

Keras实战之图像分类识别

文章目录 整体流程数据加载与预处理搭建网络模型优化网络模型学习率Drop-out操作权重初始化方法对比正则化加载模型进行测试 实战&#xff1a;利用Keras框架搭建神经网络模型实现基本图像分类识别&#xff0c;使用自己的数据集进行训练测试。 问&#xff1a;为什么选择Keras&am…

全网最详细的Appium自动化测试框架(一)环境搭建

一、环境搭建 1、安装python3 2、安装appium-destop 3 、安装python虚拟环境 ,安装依赖库 : pip install Appium-Python-Client pip install pytest 4、安装java brew install java 配置好环境变量 5、安装 android-platform-tools &#xff08;也可以用android sdk 工…

数据库概念题总结

1、 2、简述数据库设计过程中&#xff0c;每个设计阶段的任务 需求分析阶段&#xff1a;从现实业务中获取数据表单&#xff0c;报表等分析系统的数据特征&#xff0c;数据类型&#xff0c;数据约束描述系统的数据关系&#xff0c;数据处理要求建立系统的数据字典数据库设计…

C++11|包装器

目录 引入 一、function包装器 1.1包装器使用 1.2包装器解决类型复杂 二、bind包装器 引入 在我们学过的回调中&#xff0c;函数指针&#xff0c;仿函数&#xff0c;lambda都可以完成&#xff0c;但他们都有一个缺点&#xff0c;就是类型的推导复杂性&#xff0c;从而会…

【TORCH】绘制权重分布直方图,权重torch.fmod对torch.normal生成的随机数进行取模运算

要绘制上述代码中权重初始化的分布&#xff0c;可以分别展示每一层初始化权重的直方图。我们将用 torch.fmod 对 torch.normal 生成的随机数进行取模运算&#xff0c;确保权重值在 -2 到 2 之间。 含义解释 torch.normal(0, init_sd, size...)&#xff1a;生成服从均值为 0、…

编译Open Cascade(OCC)并使用C#进行开发

说明&#xff1a; VS版本&#xff1a;Visual Studio Community 2022系统&#xff1a;Windows 11 专业版23H2Open CASCADE&#xff1a;v7.7.0&#xff08;链接&#xff1a;https://pan.baidu.com/s/1-o1s4z3cjpYf5XkwhSDspQ?pwdp9i5提取码&#xff1a;p9i5&#xff09; 下载和…

【Kafka】Kafka生产者开启幂等性后报错:Cluster authorization failed.

文章目录 背景解决服务端配置ACL增加授权 背景 用户业务需求&#xff0c;需要开启生产者的幂等性&#xff0c;生产者加了配置&#xff1a;enable.idempotence true用户使用的集群开启了ACL认证&#xff1a;SASL_PLAINTEXT/SCRAM-SHA-512用户生产消息时报错&#xff1a;org.ap…

[笔记] 卷积 - 02 滤波器在时域的等效形式

1.讨论 这里主要对时域和频域的卷积运算的特征做了讨论&#xff0c;特别是狄拉克函数的物理意义。 关于狄拉克函数&#xff0c;参考这个帖子&#xff1a;https://zhuanlan.zhihu.com/p/345809392 1.狄拉克函数提到的好函数的基本特征是能够快速衰减&#xff0c;对吧&#xf…

VBA提取word表格内容到excel

这是一段提取word表格中部分内容的vb代码。 Sub 提取word表格() mypath ThisWorkbook.Path & "\"myname Dir(mypath & "*.doc*")n 4 index of rowsRange("A1:F1") Array("课程代码", "课程名称", "专业&…

云服务器在 Web 应用程序中作用

云服务器在Web应用程序中扮演着至关重要的角色&#xff0c;它不仅是现代Web应用程序的基石&#xff0c;还是推动业务发展和提升用户体验的关键技术之一。下面将详细探讨云服务器在Web应用程序中的重要作用及其优势。 首先&#xff0c;云服务器为Web应用程序提供了高度可扩展的…

蜂窝物联粮仓环境在线监测系统,确保粮食安全

在金黄的麦田里&#xff0c;每一粒小麦都承载着农民的辛勤与期待。为了保证这些宝贵粮食的品质与安全&#xff0c;储存环节显得尤为重要。传统的粮仓管理方式已难以满足现代粮食储存的需求&#xff0c;因此&#xff0c;引入智慧粮仓环境监控系统成为了必然的选择。 一、为何需…

谷粒商城 - 树形菜单递归流查询、三级分类数据查询性能优化、Jmter 性能压测

目录 树形分类菜单&#xff08;递归查询&#xff0c;强扩展&#xff09; 1&#xff09;需求 2&#xff09;数据库表设计 3&#xff09;实现 4&#xff09;关于 asSequence 优化 性能压测 1&#xff09;Jmeter 安装使用说明 2&#xff09;中间件对性能的影响 三级分类数…

Python内存优化的实战技巧详解

概要 Python是一种高级编程语言,以其易读性和强大的功能而广受欢迎。然而,由于其动态类型和自动内存管理,Python在处理大量数据或高性能计算时,内存使用效率可能不如一些低级语言。本文将介绍几种Python内存优化的技巧,并提供相应的示例代码,帮助在开发中更高效地管理内…

uniapp启动安卓模拟器mumu

mumu模拟器下载 ADB&#xff1a; android debug bridge &#xff0c; 安卓调试桥&#xff0c;是一个多功能的命令行工具&#xff0c;他使你能够与连接的安卓设备进行交互 # adb连接安卓模拟器 adb connect 127.0.0.1:port # 查看adb设备 adb deviceshubuilderx 有内置的adb&a…

【鸿蒙学习笔记】@Link装饰器:父子双向同步

官方文档&#xff1a;Link装饰器&#xff1a;父子双向同步 目录标题 [Q&A] Link装饰器作用 [Q&A] Link装饰器特点样例&#xff1a;简单类型样例&#xff1a;数组类型样例&#xff1a;Map类型样例&#xff1a;Set类型样例&#xff1a;联合类型 [Q&A] Link装饰器作用…

锂电池寿命预测 | Matlab基于改进的遗传算法优化BP神经网络的锂离子电池健康状态SOH估计

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 主要流程如下: 1、首先提取“放电截止电压时间”作为锂电池间接健康因子&#xff1b; 2、然后引入改进的遗传算法对BP神经网络的模型参数进行优化。 3、最后 NASA 卓越预测中心的锂电池数据集 B0005、B0006、B0007对…