为什么我的图像不会出现在 canvas 上?
Why won't my images appear on the canvas?
我想使用原型绘制许多不同大小的圆圈,上面有相同的图像。问题是,圆圈上没有绘制图像。
圆圈仍然存在,因为在使用描边时它们是可见的,但没有绘制图像。我可以在没有原型的情况下绘制一个带有图像的圆弧,但是一旦我使用它,它就不起作用了。
控制台中没有出现错误,所以我不清楚我遗漏了什么。
我试过将事件侦听器移到原型之外,但圆圈图像仍然没有出现。
如果有人对为什么这不起作用有任何见解或者解决方案可以分享,我们将不胜感激。
代码如下:
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>
您的代码中有两个问题。首先,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>
给你,我只是在这里更改了 2 处以使你的代码工作。
load
用于事件侦听器而不是 onload
。
- 使用箭头函数以依赖父上下文而不是动态上下文(
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>
这是加载图像的另一种方式,它更加模块化,如果您正在制作游戏,Img
class 会派上用场。
Off-topic -
if you want to load multiple images then you can add a
总加载counter to keep track of how many images has been loaded and if the
总加载count is equal to
总图像count 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>
我想使用原型绘制许多不同大小的圆圈,上面有相同的图像。问题是,圆圈上没有绘制图像。
圆圈仍然存在,因为在使用描边时它们是可见的,但没有绘制图像。我可以在没有原型的情况下绘制一个带有图像的圆弧,但是一旦我使用它,它就不起作用了。
控制台中没有出现错误,所以我不清楚我遗漏了什么。 我试过将事件侦听器移到原型之外,但圆圈图像仍然没有出现。
如果有人对为什么这不起作用有任何见解或者解决方案可以分享,我们将不胜感激。
代码如下:
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>
您的代码中有两个问题。首先,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>
给你,我只是在这里更改了 2 处以使你的代码工作。
load
用于事件侦听器而不是onload
。- 使用箭头函数以依赖父上下文而不是动态上下文(
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>
这是加载图像的另一种方式,它更加模块化,如果您正在制作游戏,Img
class 会派上用场。
Off-topic -
if you want to load multiple images then you can add a
总加载counter to keep track of how many images has been loaded and if the
总加载count is equal to
总图像count 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>