我正在创建一个画布游戏,其中的球会相互反弹。 我希望这些球具有自己的皮肤,在弧形元素上放置背景图像。
当球不弹跳时,图像剪辑得很好并且像弧线一样是圆形的。但是,当我开始为球设置动画时,它根本不会移动,因为剪辑功能不允许重绘图像或弧线。
那是我在画布中发现保存和恢复功能时允许在动画时使用clip方法的时候。
此问题是图像的一部分无法正确裁剪。动画中只有一半是圆形的,另一半是矩形图像。我尝试过调整图像的位置,但是并没有达到预期的效果。
我不确定代码为什么会这样,以及如何修复它,使其只是具有图像背景的动画球。
如果有人对此有所了解,甚至可能对解决方案有所了解,将不胜感激。
这是下面的代码和摘录:
const x = document.getElementById('canvas');
const ctx = x.getContext('2d');
let slide = 0;
class Balls {
constructor(xPos, yPos, radius) {
this.xPos = xPos;
this.yPos = yPos;
this.radius = radius;
this.imgX = this.xPos - this.radius;
}
}
const img = document.createElement('img');
img.src = 'https://geology.com/google-earth/google-earth.jpg';
Balls.prototype.render = function() {
ctx.save();
ctx.arc(this.xPos, this.yPos, this.radius, 0, Math.PI * 2);
ctx.clip();
ctx.drawImage(img, this.imgX, this.yPos - this.radius, this.radius * 2, this.radius * 2);
};
Balls.prototype.motion = function() {
this.imgX = this.imgX + 1;
this.xPos = this.xPos + 1;
}
let object = new Balls(100, 100, 25);
const animate = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
object.render();
object.motion();
ctx.restore();
}
setInterval(animate, 50);
body {
background-color: grey;
}
#canvas {
background-color: white;
}
#mod {
border-radius: 100%
}
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script src='practice.js'></script>
<link rel="stylesheet" type="text/css" href="practice.css">
</head>
<body>
<canvas id="canvas" height="200" width="800" />
</body>
</html>
答案 0 :(得分:2)
您需要调用ctx.beginPath()
,否则,每次对arc()
的调用都会添加到相同且唯一的子路径中。这意味着最后,您将剪切由许多弧线组成的怪异路径:5帧后路径的ASCII表示形式:((((( )
const x = document.getElementById('canvas');
const ctx = x.getContext('2d');
let slide = 0;
class Balls {
constructor(xPos, yPos, radius) {
this.xPos = xPos;
this.yPos = yPos;
this.radius = radius;
this.imgX = this.xPos - this.radius;
}
}
const img = document.createElement('img');
img.src = 'https://geology.com/google-earth/google-earth.jpg';
Balls.prototype.render = function() {
ctx.save();
// begin a new sub-path
ctx.beginPath();
ctx.arc(this.xPos, this.yPos, this.radius, 0, Math.PI * 2);
ctx.clip();
ctx.drawImage(img, this.imgX, this.yPos - this.radius, this.radius * 2, this.radius * 2);
};
Balls.prototype.motion = function() {
this.imgX = this.imgX + 1;
this.xPos = this.xPos + 1;
}
let object = new Balls(100, 100, 25);
const animate = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
object.render();
object.motion();
ctx.restore();
requestAnimationFrame(animate);
}
animate();
body {
background-color: grey;
}
#canvas {
background-color: white;
}
#mod {
border-radius: 100%
}
<canvas id="canvas" height="200" width="800" />
还请注意,对于圆形蒙版,使用合成比剪切更好,合成可以更好地消除锯齿,并且不需要昂贵的保存/恢复。
const x = document.getElementById('canvas');
const ctx = x.getContext('2d');
let slide = 0;
class Balls {
constructor(xPos, yPos, radius) {
this.xPos = xPos;
this.yPos = yPos;
this.radius = radius;
this.imgX = this.xPos - this.radius;
}
}
const img = document.createElement('img');
img.src = 'https://geology.com/google-earth/google-earth.jpg';
Balls.prototype.render = function() {
// begin a new sub-path
ctx.beginPath();
ctx.arc(this.xPos, this.yPos, this.radius, 0, Math.PI * 2);
ctx.fill();
ctx.globalCompositeOperation = 'source-in';
ctx.drawImage(img, this.imgX, this.yPos - this.radius, this.radius * 2, this.radius * 2);
ctx.globalCompositeOperation = 'source-over';
};
Balls.prototype.motion = function() {
this.imgX = this.imgX + 1;
this.xPos = this.xPos + 1;
}
let object = new Balls(100, 100, 25);
const animate = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
object.render();
object.motion();
requestAnimationFrame(animate);
}
animate();
body {
background-color: grey;
}
#canvas {
background-color: white;
}
#mod {
border-radius: 100%
}
<canvas id="canvas" height="200" width="800" />