? HTML5 Canvas 自行车动画基础准备:从画布搭建到坐标系理解
document.createElement('canvas')创建画布,记得给它设置宽高可别用 CSS,不然会出现拉伸模糊的问题。这里有个小细节,画布默认坐标系原点在左上角,x 轴向右延伸,y 轴向下延伸,这和数学课本里的坐标系方向相反,刚开始画的时候很容易搞反方向,我自己就踩过这个坑。const ctx = canvas.getContext('2d')。这时候可以先画个简单的矩形当自行车的车架,用ctx.fillStyle设置颜色,ctx.fillRect(x, y, width, height)就能画出矩形。不过画自行车这种有曲线的图形,光靠矩形可不够,还得学会用arc方法画车轮,ctx.arc(x, y, radius, startAngle, endAngle),这里的角度单位是弧度,360 度对应的就是 2π 弧度,刚开始计算角度的时候记得用Math.PI来转换。? 精细绘制自行车部件:从车轮到车把的细节处理
beginPath和closePath来绘制车轮的辐条。辐条可以用循环来画,比如从圆心到圆周均匀分布 8 根辐条,每次循环计算当前辐条的角度,然后用lineTo方法连接圆心和圆周上的点。这里要注意的是,绘制完一个部件后最好用ctx.save()保存当前的绘图状态,画完后再用ctx.restore()恢复,这样就不会影响到其他部件的绘制了。ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)这个方法可以创建三次贝塞尔曲线,通过调整控制点的位置来得到不同形状的车架。车把和车座可以用简单的矩形和圆形组合来绘制,车把可以画两个矩形作为把手,中间用一个小矩形连接,车座画一个椭圆就行。绘制的时候要注意各个部件的位置和比例,比如车轮的直径和车架的长度要协调,这样画出来的自行车才好看。? 动画实现核心:requestAnimationFrame 的正确用法
requestAnimationFrame是浏览器提供的高效动画更新方法。它会在浏览器下次重绘之前调用回调函数,保证动画流畅的同时还能节省资源。我们可以创建一个动画函数,在函数里先清除画布ctx.clearRect(0, 0, canvas.width, canvas.height),然后重新绘制自行车的各个部件,通过改变部件的位置来实现动画效果,比如让自行车向前移动,就可以每次循环给自行车的 x 坐标增加一个位移量。requestAnimationFrame的回调函数会传入一个时间戳参数,我们可以用这个时间戳来计算动画的时间间隔,实现更稳定的动画速度。比如记录上一次动画的时间戳,用当前时间戳减去上一次的时间戳得到时间差,然后根据时间差来计算位移量,这样不管浏览器的刷新率如何,动画的速度都能保持一致。另外,停止动画的时候要用cancelAnimationFrame来取消动画循环,避免内存泄漏。? 交互优化:让用户通过鼠标控制自行车方向
mousedown、mousemove和mouseup事件监听,当用户按下鼠标时记录鼠标的位置,移动鼠标时根据鼠标位置的变化来改变自行车的方向,比如让自行车的车头朝向鼠标的方向。这里需要计算鼠标位置和自行车当前位置的角度,用到三角函数Math.atan2(dy, dx)来得到角度,然后根据角度来旋转自行车的车头部件。? WebGL 进阶:3D 自行车模型的渲染技巧
const gl = canvas.getContext('webgl'),然后定义顶点数据,包括顶点的位置、颜色、纹理坐标等。顶点数据需要用缓冲区对象来存储,通过gl.createBuffer创建缓冲区,gl.bindBuffer绑定缓冲区,gl.bufferData向缓冲区写入数据。gl.createShader创建着色器,gl.shaderSource添加着色器代码,gl.compileShader编译着色器。然后创建程序对象,将顶点着色器和片元着色器附着到程序对象上,用gl.linkProgram链接程序。最后通过gl.useProgram使用程序,设置顶点属性指针,调用gl.drawArrays或gl.drawElements来绘制 3D 模型。? 性能优化:让动画在低端设备上也能流畅运行
requestAnimationFrame来控制动画循环,不要用setTimeout或setInterval,因为它们的时间间隔不够精确,容易导致动画卡顿。? 实战案例:完整自行车动画项目的搭建步骤
requestAnimationFrame来更新动画。❓ 常见问题解答:新手必看的避坑指南
A:很可能是因为你用 CSS 设置了画布的宽高,而没有用画布本身的
width和height属性。应该在 HTML 中直接设置canvas标签的宽高,或者用 JavaScript 动态设置,这样才能保证画布的物理像素和显示像素一致,避免模糊。A:首先检查着色器代码是否有错误,编译是否成功。然后查看顶点数据是否正确,坐标系是否转换正确。还要注意光照的设置,是否有开启光照,光源的位置和颜色是否正确,材质参数是否合理。
A:先检查是否使用了
requestAnimationFrame,然后看看画布的大小是否过大,尝试减小画布尺寸。对于复杂的绘制内容,可以进行简化,合并绘制操作,减少绘制次数。如果是 3D 模型,进行模型简化和纹理压缩,关闭不必要的特效。