【问题标题】:Why won't my images appear on the canvas?为什么我的图像不会出现在画布上?
【发布时间】:2019-02-15 17:47:12
【问题描述】:

我想使用原型绘制许多不同大小的圆圈,上面有相同的图像。问题是,圆圈上没有绘制图像。

圆圈仍然存在,因为它们在使用描边时可见,但未绘制图像。我能够在没有原型的情况下绘制带有图像的弧线,但是一旦我使用它,它就不起作用了。

控制台中没有出现任何错误,所以我不清楚我缺少什么。 我尝试将事件侦听器移到原型之外,但圆形图像仍然没有出现。

如果有人对为什么这不起作用有任何见解和解决方案,他们可以分享,那将不胜感激。

代码如下:

const ctx = document.getElementById('canvas').getContext('2d');
class Balls {
  constructor(xPos, yPos, radius){
    this.xPos = xPos;
    this.yPos = yPos;
    this.radius = radius;
  }
}
Balls.prototype.render  = function(){
  const img = document.createElement('img');
  img.src = 'crystal.jpg';
  ctx.arc(this.xPos, this.yPos, this.radius, 0, Math.PI*2)
  ctx.stroke();	
  ctx.clip();
  img.addEventListener('onload', function(e){
    ctx.drawImage(img, this.xPos - this.radius, this.yPos - this.radius, 
    this.radius*2, this.radius*2);
  });
};
let object = new Balls(100, 100, 50);
object.render();
<canvas id='canvas'></canvas>

【问题讨论】:

标签: javascript object html5-canvas prototype drawimage


【解决方案1】:

给你,为了让你的代码正常工作,我只是在这里更改了 2 件事。

  1. load 用于事件监听器,而不是 onload。
  2. 使用箭头函数以依赖父上下文而不是动态上下文 (this)。

const ctx = document.getElementById('canvas').getContext('2d');
class Balls {
  constructor(xPos, yPos, radius) {
    this.xPos = xPos;
    this.yPos = yPos;
    this.radius = radius;
  }
}
Balls.prototype.render = function() {
  const img = document.createElement('img');
  img.src = 'https://via.placeholder.com/150.png?text=vijay'
  ctx.arc(this.xPos, this.yPos, this.radius, 0, Math.PI * 2)
  ctx.stroke();
  ctx.clip();
  img.addEventListener('load', (e) => {
    ctx.drawImage(img, this.xPos - this.radius, this.yPos - this.radius,
      this.radius * 2, this.radius * 2);
  });
};
let object = new Balls(100, 100, 50);
object.render();
<canvas id='canvas'></canvas>

【讨论】:

    【解决方案2】:

    您的代码中有两个问题。首先,onload 事件应该是load。其次,this在事件监听函数内部是未知的,所以this.radius等都是未定义的,ctx.drawImage(img, this.xPos - this.radius, this.yPos - this.radius, this.radius*2, this.radius*2)不起作用。

    我为this.xPos、this.yPos、this.radius 使用了一些变量,这些变量可以在事件侦听器回调函数中使用。 希望这会有所帮助!

    const ctx = document.getElementById('canvas').getContext('2d');
    class Balls {
      constructor(xPos, yPos, radius) {
        this.xPos = xPos;
        this.yPos = yPos;
        this.radius = radius;
      }
    }
    Balls.prototype.render = function() {
      const img = new Image();
      img.src = 'https://source.unsplash.com/random';
      var xPos = this.xPos, yPos = this.yPos, radius = this.radius
      ctx.arc(xPos, yPos, radius, 0, Math.PI * 2)
      ctx.stroke();
      ctx.clip();
      img.addEventListener('load', function(e) {
        console.log("load")
        ctx.drawImage(img, xPos - radius, yPos - radius, 
        radius*2, radius*2);
      });
    };
    let object = new Balls(100, 100, 50);
    object.render();
    <canvas id='canvas'></canvas>

    【讨论】:

      【解决方案3】:

      这是一种加载图像的替代方法,它更加模块化,如果您正在制作游戏,Img 类将派上用场。

      Off-topic - if you want to load multiple images then you can add atotalLoadedcounter to keep track of how many images has been loaded and if thetotalLoadedcount is equal tototalImagescount then you can call a callback which will fire the animationLoop and preloads all the images.

      const ctx = document.getElementById('canvas').getContext('2d');
      
      // Img class to provide modular code
      class Img {
        constructor(src, x, y, size) {
          this.x = x;
          this.y = y;
          this.size = size;
          this.src = src;
          this.img = new Image();
          this.img.src = this.src;
          this.isLoaded = false;
          this.img.addEventListener('load', (e) => {
            this.isLoaded = true;
            this.draw();
          });
        }
      
        draw() {
          if (this.isLoaded) {
            ctx.drawImage(this.img, this.x, this.y, this.size, this.size);
          }
        }
      }
      
      class Balls {
        constructor(xPos, yPos, radius) {
          this.xPos = xPos;
          this.yPos = yPos;
          this.radius = radius;
        }
      }
      Balls.prototype.render = function() {
        let imgx = this.xPos - this.radius;
        let imgy = this.yPos - this.radius;
        let imgr = this.radius * 2;
        let url = 'https://via.placeholder.com/150.png?text=Better';
        const img = new Img(url, imgx, imgy, imgr);
        ctx.arc(this.xPos, this.yPos, this.radius, 0, Math.PI * 2)
        ctx.stroke();
        ctx.clip();
        img.draw();
      };
      let object = new Balls(100, 100, 50);
      object.render();
      <canvas id='canvas'></canvas>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-15
        • 2013-11-21
        • 2022-01-09
        • 2014-05-03
        相关资源
        最近更新 更多