[英]How to add a fade effect to only certain elements on a html canvas
我有一个带有多个不同颜色圆圈的画布,我只想为某些圆圈添加淡出效果。 该效果仅适用于红色和绿色。
代码如下
function drawPiece(pieceX, pieceY, color) {
if (color === "rgba(0,0,0,1)" || color === "rgba(255,255,255,1)"){
ctx.beginPath();
ctx.fillStyle = color;
ctx.arc(pieceX, pieceY, 50, 0, 2 * Math.PI, false);
ctx.fill();
ctx.lineWidth = "4";
ctx.strokeStyle = "rgba(0,0,0,1)";
ctx.stroke();
ctx.closePath();
}
else {
ctx.beginPath();
ctx.fillStyle = color;
ctx.arc(pieceX, pieceY, 10, 0, 2 * Math.PI, false);
ctx.fill();
ctx.lineWidth = "4";
ctx.strokeStyle = "rgba(0,0,0,1)";
ctx.stroke();
ctx.closePath();
setTimeout(function(){
var fadeTarget = document.getElementById("canvasGame");
var fadeEffect = setInterval(function () {
if (!fadeTarget.style.opacity) {
fadeTarget.style.opacity = 1;
}
if (fadeTarget.style.opacity > 0) {
fadeTarget.style.opacity -= 0.02;
} else {
clearInterval(fadeEffect);
}
}, 20);
},0.5);
}
}
淡入淡出效果有效,但它淡出整个画布而不是单个圆圈。
我怎样才能做到这一点,只有一些元素淡出。
提前致谢
画布是一种绘画表面。 这意味着你不能在你画完之后改变它。 您只能清除它,或在其上涂漆。 就像真正的绘画一样,您无法更改已绘制的笔划的颜色。
所以你必须清除画布,然后重新绘制它,除了这次绘制一些具有不同不透明度的圆圈。 只需将这些rgba
值的最后一个数字更改为 0 到 1 之间即可更改不透明度。
将不透明度存储在某个变量中:
var circleOpacity = 1;
更改不透明度,然后在间隔函数中重绘:
circleOpactiy -= 0.2;
drawMyCanvas();
现在用fillStyle
绘制一些部分,例如:
ctx.fillStyle = shouldBeFaded ? `rgba(0,0,0,${circleOpacity})` : 'rgba(0,0,0,1)'
或者,您可以绝对放置两个画布,使它们彼此重叠,并且您可以像已经在做的那样淡化顶部的画布。 这样你就不必不断地重新渲染画布。 如果您只想淡化一些圆圈,这可能会更容易。 但是如果你想在画布上做任何更复杂的事情(比如渲染某种游戏),你无论如何都要重新绘制画布的每一帧动画。
一个很棒的画布 2d 资源是 MDN 的CanvasRenderingContext2D
如果要为画布内容设置动画,则需要一个渲染循环。
渲染循环每秒调用 60 次,如果可能,绘制过多并且速率将降至 60fps 以下。
主循环清除画布,然后绘制动画内容,然后请求下一帧。
requestAnimationFrame(mainLoop); // request the first frame to start the animation
function mainLoop() {
ctx.globalAlpha = 1; // default to 1 in case there is other content drawn
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); // clear the canvas
drawContent(); // render the content.
requestAnimationFrame(mainLoop); // request the next frame (in 1/60th second)
}
绘制圆的函数。 您可以从颜色中删除 alpha 并使用globalAlpha
设置透明度。
Math.TAU = Math.PI * 2; // set up 2 PI
function drawCircle(x, y, radius, color, alpha = 1) {
ctx.globalAlpha = alpha;
ctx.fillStyle = color;
ctx.strokeStyle = "#000";
ctx.lineWidth = 4;
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.TAU);
ctx.fill();
ctx.stroke();
}
创建一个对象来保存一个圆的描述和一个数组来放置它们
const circles = [];
function circle(x,y,r = 10, col = "#FFF", alpha = 1) {
return {x, y, r, col, alpha, alphaTarget: alpha};
}
然后在drawContent
函数中一次绘制一个圆圈
function drawContent() {
for (const circle of circles) {
if(circle.alpha !== circle.alphaTarget) {
const aStep = circle.alphaTarget - circle.alpha;
const dir = Math.sign(aStep);
circle.alpha += Math.min(Math.abs(aStep), dir * 0.02)) * dir;
}
drawCircle(circle.x, circle.y, circle.r, circle.col, circle.alpha);
}
}
该演示绘制了 100 个圆圈,每个圆圈都有自己的颜色和 alpha。 随机选择 alpha 淡出然后再回来。
如果要为画布内容设置动画,则需要一个渲染循环。
我移动圆圈,以便如果设备渲染内容变慢,那么更容易看到低帧速率。
Math.TAU = Math.PI * 2; // set up 2 PI Math.rand = (val) => Math.random() * val; Math.randI = (val) => Math.random() * val | 0; requestAnimationFrame(mainLoop); const ctx = canvas.getContext("2d"); const W = canvas.width = innerWidth; // size canvas to page const H = canvas.height = innerHeight; // size canvas to page const circleCount = 100; const circleFadeRate = 0.01; // per 60th second const circles = []; const circle = (x,y,r = 10, col = "#FFF", alpha = 1) => ({x, y, r, col, alpha, alphaTarget: alpha}); createCircles(); function createCircles() { var i = circleCount; while (i--) { circles.push(circle(Math.rand(W), Math.rand(H), Math.rand(10) + 10, "#" + Math.randI(0xFFF).toString(16).padStart(3,"0"), 1)); } circles.sort((a,b) => ar - br); // big drawn last } function mainLoop() { ctx.globalAlpha = 1; ctx.clearRect(0, 0, W, H); drawContent(); requestAnimationFrame(mainLoop); } function drawCircle(x, y, radius, color, alpha = 1) { ctx.globalAlpha = alpha; ctx.fillStyle = color; ctx.strokeStyle = "#000"; ctx.lineWidth = 2; ctx.beginPath(); ctx.arc(x, y, radius, 0, Math.TAU); ctx.fill(); ctx.stroke(); } function drawContent() { for (const circle of circles) { if(circle.alpha !== circle.alphaTarget) { const aStep = circle.alphaTarget - circle.alpha; const dir = Math.sign(aStep); circle.alpha += Math.min(Math.abs(aStep), 0.02) * dir; } else if(Math.random() < 0.01) { circle.alphaTarget = circle.alpha < 0.7 ? 1 : Math.random() * 0.4; } circle.y += (circle.r - 10) / 5; circle.y = circle.y > H + circle.r + 2 ? -(circle.r + 2) : circle.y; drawCircle(circle.x, circle.y, circle.r, circle.col, circle.alpha); } }
body { padding: 0px; } canvas { position: absolute; top: 0px; left: 0px; }
<canvas id="canvas"></canvas>
有关 2D 画布 API 的更多信息,请参阅此答案顶部的链接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.