如何改造JavaScript类使其具备可移植性适配任意项目
优化思路
你的Layer类当前强依赖三个全局变量:绘图上下文ctx、全局速度gameSpeed、全局帧计数gameFrame,这是导致它移植性差的核心原因,只需要把这些依赖从全局改为注入到类实例中,就能实现跨项目复用。
具体优化点
- 构造函数新增必传的
ctx参数,把绘图上下文注入到实例内部,不再依赖全局同名变量 - 移除方法对全局
gameSpeed、gameFrame的依赖,改为调用update时主动传入当前运行参数,也支持实例单独设置速度 - 把写死的宽高、坐标做成可选配置项,适配不同尺寸的图层需求
优化后代码
class Layer { /** * 构造函数 * @param {Object} options 配置项 * @param {CanvasRenderingContext2D} options.ctx canvas绘图上下文,必传 * @param {Image} options.image 图层使用的图片对象,必传 * @param {Number} [options.speedModifier=1] 速度系数,默认1 * @param {Number} [options.width=2400] 图层宽度,默认2400 * @param {Number} [options.height=700] 图层高度,默认700 * @param {Number} [options.x=0] 初始x坐标,默认0 * @param {Number} [options.y=0] 初始y坐标,默认0 */ constructor(options) { const { ctx, image, speedModifier = 1, width = 2400, height = 700, x = 0, y = 0 } = options // 必传参数校验,避免使用时报错 if (!ctx || !image) throw new Error('ctx和image为必传参数') this.ctx = ctx this.image = image this.speedModifier = speedModifier this.width = width this.height = height this.x = x this.y = y } /** * 更新图层状态 * @param {Number} gameFrame 当前全局帧计数 * @param {Number} gameSpeed 当前全局速度 */ update(gameFrame, gameSpeed) { const speed = gameSpeed * this.speedModifier this.x = (gameFrame * speed) % this.width } // 绘制图层,使用实例内部存储的ctx draw() { this.ctx.drawImage(this.image, this.x, this.y, this.width, this.height) this.ctx.drawImage(this.image, this.x + this.width, this.y, this.width, this.height) } }
使用示例
// 你项目中自己声明的上下文变量名可以随意取,不需要固定叫ctx const myCanvas = document.getElementById('my-custom-canvas') const myCtx = myCanvas.getContext('2d') const bgImage = new Image() bgImage.src = '你的背景图地址' // 初始化实例,注入上下文 const bgLayer = new Layer({ ctx: myCtx, image: bgImage, speedModifier: 0.5, width: 1920, height: 1080 }) // 游戏主循环里调用 let frameCount = 0 const globalSpeed = 3 function animate() { myCtx.clearRect(0, 0, myCanvas.width, myCanvas.height) // 传入当前帧计数和全局速度即可 bgLayer.update(frameCount, globalSpeed) bgLayer.draw() frameCount++ requestAnimationFrame(animate) } animate()
内容的提问来源于stack exchange,提问作者Mentani2020
相关产品推荐
相关产品推荐

