Canvas带编号平移动画实现各圆生成不同1-60随机数的问题
实现思路与修改方案
问题根因
- 全局的
randomNumber仅在代码初始化时生成一次,所有圆绘制时都读取同一个固定值,所以编号完全一致 - 描边颜色的判断逻辑仅全局执行一次,无法适配不同编号的圆的配色规则
修改思路
- 预先创建1-60的数字池,每次取随机数后从池中移除,保证所有圆的编号不重复
- 每个Circle实例创建时单独分配随机编号、计算对应描边颜色,作为实例自有属性存储,不依赖全局变量
- 绘制时读取当前实例自身的编号和颜色属性
完整修改后代码
// Single Animated Circle - Get Canvas element by Id var canvas = document.getElementById("canvas"); // Set Canvas dimensions canvas.width = 300; canvas.height = 900; // Get drawing context var ctx = canvas.getContext("2d"); // Radius var radius = 13; // Starting Position var x = radius; var y = radius; // Speed in x and y direction var dx = 1; var dy = 0; // 生成1-60数字池,用于获取不重复随机数 function createNumberPool() { const pool = [] for(let i = 1; i <= 60; i++) { pool.push(i) } return pool } const numberPool = createNumberPool() // 从数字池中取随机数 function getUniqueRandomNum() { const randomIndex = Math.floor(Math.random() * numberPool.length) return numberPool.splice(randomIndex, 1)[0] } class Circle { constructor(data) { this.data = data; // 每个实例单独分配唯一随机编号 this.number = getUniqueRandomNum() // 计算当前编号对应的描边颜色 if (this.number > 0 && this.number <= 10) { this.strokeStyle = "#0b0bf1"; } else if (this.number > 10 && this.number <= 20) { this.strokeStyle = "#f10b0b"; } else if (this.number > 20 && this.number <= 30) { this.strokeStyle = "#0bf163"; } else if (this.number > 30 && this.number <= 40) { this.strokeStyle = "#f1da0b"; } else if (this.number > 40 && this.number <= 50) { this.strokeStyle = "#950bf1"; } else if (this.number > 50 && this.number <= 60) { this.strokeStyle = "#0bf1e5"; } } draw() { if ( this.data.x + this.data.radius > 300 || this.data.x - this.data.radius < 0 ) { this.data.x = this.data.radius; } this.data.x += this.data.dx; ctx.beginPath(); ctx.arc(this.data.x, this.data.y, this.data.radius, 0, Math.PI * 2, false); // 使用当前实例对应的描边颜色 ctx.strokeStyle = this.strokeStyle ctx.stroke(); // 使用当前实例的编号绘制文本 ctx.fillText(this.number, this.data.x - 5, this.data.y + 3); } } circles = []; circles.push(new Circle({ radius, x, y, dx, dy })); setTimeout(function () { circles.push(new Circle({ radius, x, y: y * 4, dx, dy })); }, 500); setTimeout(function () { circles.push(new Circle({ radius, x, y: y * 8, dx, dy })); }, 1000); setTimeout(function () { circles.push(new Circle({ radius, x, y: y * 12, dx, dy })); }, 1500); setTimeout(function () { circles.push(new Circle({ radius, x, y: y * 16, dx, dy })); }, 2000); setTimeout(function () { circles.push(new Circle({ radius, x, y: y * 20, dx, dy })); }, 2500); function animate3() { requestAnimationFrame(animate3); ctx.clearRect(0, 0, canvas.width, canvas.height); circles.forEach((item) => item.draw()); } animate3();
内容的提问来源于stack exchange,提问作者Pedro Fernandes
相关产品推荐
相关产品推荐

