Your issue is that you are calling animate()
again and again within your requestAnimationFrame()
method.(您的问题是您在requestAnimationFrame()
方法中一次又一次调用animate()
。)
You instead need to let JS call the function animate
for you when requestAnimationFrame() decides to do so.(相反,当requestAnimationFrame()决定这样做时,您需要让JS为您调用animate
函数。)
This means you need to pass the animate
function into requestAnimationFrame
, not the actual function call (because when you call the function, you're really passing through its return value):(这意味着您需要将animate
函数传递给requestAnimationFrame
,而不是实际的函数调用 (因为调用该函数时,您实际上是在传递其返回值):)
requestAnimationFrame(this.animate.bind(this));
Since JS will handle the calling of the animate
method, the this
inside of animate()
(when invoked) will not be your Canvas
object, but rather the window
.(由于JS将处理animate
方法的调用,因此animate
animate()
内部的this
(在调用时)将不是Canvas
对象,而是window
。) To make this
refer to your Canvas
object you'll need to .bind(this)
to your animate
function.(为了使this
是指你的Canvas
对象,你就需要.bind(this)
你的animate
功能。) The above is equivalent to using an arrow function:(以上等效于使用箭头功能:)
requestAnimationFrame(() => this.animate());
Your other issue is that you're trying to display the image before it has loaded.(另一个问题是您试图在图像加载之前显示它。) You firstly need to load the image and then display it.(您首先需要加载图像,然后显示它。) If your image is going to stay the same, I recommend you load it before you draw, rather than loading it every time you want to redraw (see second code snippet).(如果您的图像将保持不变,建议您在绘制之前先加载它,而不是每次要重绘时都加载它(请参见第二代码段)。)
Also, ctx
is part of your canvas instance.(另外, ctx
是画布实例的一部分。) Each canvas object will have a .ctx
property as it is defined in the constructor.(每个画布对象将具有在构造函数中定义的.ctx
属性。) So, there is no need to pass it through as an argument to animate
or display
, as you can access it by using this.ctx
.(因此,无需传递它作为参数进行animate
或display
,因为您可以使用this.ctx
进行访问。)
See example below (note the image is a temporary image):(请参见下面的示例(请注意该图像是临时图像):)
class Canvas { constructor(canvasId = 'canvas', dimension = '2d', canvasWidth = document.body.clientWidth, canvasHeight = window.innerHeight, canvasDisplay = 'block', canvasOverflow = 'hidden') { // Initialize Canvas and Context variables this.can = document.getElementById(canvasId); this.ctx = this.can.getContext(dimension); // Set canvas properties this.can.width = canvasWidth; this.can.height = canvasHeight; this.can.style.display = canvasDisplay; this.can.style.overflow = canvasOverflow; this.count = 0; } display() { var ctx = this.ctx; var scrollSS = new Image(); scrollSS.src = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRha_-J-uQR_8pUrUQOiPYZ_JXRoqfoqDt8BO8icSfkworyz9woQQ&s"; scrollSS.addEventListener('load', e => { ctx.drawImage(scrollSS, 0, 0, 102, 345, 10, 0, this.can.width / 10, this.can.height); }); } animate() { this.count++; this.display(); requestAnimationFrame(this.animate.bind(this)); } } var canvas = new Canvas(); canvas.animate();
<canvas id="canvas" style="border: 1px solid black"></canvas>
Here is an approach using Promises that you might want to take if you only need to load the one image:(如果只需要加载一个图像,则可以使用以下方法使用Promises :)
class Canvas { constructor(canvasId = 'canvas', dimension = '2d', canvasWidth = document.body.clientWidth, canvasHeight = window.innerHeight, canvasDisplay = 'block', canvasOverflow = 'hidden') { // Initialize Canvas and Context variables this.can = document.getElementById(canvasId); this.ctx = this.can.getContext(dimension); // Set canvas properties this.can.width = canvasWidth; this.can.height = canvasHeight; this.can.style.display = canvasDisplay; this.can.style.overflow = canvasOverflow; this.count = 0; } loadImage(url) { var img = new Image(); img.src = url; return new Promise((resolve) => { img.addEventListener('load', function(e) { resolve(this); }); }); } display(img) { var ctx = this.ctx; ctx.drawImage(img, 0, 0, 102, 345, 10, 0, this.can.width / 10, this.can.height); } animate(img) { this.count++; this.display(img); requestAnimationFrame(this.animate.bind(this, img)); } } var canvas = new Canvas(); var img_url = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRha_-J-uQR_8pUrUQOiPYZ_JXRoqfoqDt8BO8icSfkworyz9woQQ&s"; canvas .loadImage(img_url) .then(function(image) { canvas.animate(image); });
<canvas id="canvas" style="border: 1px solid black"></canvas>
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…