You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用HTML Canvas与JavaScript类绘制100个移动圆形失败问题求助

问题修复方案

错误点1:数组元素添加方式错误

你直接把circleArray赋值成单个Circle实例,而非往数组中添加元素,循环结束后circleArray会变成单个对象而非数组,后续遍历circleArray.length必然报错。
修正:使用数组push方法添加实例:

circleArray.push(new Circle(x,y,dx,dy,radius))

错误点2:update方法调用draw的方式错误

circleArray.draw()写法错误,数组本身没有draw方法,应该调用当前Circle实例的draw方法,即this.draw()。
修正:把circleArray.draw()替换为this.draw()

错误点3:Canvas上下文未初始化

代码中的c变量未定义,浏览器无法识别要操作的Canvas对象,必须先获取Canvas元素并创建2D上下文。
修正:在代码开头添加:

const c = document.querySelector('canvas').getContext('2d');
// 同步设置Canvas尺寸与窗口一致
document.querySelector('canvas').width = innerWidth;
document.querySelector('canvas').height = innerHeight;

注意:HTML页面中需要先存在<canvas></canvas>标签。

错误点4:速度计算逻辑错误

dx = (Math.random() - 0.5 * 5)运算优先级错误,0.5先与5相乘,导致速度范围不符合预期,应先做减法再乘法,让速度区间落在-2.5到2.5之间。
修正:改为(Math.random() - 0.5) * 5,dy同理。


修正后的完整代码

// 初始化Canvas上下文
const c = document.querySelector('canvas').getContext('2d');
document.querySelector('canvas').width = innerWidth;
document.querySelector('canvas').height = innerHeight;

class Circle {
    constructor(x, y, dx, dy, radius) {
        this.x = x
        this.y = y
        this.dx = dx
        this.dy = dy
        this.radius = radius
    }

    draw() {
        c.beginPath()
        c.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
        c.strokeStyle = "blue"
        c.stroke()
    }

    update() {
        if (this.x + this.radius > innerWidth || this.x - this.radius < 0) {
            this.dx = -this.dx
        }
        if (this.y + this.radius > innerHeight || this.y - this.radius < 0) {
            this.dy = -this.dy
        }

        this.x += this.dx
        this.y += this.dy // 修正y轴移动逻辑,与碰撞判断保持一致
        this.draw()
    }
}

let circleArray = []
for (let i = 0; i < 100; i++){
    let radius = 30
    // 修正初始位置,避免圆形一开始就超出屏幕
    let x = Math.random() * (innerWidth - radius * 2) + radius;
    let y = Math.random() * (innerHeight - radius * 2) + radius;
    let dx = (Math.random() - 0.5) * 5
    let dy = (Math.random() - 0.5) * 5
    circleArray.push(new Circle(x,y,dx,dy,radius))
}

function animation() {
    requestAnimationFrame(animation)
    c.clearRect(0, 0, innerWidth, innerHeight)

    for(let i = 0; i < circleArray.length; i++){
        circleArray[i].update()
    }
}

animation()

额外优化:调整了圆形初始位置的计算逻辑,避免圆形一开始就超出屏幕边界;修正了y轴移动方向,让碰撞后的移动逻辑与判断条件一致。

内容的提问来源于stack exchange,提问作者raj singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 16:25:23