此屏幕截图和代码段会告诉您我的麻烦。怎么避免这个?可能是我做错了吗?我希望看到一些代码示例,如果可能的话。
let canvas = document.querySelector("canvas");
let ctx = canvas.getContext("2d");
canvas.width = 500;
canvas.height = 500;
let image = new Image();
image.src= "https://www.html5rocks.com/static/images/identity/HTML5_Badge_256.png";
function rand(min, max)
{
return Math.floor(Math.random() * (max - min + 1)) + min;
}
image.addEventListener("load", function()
{
let top = canvas.width / 2 - image.width / 2;
let left = canvas.height / 2 - image.height / 2;
function render()
{
top += rand(-2, 2);
left += rand(-2, 2);
ctx.save();
ctx.globalAlpha = 0.05;
ctx.fillStyle = "#9ea7b8";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.restore();
ctx.drawImage(image, top, left, image.width, image.height);
requestAnimationFrame(render);
}
render();
});
<canvas></canvas>
答案 0 :(得分:2)
问题
我能想到描述这个工件的最好方法是将其称为舍入误差。人们倾向于忘记的一件事是,当你绘制到画布时,你实际上是在写一个位图。有效地形象。每个像素的α值是整数x,其中0 <= x <= 255。
所以,当你说:
ctx.save();
ctx.globalAlpha = 0.05;
ctx.fillStyle = "#9ea7b8";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.restore();
ctx.drawImage(image, top, left, image.width, image.height);
你正在绘制一个大多数透明的方块,它不会让任何东西完全消失。例如,如果某个像素的颜色为rgba(254,255,255,255)
,并且您使用0.05不透明度的白色方块rgba(255,255,255,12)
绘制它,则会将红色从254
拉到{{1} }}。但这需要是一个整数,因此它会向下舍入,并且永远不会完全成为它所接近的颜色。
现在如何解决
像素比较应与
相似254.05
希望这会有所帮助。
答案 1 :(得分:2)
好的,经过多次尝试,工作完成了。我绘制完整路径的每一帧。
let canvas = document.querySelector("canvas");
let ctx = canvas.getContext("2d");
let tail = 20;
canvas.width = 800;
canvas.height = 600;
let image = new Image();
let opacity = [];
image.src= "https://www.html5rocks.com/static/images/identity/HTML5_Badge_256.png";
for(let i = 1; i <= tail; i++)
{
opacity.push(i / tail);
}
function rand(min, max)
{
return Math.floor(Math.random() * (max - min + 1)) + min;
}
image.addEventListener("load", function()
{
let frames = [];
frames.push({
x: canvas.width / 2 - image.width / 2,
y: canvas.height / 2 - image.height / 2
});
for (let i = 1; i < tail; i++)
{
frames.push({
x: frames[i - 1].x + rand(-2, 2),
y: frames[i - 1].y + rand(-2, 2)
});
}
function render()
{
frames.shift();
frames.push({
x: frames[frames.length - 1].x + rand(-2, 2),
y: frames[frames.length - 1].y + rand(-2, 2)
});
ctx.globalAlpha = 1;
ctx.fillStyle = "#9ea7b8";
ctx.fillRect(0, 0, canvas.width, canvas.height);
for(let i = 0; i < tail; i++)
{
ctx.save();
ctx.drawImage(image, frames[i].x, frames[i].y, image.width, image.height);
ctx.globalAlpha = opacity[tail - 1 - i];
ctx.fillRect(frames[i].x - tail, frames[i].y - tail, image.width + tail + tail, image.height + tail + tail);
ctx.restore();
}
requestAnimationFrame(render);
}
render();
});
<canvas></canvas>