前言
如果是新手的话 建议先看一遍官方文档,这里放两个文档链接
Canvas 的基本用法 - Web API | MDN (mozilla.org)
HTML DOM Canvas 对象 | 菜鸟教程 (runoob.com)
画一个圆
let canvas: HTMLCanvasElement | null = null;
const dpr = window.devicePixelRatio; // 获取设备像素比
onMounted(() => {
canvas = document.getElementById("clockCanvas") as HTMLCanvasElement; // 获取Canvas元素
if (canvas) {
ctx = canvas.getContext("2d"); // 获取2D上下文
if (ctx) {
//此段代码是为了让canvas更清晰
const { width, height } = canvas;
canvas.width = Math.round(width * dpr);
canvas.height = Math.round(height * dpr);
canvas.style.width = width + "px";
canvas.style.height = height + "px";
ctx.scale(dpr, dpr);//设置画布的缩放比例
centerX = canvas.width / (2 * dpr); // 计算圆心X坐标
centerY = canvas.height / (2 * dpr); // 计算圆心Y坐标
ctx.translate(centerX, centerY); // 平移至圆心
drawClockFace(0, 0); // 如果成功获取到2D上下文,则绘制
}
}
});
// 绘制背景圆
function drawClockFace(centerX: number, centerY: number): void {
if (!ctx) return; // 如果2D上下文不存在,则返回
ctx.beginPath(); // 开始路径
ctx.arc(centerX, centerY, 240, 0, Math.PI * 2); // 绘制圆形
ctx.lineWidth = 2; // 设置线宽
ctx.strokeStyle = "#000"; // 设置描边颜色
ctx.stroke(); // 绘制描边
ctx.closePath(); // 结束路径
}
这样一个圆就画好了
旋转
这里为了更直观的查看旋转 简单的上了色
基本逻辑为让它旋转一定角度后重新绘制并清空画布,这里还简单写了一个加速减速的效果
核心旋转代码如下,我尽量写了注释
let rotateTimer: NodeJS.Timeout | null = null; // 定义定时器变量
let rotateTime: number = 3000 * randomNumber; // 旋转时间
function rotateCircular() {
// console.log(divideContentList);
if (!canvas || !ctx) return; // 如果Canvas元素或2D上下文不存在,则返回
ctx?.save();
randomNumber = parseFloat((0.5 + Math.random()).toFixed(2));
// console.log(randomNumber);
const accelerationTime: number = rotateTime / 5; // 加速时间
const decelerationTime: number = accelerationTime; // 减速时间
let alRotatedTime: number = 0; // 旋转时间
let rotationSpeed: number = 0.01 * randomNumber; // 旋转速度
if (!rotating.value) {
rotating.value = true; // 开始旋转
rotateTimer = setInterval(() => {
ctx?.clearRect(-centerX, -centerY, canvas!.width, canvas!.height); // 清空画布
alRotatedTime += 16; // 旋转时间累加
// console.log("时间", alRotatedTime, "速度", rotationSpeed);
if (alRotatedTime < accelerationTime) {
// 如果加速时间未到,则加速
// console.log("加速");
rotationSpeed += 0.002;
} else if (alRotatedTime > decelerationTime || rotationSpeed > 0.3) {
// 如果加速时间已到,则减速
// console.log("减速");
rotationSpeed >= 0 ? (rotationSpeed -= 0.0005) : ""; // 防止速度为负
}
drawClock(); // 绘制
ctx?.rotate(rotationSpeed * Math.PI);
}, 16); // 每16毫秒旋转一次
setTimeout(() => {
clearInterval(rotateTimer!); // 停止旋转
rotating.value = false; // 标志位重置
}, rotateTime); // 旋转n秒后停止
}
}
这样就可以了
20240520104206
可能我粘贴时代码有遗漏或是表达不清楚,可以在评论区反馈,也可以去可以去该我的开源项目自行查看完整代码,链接如下:
Aggregate-lottery-system: 本开源仓库呈现了一套全面、灵活且易于定制的聚合抽签系统。设计之初便充分考虑了用户的多样需求与便捷性,确保无论是基本应用还是复杂场景都能轻松应对。系统的核心优势在于其简单易修改的结构,无论开发者经验深浅,都能快速上手,根据实际应用场景对功能进行调整或扩展,大大降低了维护与升级的成本。 (gitee.com)
我们最终实现了一个随机轮盘 右侧可更改轮盘的内容
