我正在尝试基于类的代码。我为画布创建了一个类,然后将一个组件传递给它,然后再渲染它。问题是当浏览器请求动画帧时,上下文丢失,并且变得不确定。我正在寻找解释为什么会出现这种情况的原因。
我并不关心最佳实践,只是弄清楚为什么背景会丢失。
我在codepen上附加了一个示例链接。
http://codepen.io/BrianDGLS/pen/BoJorM?editors=001
这是JS代码:
class Canvas {
constructor() {
this.canvas = document.getElementById('canvas');
this.context = this.canvas.getContext('2d');
this.width = this.canvas.width = window.innerHeight;
this.height = this.canvas.height = window.innerWidth;
this.components = [];
}
draw() {
this.context.clearRect(0, 0, this.width, this.height);
this.context.globalCompositeOperation = 'hard-light';
this.components.map(_ => _.render());
window.requestAnimationFrame(this.draw);
}
listeners() {
window.addEventListener('resize', () => {
this.width = this.canvas.width = window.innerHeight;
this.height = this.canvas.height = window.innerWidth;
}, false);
}
init() {
this.listeners();
this.draw();
}
}
class Utils {
randomNum(max, min) {
return Math.floor(max * Math.random()) + min;
}
color(opacity) {
return `hsla(${this.randomNum(360, 1)}, 70%, 60%, ${opacity})`;
}
}
const utils = new Utils();
const _canvas = new Canvas();
class Stars {
constructor(_) {
this.total = _.total;
this.spawn = [];
this.z = 300;
this.canvas = _.canvas;
this.xw = this.canvas.width * this.z;
this.xh = this.canvas.height * this.z;
}
create() {
while (this.spawn.length < this.total) {
this.spawn.push({
pos: [this.xw * Math.random() - this.canvas.width / 2 * this.z, this.xh * Math.random() - this.canvas.height / 2 * this.z, this.z],
vel: [0, 0, -2],
r: utils.randomNum(500, 100),
color: utils.color(1)
});
}
}
draw() {
for (let i = 0; i < this.spawn.length; ++i) {
let t = this.spawn[i];
let x = t.pos[0] / t.pos[2];
let y = t.pos[1] / t.pos[2];
if (x < -this.canvas.width / 2 || x > this.canvas.width / 2 || y < -this.canvas.height / 2 || y > this.canvas.height / 2 || t.pos[2] < 0) {
this.spawn.splice(i, 1);
--i;
continue;
}
this.canvas.context.beginPath();
this.canvas.context.fillStyle = t.color;
this.canvas.context.arc(x, y, t.r / t.pos[2], 0, Math.PI * 2, false);
t.pos[0] += t.vel[0];
t.pos[1] += t.vel[1];
t.pos[2] += t.vel[2];
this.canvas.context.fill();
}
}
render() {
this.create();
this.canvas.context.save();
this.canvas.context.translate(this.canvas.width / 2, this.canvas.height / 2);
this.draw();
this.canvas.context.restore();
}
}
_canvas.components.push(new Stars({
canvas: _canvas,
total: 200
}));
答案 0 :(得分:7)
当您通过draw()
调用window.requestAnimationFrame(this.draw)
时,draw()
中的范围将绑定到window
而不是Canvas
。尝试显式绑定范围,如下所示:
window.requestAnimationFrame(this.draw.bind(this));